summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/00-Common.cmake15
-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.cpp139
-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.txt15
-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.h70
-rw-r--r--indra/llcommon/lldate.cpp6
-rw-r--r--indra/llcommon/llerror.cpp18
-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/llpreprocessor.h4
-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.h33
-rw-r--r--indra/llcommon/llstring.cpp111
-rw-r--r--indra/llcommon/llstring.h225
-rw-r--r--indra/llcommon/llsys.cpp5
-rw-r--r--indra/llcommon/llthread.cpp9
-rw-r--r--indra/llcommon/llthreadsafequeue.h554
-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/stdtypes.h7
-rw-r--r--indra/llcommon/stringize.h117
-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.cpp235
-rw-r--r--indra/llcommon/threadpool.cpp88
-rw-r--r--indra/llcommon/threadpool.h71
-rw-r--r--indra/llcommon/threadsafeschedule.h399
-rw-r--r--indra/llcommon/timing.cpp25
-rw-r--r--indra/llcommon/tuple.h84
-rw-r--r--indra/llcommon/workqueue.cpp158
-rw-r--r--indra/llcommon/workqueue.h574
-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.h50
-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.cpp43
-rw-r--r--indra/llprimitive/llmodel.h20
-rw-r--r--indra/llrender/llcubemap.cpp48
-rw-r--r--indra/llrender/llcubemap.h3
-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.cpp668
-rw-r--r--indra/llrender/llgl.h12
-rw-r--r--indra/llrender/llglheaders.h19
-rw-r--r--indra/llrender/llglslshader.cpp180
-rw-r--r--indra/llrender/llglslshader.h91
-rw-r--r--indra/llrender/llgltexture.cpp2
-rw-r--r--indra/llrender/llgltexture.h2
-rw-r--r--indra/llrender/llimagegl.cpp540
-rw-r--r--indra/llrender/llimagegl.h55
-rw-r--r--indra/llrender/llrender.cpp513
-rw-r--r--indra/llrender/llrender.h44
-rw-r--r--indra/llrender/llrender2dutils.cpp149
-rw-r--r--indra/llrender/llrendertarget.cpp2
-rw-r--r--indra/llrender/llshadermgr.cpp45
-rw-r--r--indra/llrender/llshadermgr.h2
-rw-r--r--indra/llrender/lltexture.h7
-rw-r--r--indra/llrender/llvertexbuffer.cpp805
-rw-r--r--indra/llrender/llvertexbuffer.h46
-rw-r--r--indra/llui/CMakeLists.txt6
-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.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.h15
-rw-r--r--indra/llwindow/llwindowmacosx.cpp65
-rw-r--r--indra/llwindow/llwindowmacosx.h150
-rw-r--r--indra/llwindow/llwindowwin32.cpp3156
-rw-r--r--indra/llwindow/llwindowwin32.h44
-rw-r--r--indra/llxml/llcontrol.h9
-rw-r--r--indra/media_plugins/cef/CMakeLists.txt3
-rw-r--r--indra/newview/CMakeLists.txt23
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/cmd_line.xml8
-rw-r--r--indra/newview/app_settings/high_graphics.xml2
-rw-r--r--indra/newview/app_settings/low_graphics.xml2
-rw-r--r--indra/newview/app_settings/mid_graphics.xml2
-rw-r--r--indra/newview/app_settings/settings.xml145
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl)45
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl)41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl)31
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/debugV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl)25
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl71
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyV.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleV.glsl18
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml2
-rw-r--r--indra/newview/featuretable.txt422
-rw-r--r--indra/newview/featuretable_mac.txt318
-rwxr-xr-xindra/newview/installers/darwin/apple-notarize.sh3
-rw-r--r--indra/newview/llagent.cpp2
-rw-r--r--indra/newview/llappviewer.cpp323
-rw-r--r--indra/newview/llappviewer.h107
-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.cpp4
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp4
-rw-r--r--indra/newview/lldrawable.cpp149
-rw-r--r--indra/newview/lldrawable.h69
-rw-r--r--indra/newview/lldrawpool.cpp154
-rw-r--r--indra/newview/lldrawpool.h44
-rw-r--r--indra/newview/lldrawpoolalpha.cpp794
-rw-r--r--indra/newview/lldrawpoolalpha.h34
-rw-r--r--indra/newview/lldrawpoolavatar.cpp1754
-rw-r--r--indra/newview/lldrawpoolavatar.h185
-rw-r--r--indra/newview/lldrawpoolbump.cpp668
-rw-r--r--indra/newview/lldrawpoolbump.h52
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp124
-rw-r--r--indra/newview/lldrawpoolmaterials.h18
-rw-r--r--indra/newview/lldrawpoolsimple.cpp753
-rw-r--r--indra/newview/lldrawpoolsimple.h36
-rw-r--r--indra/newview/lldrawpoolsky.cpp18
-rw-r--r--indra/newview/lldrawpoolterrain.cpp77
-rw-r--r--indra/newview/lldrawpooltree.cpp26
-rw-r--r--indra/newview/lldrawpoolwater.cpp517
-rw-r--r--indra/newview/lldrawpoolwater.h3
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp33
-rw-r--r--indra/newview/lldynamictexture.cpp11
-rw-r--r--indra/newview/lldynamictexture.h10
-rw-r--r--indra/newview/llenvironment.cpp44
-rw-r--r--indra/newview/llenvironment.h29
-rw-r--r--indra/newview/llexperiencelog.cpp4
-rw-r--r--indra/newview/llface.cpp289
-rw-r--r--indra/newview/llface.h21
-rw-r--r--indra/newview/llfasttimerview.cpp19
-rw-r--r--indra/newview/llfeaturemanager.cpp62
-rw-r--r--indra/newview/llflexibleobject.cpp13
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp5
-rw-r--r--indra/newview/llfloaterimagepreview.cpp20
-rw-r--r--indra/newview/llfloaterimcontainer.cpp38
-rw-r--r--indra/newview/llfloatermodelpreview.cpp88
-rw-r--r--indra/newview/llfloaterpreference.cpp55
-rw-r--r--indra/newview/llfloaterwebcontent.cpp4
-rw-r--r--indra/newview/llglsandbox.cpp37
-rw-r--r--indra/newview/llgroupmgr.cpp14
-rw-r--r--indra/newview/llhudnametag.cpp4
-rw-r--r--indra/newview/llhudtext.cpp5
-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.cpp75
-rw-r--r--indra/newview/lllegacyatmospherics.h6
-rw-r--r--indra/newview/llmainlooprepeater.cpp88
-rw-r--r--indra/newview/llmainlooprepeater.h64
-rw-r--r--indra/newview/llmaniprotate.cpp21
-rw-r--r--indra/newview/llmaniptranslate.cpp7
-rw-r--r--indra/newview/llmaterialmgr.cpp4
-rw-r--r--indra/newview/llmeshrepository.cpp45
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp113
-rw-r--r--indra/newview/llmodelpreview.h6
-rw-r--r--indra/newview/llnetmap.cpp5
-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.cpp19
-rw-r--r--indra/newview/llscreenchannel.cpp6
-rw-r--r--indra/newview/llscripteditor.cpp6
-rw-r--r--indra/newview/llselectmgr.cpp6
-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.cpp335
-rw-r--r--indra/newview/llspatialpartition.h77
-rw-r--r--indra/newview/llstartup.cpp28
-rw-r--r--indra/newview/llstartup.h8
-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/lltextureatlas.cpp416
-rw-r--r--indra/newview/lltextureatlas.h90
-rw-r--r--indra/newview/lltextureatlasmanager.cpp268
-rw-r--r--indra/newview/lltextureatlasmanager.h105
-rw-r--r--indra/newview/lltexturefetch.cpp8
-rw-r--r--indra/newview/lltoastpanel.cpp3
-rw-r--r--indra/newview/lltoolgrab.cpp4
-rw-r--r--indra/newview/lltoolmorph.cpp9
-rw-r--r--indra/newview/llviewercamera.cpp3
-rw-r--r--indra/newview/llviewercamera.h22
-rw-r--r--indra/newview/llviewercontrol.cpp38
-rw-r--r--indra/newview/llviewercontrollistener.cpp8
-rw-r--r--indra/newview/llviewerdisplay.cpp159
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewerjointattachment.cpp6
-rw-r--r--indra/newview/llviewerjointmesh.cpp16
-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.cpp357
-rw-r--r--indra/newview/llvieweroctree.h7
-rw-r--r--indra/newview/llviewerparceloverlay.cpp1
-rw-r--r--indra/newview/llviewershadermgr.cpp1517
-rw-r--r--indra/newview/llviewershadermgr.h25
-rw-r--r--indra/newview/llviewerstats.cpp12
-rw-r--r--indra/newview/llviewerstats.h4
-rw-r--r--indra/newview/llviewertexture.cpp347
-rw-r--r--indra/newview/llviewertexture.h14
-rw-r--r--indra/newview/llviewertexturelist.cpp126
-rw-r--r--indra/newview/llviewerwindow.cpp143
-rw-r--r--indra/newview/llviewerwindow.h2
-rw-r--r--indra/newview/llvlcomposition.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp253
-rw-r--r--indra/newview/llvoavatar.h49
-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.cpp65
-rw-r--r--indra/newview/llvotree.cpp4
-rw-r--r--indra/newview/llvovolume.cpp984
-rw-r--r--indra/newview/llvovolume.h3
-rw-r--r--indra/newview/llvowater.cpp6
-rw-r--r--indra/newview/llvowlsky.cpp85
-rw-r--r--indra/newview/llvowlsky.h13
-rw-r--r--indra/newview/llworld.cpp11
-rw-r--r--indra/newview/llworld.h7
-rw-r--r--indra/newview/llworldmapmessage.cpp4
-rw-r--r--indra/newview/llworldmapview.cpp9
-rw-r--r--indra/newview/pipeline.cpp1467
-rw-r--r--indra/newview/pipeline.h55
-rw-r--r--indra/newview/skins/default/xui/da/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml40
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml19
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/floater_about.xml1
-rw-r--r--indra/newview/slplugin.entitlements2
-rw-r--r--indra/test/test.cpp1
372 files changed, 12892 insertions, 17822 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index f4071793d5..bb5dd8f847 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)
@@ -66,16 +66,21 @@ if (WINDOWS)
# CP changed to only append the flag for 32bit builds - on 64bit builds,
# locally at least, the build output is spammed with 1000s of 'D9002'
# warnings about this switch being ignored.
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
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 336896ed01..b408702f04 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -103,6 +103,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 a4600069ce..234f5c3007 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -142,17 +142,8 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target)
BOOL success = TRUE;
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- if (use_shaders)
- {
- gAlphaMaskProgram.bind();
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f);
- }
+ gAlphaMaskProgram.bind();
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
LLVertexBuffer::unbind();
@@ -164,10 +155,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target)
midRenderTexLayerSet(success);
- if (use_shaders)
- {
- gAlphaMaskProgram.unbind();
- }
+ gAlphaMaskProgram.unbind();
LLVertexBuffer::unbind();
@@ -390,8 +378,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget*
}
}
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
LLGLSUIDefault gls_ui;
LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
gGL.setColorMask(true, true);
@@ -400,20 +386,14 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget*
{
gGL.flush();
LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.0f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.0f);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4f( 0.f, 0.f, 0.f, 1.f );
gl_rect_2d_simple( width, height );
gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
if (mIsVisible)
@@ -440,10 +420,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget*
gGL.setSceneBlendType(LLRender::BT_REPLACE);
LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4f( 0.f, 0.f, 0.f, 0.f );
@@ -452,10 +429,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget*
gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
return success;
@@ -520,10 +494,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++ )
@@ -536,14 +509,11 @@ 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;
-
gGL.setColorMask(false, true);
gGL.setSceneBlendType(LLRender::BT_REPLACE);
@@ -557,7 +527,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
{
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->bind(tex);
- gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
gl_rect_2d_simple_tex( width, height );
}
}
@@ -568,20 +537,14 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
// Set the alpha channel to one (clean up after previous blending)
gGL.flush();
LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4f( 0.f, 0.f, 0.f, 1.f );
gl_rect_2d_simple( width, height );
gGL.flush();
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
// (Optional) Mask out part of the baked texture with alpha masks
@@ -589,7 +552,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
if (mMaskLayerList.size() > 0)
{
gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
- gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
{
LLTexLayerInterface* layer = *iter;
@@ -602,7 +564,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
gGL.setColorMask(true, true);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
@@ -1128,13 +1089,6 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou
// *TODO: Is this correct?
//gPipeline.disableLights();
stop_glerror();
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_LIGHTING);
- }
- stop_glerror();
-
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
LLColor4 net_color;
BOOL color_specified = findNetColor(&net_color);
@@ -1221,10 +1175,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou
LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
if (no_alpha_test)
{
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
}
LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
@@ -1238,10 +1189,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
if (no_alpha_test)
{
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
}
}
@@ -1275,18 +1223,12 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou
color_specified )
{
LLGLDisable no_alpha(GL_ALPHA_TEST);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.000f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.000f);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( net_color.mV );
gl_rect_2d_simple( width, height );
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
if( alpha_mask_specified || getInfo()->mWriteAllChannels )
@@ -1374,25 +1316,17 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
gGL.flush();
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
if( !getInfo()->mStaticImageFileName.empty() )
{
LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
if( tex )
{
LLGLSNoAlphaTest gls_no_alpha_test;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
gGL.getTexUnit(0)->bind(tex, TRUE);
gl_rect_2d_simple_tex( width, height );
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
else
{
@@ -1407,18 +1341,11 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
if (tex)
{
LLGLSNoAlphaTest gls_no_alpha_test;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
gGL.getTexUnit(0)->bind(tex);
gl_rect_2d_simple_tex( width, height );
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- success = TRUE;
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
}
}
}
@@ -1431,7 +1358,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())
@@ -1439,18 +1365,12 @@ 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() );
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.f);
- }
-
+ gAlphaMaskProgram.setMinimumAlpha(0.f);
gGL.setColorMask(false, true);
LLTexLayerParamAlpha* first_param = *mParamAlphaList.begin();
@@ -1535,10 +1455,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
gl_rect_2d_simple( width, height );
}
- if (use_shaders)
- {
- gAlphaMaskProgram.setMinimumAlpha(0.004f);
- }
+ gAlphaMaskProgram.setMinimumAlpha(0.004f);
LLGLSUIDefault gls_ui;
@@ -1637,10 +1554,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())
@@ -1981,10 +1897,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() )
@@ -2011,10 +1926,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);
@@ -2061,10 +1975,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 7842f0e5fb..9a41ba4d3d 100644
--- a/indra/llcharacter/llkeyframefallmotion.cpp
+++ b/indra/llcharacter/llkeyframefallmotion.cpp
@@ -121,6 +121,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 fe9de30f0a..5a5aa2c83e 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -677,6 +677,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..782f656406 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)
@@ -117,14 +119,16 @@ set(llcommon_SOURCE_FILES
lluriparser.cpp
lluuid.cpp
llworkerthread.cpp
- timing.cpp
u64.cpp
+ threadpool.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,12 @@ set(llcommon_HEADER_FILES
lockstatic.h
stdtypes.h
stringize.h
+ threadpool.h
+ threadsafeschedule.h
timer.h
+ tuple.h
u64.h
+ workqueue.h
StackWalker.h
)
@@ -299,6 +308,7 @@ target_link_libraries(
${BOOST_SYSTEM_LIBRARY}
${GOOGLE_PERFTOOLS_LIBRARIES}
${URIPARSER_LIBRARIES}
+ ${TRACY_LIBRARY}
)
if (DARWIN)
@@ -355,6 +365,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..da6e6affe1 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,29 @@ 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;
+ }
+
+ /**
+ * get(functor) returns whatever the functor returns. It allows us to peek
+ * at the stored DATA without copying the whole thing. The functor must
+ * accept a const reference to DATA. If you want to modify DATA, call
+ * update_one() or update_all() instead.
+ */
+ template <typename FUNC>
+ auto get(FUNC&& func)
+ {
+ LockType lk(mMutex);
+ return std::forward<FUNC>(func)(const_data());
+ }
/**
* Pass update_one() an invocable accepting non-const (DATA&). The
@@ -80,11 +101,11 @@ public:
* update_one() when DATA is a struct or class.
*/
template <typename MODIFY>
- void update_one(MODIFY modify)
+ void update_one(MODIFY&& modify)
{
{ // scope of lock can/should end before notify_one()
- LLCoros::LockType lk(mMutex);
- modify(mData);
+ LockType lk(mMutex);
+ std::forward<MODIFY>(modify)(mData);
}
mCond.notify_one();
}
@@ -99,11 +120,11 @@ public:
* update_all() when DATA is a struct or class.
*/
template <typename MODIFY>
- void update_all(MODIFY modify)
+ void update_all(MODIFY&& modify)
{
{ // scope of lock can/should end before notify_all()
- LLCoros::LockType lk(mMutex);
- modify(mData);
+ LockType lk(mMutex);
+ std::forward<MODIFY>(modify)(mData);
}
mCond.notify_all();
}
@@ -116,9 +137,9 @@ public:
* wait() on the condition_variable.
*/
template <typename Pred>
- void wait(Pred 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.
@@ -127,7 +148,7 @@ public:
// 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)))
+ while (! std::forward<Pred>(pred)(const_data()))
{
mCond.wait(lk);
}
@@ -144,7 +165,7 @@ public:
* returning true.
*/
template <typename Rep, typename Period, typename Pred>
- bool wait_for(const std::chrono::duration<Rep, Period>& timeout_duration, Pred pred)
+ bool wait_for(const std::chrono::duration<Rep, Period>& timeout_duration, Pred&& pred)
{
// Instead of replicating wait_until() logic, convert duration to
// time_point and just call wait_until().
@@ -153,7 +174,8 @@ public:
// wrong! We'd keep pushing the timeout time farther and farther into
// the future. This way, we establish a definite timeout time and
// stick to it.
- return wait_until(std::chrono::steady_clock::now() + timeout_duration, pred);
+ return wait_until(std::chrono::steady_clock::now() + timeout_duration,
+ std::forward<Pred>(pred));
}
/**
@@ -163,9 +185,9 @@ public:
* generic wait_for() method.
*/
template <typename Pred>
- bool wait_for(F32Milliseconds timeout_duration, Pred pred)
+ bool wait_for(F32Milliseconds timeout_duration, Pred&& pred)
{
- return wait_for(convert(timeout_duration), pred);
+ return wait_for(convert(timeout_duration), std::forward<Pred>(pred));
}
protected:
@@ -183,6 +205,10 @@ protected:
}
private:
+ // It's important to pass a const ref to certain user-specified functors
+ // that aren't supposed to be able to modify mData.
+ const value_type& const_data() const { return mData; }
+
/**
* Pass wait_until() a chrono::time_point, indicating the time at which we
* should stop waiting, and a predicate accepting (const DATA&), returning
@@ -203,21 +229,21 @@ private:
* honoring a fixed timeout.
*/
template <typename Clock, typename Duration, typename Pred>
- bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, Pred 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)))
+ while (! std::forward<Pred>(pred)(const_data()))
{
- 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
// wait_until() timed out, check the predicate one more time.
- return pred(const_cast<const value_type&>(mData));
+ return std::forward<Pred>(pred)(const_data());
}
}
return true;
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 3fe8ce5f0e..17a5ec5776 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;
@@ -194,7 +196,7 @@ namespace {
{
return LLError::getEnabledLogTypesMask() & 0x04;
}
-
+
LL_FORCE_INLINE std::string createBoldANSI()
{
std::string ansi_code;
@@ -220,10 +222,10 @@ namespace {
LL_FORCE_INLINE std::string createANSI(const std::string& color)
{
std::string ansi_code;
- ansi_code += '\033';
- ansi_code += "[";
+ ansi_code += '\033';
+ ansi_code += "[";
ansi_code += "38;5;";
- ansi_code += color;
+ ansi_code += color;
ansi_code += "m";
return ansi_code;
@@ -232,6 +234,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
// The default colors for error, warn and debug are now a bit more pastel
// and easier to read on the default (black) terminal background but you
// now have the option to set the color of each via an environment variables:
@@ -261,6 +264,7 @@ namespace {
}
else
{
+ LL_PROFILE_ZONE_NAMED("fprintf");
fprintf(stderr, "%s\n", message.c_str());
}
}
@@ -270,6 +274,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 = createBoldANSI(); // bold text
static std::string s_ansi_reset = createResetANSI(); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
@@ -306,6 +311,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
mBuffer->addLine(message);
}
@@ -332,6 +338,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
+ LL_PROFILE_ZONE_SCOPED
debugger_print(message);
}
};
@@ -1213,6 +1220,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();
@@ -1347,6 +1355,7 @@ namespace LLError
bool Log::shouldLog(CallSite& site)
{
+ LL_PROFILE_ZONE_SCOPED
LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
if (!lock.isLocked())
{
@@ -1391,6 +1400,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/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index b17a8e761a..dc586b0008 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -171,7 +171,9 @@
#define LL_DLLIMPORT
#endif // LL_WINDOWS
-#if ! defined(LL_WINDOWS)
+#if __clang__ || ! defined(LL_WINDOWS)
+// Only on Windows, and only with the Microsoft compiler (vs. clang) is
+// wchar_t potentially not a distinct type.
#define LL_WCHAR_T_NATIVE 1
#else // LL_WINDOWS
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
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..6042c0906c 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,36 @@ 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:
+ template <typename... ARGS>
+ static void createInstance(ARGS&&... args)
+ {
+ llassert(sInstance == nullptr);
+ sInstance = new T(std::forward<ARGS>(args)...);
+ }
+
+ 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;
+ }
+
+private:
+ static T* sInstance;
+};
+
+template <class T>
+T* LLSimpleton<T>::sInstance{ nullptr };
+
#endif
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 0290eea143..bdea1e76ea 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);
@@ -215,7 +212,7 @@ S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar)
return inchars - base;
}
-llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len)
+llutf16string wstring_to_utf16str(const llwchar* utf32str, size_t len)
{
llutf16string out;
@@ -237,27 +234,19 @@ llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len)
return out;
}
-llutf16string wstring_to_utf16str(const LLWString &utf32str)
-{
- const S32 len = (S32)utf32str.length();
- return wstring_to_utf16str(utf32str, len);
-}
-
-llutf16string utf8str_to_utf16str ( const std::string& utf8str )
+llutf16string utf8str_to_utf16str( const char* utf8str, size_t len )
{
- LLWString wstr = utf8str_to_wstring ( utf8str );
+ LLWString wstr = utf8str_to_wstring ( utf8str, len );
return wstring_to_utf16str ( wstr );
}
-
-LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len)
+LLWString utf16str_to_wstring(const U16* utf16str, size_t len)
{
LLWString wout;
- if((len <= 0) || utf16str.empty()) return wout;
+ if (len == 0) return wout;
S32 i = 0;
- // craziness to make gcc happy (llutf16string.c_str() is tweaked on linux):
- const U16* chars16 = &(*(utf16str.begin()));
+ const U16* chars16 = utf16str;
while (i < len)
{
llwchar cur_char;
@@ -267,12 +256,6 @@ LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len)
return wout;
}
-LLWString utf16str_to_wstring(const llutf16string &utf16str)
-{
- const S32 len = (S32)utf16str.length();
- return utf16str_to_wstring(utf16str, len);
-}
-
// Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string.
S32 utf16str_wstring_length(const llutf16string &utf16str, const S32 utf16_len)
{
@@ -392,8 +375,7 @@ S32 wstring_utf8_length(const LLWString& wstr)
return len;
}
-
-LLWString utf8str_to_wstring(const std::string& utf8str, S32 len)
+LLWString utf8str_to_wstring(const char* utf8str, size_t len)
{
LLWString wout;
@@ -481,13 +463,7 @@ LLWString utf8str_to_wstring(const std::string& utf8str, S32 len)
return wout;
}
-LLWString utf8str_to_wstring(const std::string& utf8str)
-{
- const S32 len = (S32)utf8str.length();
- return utf8str_to_wstring(utf8str, len);
-}
-
-std::string wstring_to_utf8str(const LLWString& utf32str, S32 len)
+std::string wstring_to_utf8str(const llwchar* utf32str, size_t len)
{
std::string out;
@@ -503,20 +479,9 @@ std::string wstring_to_utf8str(const LLWString& utf32str, S32 len)
return out;
}
-std::string wstring_to_utf8str(const LLWString& utf32str)
-{
- const S32 len = (S32)utf32str.length();
- return wstring_to_utf8str(utf32str, len);
-}
-
-std::string utf16str_to_utf8str(const llutf16string& utf16str)
-{
- return wstring_to_utf8str(utf16str_to_wstring(utf16str));
-}
-
-std::string utf16str_to_utf8str(const llutf16string& utf16str, S32 len)
+std::string utf16str_to_utf8str(const U16* utf16str, size_t len)
{
- return wstring_to_utf8str(utf16str_to_wstring(utf16str, len), len);
+ return wstring_to_utf8str(utf16str_to_wstring(utf16str, len));
}
std::string utf8str_trim(const std::string& utf8str)
@@ -657,17 +622,16 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
}
#if LL_WINDOWS
-std::string ll_convert_wide_to_string(const wchar_t* in)
+unsigned int ll_wstring_default_code_page()
{
- return ll_convert_wide_to_string(in, CP_UTF8);
+ return CP_UTF8;
}
-std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
+std::string ll_convert_wide_to_string(const wchar_t* in, size_t len_in, unsigned int code_page)
{
std::string out;
if(in)
{
- int len_in = wcslen(in);
int len_out = WideCharToMultiByte(
code_page,
0,
@@ -699,12 +663,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
return out;
}
-std::wstring ll_convert_string_to_wide(const std::string& in)
-{
- return ll_convert_string_to_wide(in, CP_UTF8);
-}
-
-std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
+std::wstring ll_convert_string_to_wide(const char* in, size_t len, unsigned int code_page)
{
// From review:
// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
@@ -716,10 +675,10 @@ std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_
// reserve an output buffer that will be destroyed on exit, with a place
// to put NULL terminator
- std::vector<wchar_t> w_out(in.length() + 1);
+ std::vector<wchar_t> w_out(len + 1);
memset(&w_out[0], 0, w_out.size());
- int real_output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(),
+ int real_output_str_len = MultiByteToWideChar(code_page, 0, in, len,
&w_out[0], w_out.size() - 1);
//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
@@ -729,30 +688,32 @@ std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_
return {&w_out[0]};
}
-LLWString ll_convert_wide_to_wstring(const std::wstring& in)
+LLWString ll_convert_wide_to_wstring(const wchar_t* in, size_t len)
{
- // This function, like its converse, is a placeholder, encapsulating a
- // guilty little hack: the only "official" way nat has found to convert
- // between std::wstring (16 bits on Windows) and LLWString (UTF-32) is
- // by using iconv, which we've avoided so far. It kinda sorta works to
- // just copy individual characters...
- // The point is that if/when we DO introduce some more official way to
- // perform such conversions, we should only have to call it here.
- return { in.begin(), in.end() };
+ // Whether or not std::wstring and llutf16string are distinct types, they
+ // both hold UTF-16LE characters. (See header file comments.) Pretend this
+ // wchar_t* sequence is really a U16* sequence and use the conversion we
+ // define above.
+ return utf16str_to_wstring(reinterpret_cast<const U16*>(in), len);
}
-std::wstring ll_convert_wstring_to_wide(const LLWString& in)
+std::wstring ll_convert_wstring_to_wide(const llwchar* in, size_t len)
{
- // See comments in ll_convert_wide_to_wstring()
- return { in.begin(), in.end() };
+ // first, convert to llutf16string, for which we have a real implementation
+ auto utf16str{ wstring_to_utf16str(in, len) };
+ // then, because each U16 char must be UTF-16LE encoded, pretend the U16*
+ // string pointer is a wchar_t* and instantiate a std::wstring of the same
+ // length.
+ return { reinterpret_cast<const wchar_t*>(utf16str.c_str()), utf16str.length() };
}
std::string ll_convert_string_to_utf8_string(const std::string& in)
{
- auto w_mesg = ll_convert_string_to_wide(in, CP_ACP);
- std::string out_utf8(ll_convert_wide_to_string(w_mesg.c_str(), CP_UTF8));
-
- return out_utf8;
+ // If you pass code_page, you must also pass length, otherwise the code
+ // page parameter will be mistaken for length.
+ auto w_mesg = ll_convert_string_to_wide(in, in.length(), CP_ACP);
+ // CP_UTF8 is default -- see ll_wstring_default_code_page() above.
+ return ll_convert_wide_to_string(w_mesg);
}
namespace
@@ -1356,7 +1317,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 +1390,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/llstring.h b/indra/llcommon/llstring.h
index 4263122f36..d94f549480 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -27,9 +27,11 @@
#ifndef LL_LLSTRING_H
#define LL_LLSTRING_H
+#include <boost/call_traits.hpp>
#include <boost/optional/optional.hpp>
#include <string>
#include <cstdio>
+#include <cwchar> // std::wcslen()
//#include <locale>
#include <iomanip>
#include <algorithm>
@@ -527,14 +529,71 @@ struct ll_convert_impl<T, T>
T operator()(const T& in) const { return in; }
};
+// simple construction from char*
+template<typename T>
+struct ll_convert_impl<T, const typename T::value_type*>
+{
+ T operator()(const typename T::value_type* in) const { return { in }; }
+};
+
// specialize ll_convert_impl<TO, FROM> to return EXPR
#define ll_convert_alias(TO, FROM, EXPR) \
template<> \
struct ll_convert_impl<TO, FROM> \
{ \
- TO operator()(const FROM& in) const { return EXPR; } \
+ /* param_type optimally passes both char* and string */ \
+ TO operator()(typename boost::call_traits<FROM>::param_type in) const { return EXPR; } \
+}
+
+// If all we're doing is copying characters, pass this to ll_convert_alias as
+// EXPR. Since it expands into the 'return EXPR' slot in the ll_convert_impl
+// specialization above, it implies TO{ in.begin(), in.end() }.
+#define LL_CONVERT_COPY_CHARS { in.begin(), in.end() }
+
+// Generic name for strlen() / wcslen() - the default implementation should
+// (!) work with U16 and llwchar, but we don't intend to engage it.
+template <typename CHARTYPE>
+size_t ll_convert_length(const CHARTYPE* zstr)
+{
+ const CHARTYPE* zp;
+ // classic C string scan
+ for (zp = zstr; *zp; ++zp)
+ ;
+ return (zp - zstr);
}
+// specialize where we have a library function; may use intrinsic operations
+template <>
+inline size_t ll_convert_length<wchar_t>(const wchar_t* zstr) { return std::wcslen(zstr); }
+template <>
+inline size_t ll_convert_length<char> (const char* zstr) { return std::strlen(zstr); }
+
+// ll_convert_forms() is short for a bunch of boilerplate. It defines
+// longname(const char*, len), longname(const char*), longname(const string&)
+// and longname(const string&, len) so calls written pre-ll_convert() will
+// work. Most of these overloads will be unified once we turn on C++17 and can
+// use std::string_view.
+// It also uses aliasmacro to ensure that both ll_convert<OUTSTR>(const char*)
+// and ll_convert<OUTSTR>(const string&) will work.
+#define ll_convert_forms(aliasmacro, OUTSTR, INSTR, longname) \
+LL_COMMON_API OUTSTR longname(const INSTR::value_type* in, size_t len); \
+inline auto longname(const INSTR& in, size_t len) \
+{ \
+ return longname(in.c_str(), len); \
+} \
+inline auto longname(const INSTR::value_type* in) \
+{ \
+ return longname(in, ll_convert_length(in)); \
+} \
+inline auto longname(const INSTR& in) \
+{ \
+ return longname(in.c_str(), in.length()); \
+} \
+/* string param */ \
+aliasmacro(OUTSTR, INSTR, longname(in)); \
+/* char* param */ \
+aliasmacro(OUTSTR, const INSTR::value_type*, longname(in))
+
// Make the incoming string a utf8 string. Replaces any unknown glyph
// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest
// of the data may not be recovered.
@@ -571,63 +630,47 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
// LL_WCHAR_T_NATIVE.
typedef std::basic_string<U16> llutf16string;
-#if ! defined(LL_WCHAR_T_NATIVE)
-// wchar_t is identical to U16, and std::wstring is identical to llutf16string.
-// Defining an ll_convert alias involving llutf16string would collide with the
-// comparable preferred alias involving std::wstring. (In this scenario, if
-// you pass llutf16string, it will engage the std::wstring specialization.)
-#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
-#else // defined(LL_WCHAR_T_NATIVE)
-// wchar_t is a distinct native type, so llutf16string is also a distinct
-// type, and there IS a point to converting separately to/from llutf16string.
-// (But why? Windows APIs are still defined in terms of wchar_t, and
-// in this scenario llutf16string won't work for them!)
-#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+// Considering wchar_t, llwchar and U16, there are three relevant cases:
+#if LLWCHAR_IS_WCHAR_T // every which way but Windows
+// llwchar is identical to wchar_t, LLWString is identical to std::wstring.
+// U16 is distinct, llutf16string is distinct (though pretty useless).
+// Given conversions to/from LLWString and to/from llutf16string, conversions
+// involving std::wstring would collide.
+#define ll_convert_wstr_alias(TO, FROM, EXPR) // nothing
+// but we can define conversions involving llutf16string without collisions
+#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+
+#elif defined(LL_WCHAR_T_NATIVE) // Windows, either clang or MS /Zc:wchar_t
+// llwchar (32-bit), wchar_t (16-bit) and U16 are all different types.
+// Conversions to/from LLWString, to/from std::wstring and to/from llutf16string
+// can all be defined.
+#define ll_convert_wstr_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+
+#else // ! LL_WCHAR_T_NATIVE: Windows with MS /Zc:wchar_t-
+// wchar_t is identical to U16, std::wstring is identical to llutf16string.
+// Given conversions to/from LLWString and to/from std::wstring, conversions
+// involving llutf16string would collide.
+#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
+// but we can define conversions involving std::wstring without collisions
+#define ll_convert_wstr_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+#endif
+
+ll_convert_forms(ll_convert_u16_alias, LLWString, llutf16string, utf16str_to_wstring);
+ll_convert_forms(ll_convert_u16_alias, llutf16string, LLWString, wstring_to_utf16str);
+ll_convert_forms(ll_convert_u16_alias, llutf16string, std::string, utf8str_to_utf16str);
+ll_convert_forms(ll_convert_alias, LLWString, std::string, utf8str_to_wstring);
-#if LL_WINDOWS
-// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact,
-// wchar_t is native. Everywhere but Windows, we use it for llwchar (see
-// stdtypes.h). That makes LLWString identical to std::wstring, so these
-// aliases for std::wstring would collide with those for LLWString. Only
-// define on Windows, where converting between std::wstring and llutf16string
-// means copying chars.
-ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end()));
-ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end()));
-#endif // LL_WINDOWS
-#endif // defined(LL_WCHAR_T_NATIVE)
-
-LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
-LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
-ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in));
-
-LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
-LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
-ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in));
-
-LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
-LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
-ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in));
-
-LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
-LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
// Same function, better name. JC
inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
-// best name of all
-ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in));
-//
LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
-LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
-LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
-ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in));
-LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
-LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
-ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in));
+ll_convert_forms(ll_convert_alias, std::string, LLWString, wstring_to_utf8str);
+ll_convert_forms(ll_convert_u16_alias, std::string, llutf16string, utf16str_to_utf8str);
-#if LL_WINDOWS
+// an older alias for utf16str_to_utf8str(llutf16string)
inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
-#endif
// Length of this UTF32 string in bytes when transformed to UTF8
LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr);
@@ -701,42 +744,48 @@ LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
//@{
/**
- * @brief Convert a wide string to std::string
+ * @brief Convert a wide string to/from std::string
+ * Convert a Windows wide string to/from our LLWString
*
* This replaces the unsafe W2A macro from ATL.
*/
-LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
-LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8
-inline std::string ll_convert_wide_to_string(const std::wstring& in, unsigned int code_page)
-{
- return ll_convert_wide_to_string(in.c_str(), code_page);
-}
-inline std::string ll_convert_wide_to_string(const std::wstring& in)
-{
- return ll_convert_wide_to_string(in.c_str());
-}
-ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in));
-
-/**
- * Converts a string to wide string.
- */
-LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in,
- unsigned int code_page);
-LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in);
- // default CP_UTF8
-ll_convert_alias(std::wstring, std::string, ll_convert_string_to_wide(in));
-
-/**
- * Convert a Windows wide string to our LLWString
- */
-LL_COMMON_API LLWString ll_convert_wide_to_wstring(const std::wstring& in);
-ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in));
-
-/**
- * Convert LLWString to Windows wide string
- */
-LL_COMMON_API std::wstring ll_convert_wstring_to_wide(const LLWString& in);
-ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in));
+// Avoid requiring this header to #include the Windows header file declaring
+// our actual default code_page by delegating this function to our .cpp file.
+LL_COMMON_API unsigned int ll_wstring_default_code_page();
+
+// This is like ll_convert_forms(), with the added complexity of a code page
+// parameter that may or may not be passed.
+#define ll_convert_cp_forms(aliasmacro, OUTSTR, INSTR, longname) \
+/* declare the only nontrivial implementation (in .cpp file) */ \
+LL_COMMON_API OUTSTR longname( \
+ const INSTR::value_type* in, \
+ size_t len, \
+ unsigned int code_page=ll_wstring_default_code_page()); \
+/* if passed only a char pointer, scan for nul terminator */ \
+inline auto longname(const INSTR::value_type* in) \
+{ \
+ return longname(in, ll_convert_length(in)); \
+} \
+/* if passed string and length, extract its char pointer */ \
+inline auto longname( \
+ const INSTR& in, \
+ size_t len, \
+ unsigned int code_page=ll_wstring_default_code_page()) \
+{ \
+ return longname(in.c_str(), len, code_page); \
+} \
+/* if passed only a string object, no scan, pass known length */ \
+inline auto longname(const INSTR& in) \
+{ \
+ return longname(in.c_str(), in.length()); \
+} \
+aliasmacro(OUTSTR, INSTR, longname(in)); \
+aliasmacro(OUTSTR, const INSTR::value_type*, longname(in))
+
+ll_convert_cp_forms(ll_convert_wstr_alias, std::string, std::wstring, ll_convert_wide_to_string);
+ll_convert_cp_forms(ll_convert_wstr_alias, std::wstring, std::string, ll_convert_string_to_wide);
+ ll_convert_forms(ll_convert_wstr_alias, LLWString, std::wstring, ll_convert_wide_to_wstring);
+ ll_convert_forms(ll_convert_wstr_alias, std::wstring, LLWString, ll_convert_wstring_to_wide);
/**
* Converts incoming string into utf8 string
@@ -1937,4 +1986,14 @@ void LLStringUtilBase<T>::truncate(string_type& string, size_type count)
string.resize(count < cur_size ? count : cur_size);
}
+// The good thing about *declaration* macros, vs. usage macros, is that now
+// we're done with them: we don't need them to bleed into the consuming source
+// file.
+#undef ll_convert_alias
+#undef ll_convert_u16_alias
+#undef ll_convert_wstr_alias
+#undef LL_CONVERT_COPY_CHARS
+#undef ll_convert_forms
+#undef ll_convert_cp_forms
+
#endif // LL_STRING_H
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..2806506550 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,116 @@ 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
- // reached capacity).
+ 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); }
+
+ // Add an element to the queue (will block if the queue has reached
+ // capacity). Return false if the queue is closed before push is possible.
+ template <typename T>
+ bool pushIfOpen(T&& 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); }
+
+ // 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 end of the queue (will block if the queue is
+ // 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 +186,154 @@ 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
{
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ 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>
+bool LLThreadSafeQueue<ElementT, QueueT>::pushIfOpen(T&& element)
+{
+ LL_PROFILE_ZONE_SCOPED;
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());
- }
+ return false;
- if (mStorage.size() < mCapacity)
- {
- mStorage.push_front(element);
- lock1.unlock();
- mEmptyCond.notify_one();
- return;
- }
+ if (push_(lock1, std::forward<T>(element)))
+ return true;
// Storage Full. Wait for signal.
mCapacityCond.wait(lock1);
@@ -175,142 +341,250 @@ 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>
+void LLThreadSafeQueue<ElementT, QueueT>::push(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;
+ LL_PROFILE_ZONE_SCOPED;
+ if (! pushIfOpen(std::forward<T>(element)))
+ {
+ LLTHROW(LLThreadSafeQueueInterrupt());
+ }
+}
- lock_t lock1(mLock, std::defer_lock);
- if (!lock1.try_lock_until(endpoint))
- return false;
- while (true)
- {
- if (mClosed)
+template<typename ElementT, typename QueueT>
+template<typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPush(T&& element)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ return tryLock(
+ [this, element=std::move(element)](lock_t& lock)
{
- return false;
- }
+ if (mClosed)
+ return false;
+ return push_(lock, std::move(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))
- {
- // 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, typename QueueT>
+template <typename Rep, typename Period, typename T>
+bool LLThreadSafeQueue<ElementT, QueueT>::tryPushFor(
+ const std::chrono::duration<Rep, Period>& timeout,
+ T&& element)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ // 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));
}
-template<typename ElementT>
-bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
+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)
{
- lock_t lock1(mLock, std::defer_lock);
- if (!lock1.try_lock())
- return false;
+ LL_PROFILE_ZONE_SCOPED;
+ return tryLockUntil(
+ until,
+ [this, until, element=std::move(element)](lock_t& lock)
+ {
+ 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.
+ }
+ });
+}
- if (mClosed)
- return false;
- if (mStorage.size() >= mCapacity)
- return false;
+// 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ // If mStorage is empty, there's no head element.
+ if (mStorage.empty())
+ return mClosed? DONE : EMPTY;
- mStorage.push_front(element);
- lock1.unlock();
- mEmptyCond.notify_one();
- return true;
+ // If there's a head element, pass it to canPop() to see if it's ready to pop.
+ if (! canPop(mStorage.front()))
+ return WAITING;
+
+ // 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)
{
+ LL_PROFILE_ZONE_SCOPED;
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;
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ // 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>
-size_t LLThreadSafeQueue<ElementT>::size(void)
+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)
{
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ 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, typename QueueT>
+size_t LLThreadSafeQueue<ElementT, QueueT>::size(void)
+{
+ LL_PROFILE_ZONE_SCOPED;
lock_t lock(mLock);
return mStorage.size();
}
-template<typename ElementT>
-void LLThreadSafeQueue<ElementT>::close()
+
+template<typename ElementT, typename QueueT>
+void LLThreadSafeQueue<ElementT, QueueT>::close()
{
+ LL_PROFILE_ZONE_SCOPED;
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()
{
+ LL_PROFILE_ZONE_SCOPED;
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();
+ LL_PROFILE_ZONE_SCOPED;
+ 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/stdtypes.h b/indra/llcommon/stdtypes.h
index 887f6ab733..b07805b628 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -42,10 +42,17 @@ typedef unsigned int U32;
// Windows wchar_t is 16-bit, whichever way /Zc:wchar_t is set. In effect,
// Windows wchar_t is always a typedef, either for unsigned short or __wchar_t.
// (__wchar_t, available either way, is Microsoft's native 2-byte wchar_t type.)
+// The version of clang available with VS 2019 also defines wchar_t as __wchar_t
+// which is also 16 bits.
// In any case, llwchar should be a UTF-32 type.
typedef U32 llwchar;
#else
typedef wchar_t llwchar;
+// What we'd actually want is a simple module-scope 'if constexpr' to test
+// std::is_same<wchar_t, llwchar>::value and use that to define, or not
+// define, string conversion specializations. Since we don't have that, we'll
+// have to rely on #if instead. Sorry, Dr. Stroustrup.
+#define LLWCHAR_IS_WCHAR_T 1
#endif
#if LL_WINDOWS
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index 38dd198ad3..12df693910 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -31,58 +31,109 @@
#include <sstream>
#include <llstring.h>
+#include <boost/call_traits.hpp>
/**
- * gstringize(item) encapsulates an idiom we use constantly, using
- * operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str()
- * or their wstring equivalents
- * to render a string expressing some item.
+ * stream_to(std::ostream&, items, ...) streams each item in the parameter list
+ * to the passed std::ostream using the insertion operator <<. This can be
+ * used, for instance, to make a simple print() function, e.g.:
+ *
+ * @code
+ * template <typename... Items>
+ * void print(Items&&... items)
+ * {
+ * stream_to(std::cout, std::forward<Items>(items)...);
+ * }
+ * @endcode
*/
-template <typename CHARTYPE, typename T>
-std::basic_string<CHARTYPE> gstringize(const T& item)
+// recursion tail
+template <typename CHARTYPE>
+void stream_to(std::basic_ostream<CHARTYPE>& out) {}
+// stream one or more items
+template <typename CHARTYPE, typename T, typename... Items>
+void stream_to(std::basic_ostream<CHARTYPE>& out, T&& item, Items&&... items)
{
- std::basic_ostringstream<CHARTYPE> out;
- out << item;
- return out.str();
+ out << std::forward<T>(item);
+ stream_to(out, std::forward<Items>(items)...);
}
+// why we use function overloads, not function template specializations:
+// http://www.gotw.ca/publications/mill17.htm
+
/**
- *partial specialization of stringize for handling wstring
- *TODO: we should have similar specializations for wchar_t[] but not until it is needed.
+ * gstringize(item, ...) encapsulates an idiom we use constantly, using
+ * operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str()
+ * or their wstring equivalents to render a string expressing one or more items.
*/
-inline std::string stringize(const std::wstring& item)
+// two or more args - the case of a single argument is handled separately
+template <typename CHARTYPE, typename T0, typename T1, typename... Items>
+auto gstringize(T0&& item0, T1&& item1, Items&&... items)
{
- return wstring_to_utf8str(item);
+ std::basic_ostringstream<CHARTYPE> out;
+ stream_to(out, std::forward<T0>(item0), std::forward<T1>(item1),
+ std::forward<Items>(items)...);
+ return out.str();
}
-/**
- * Specialization of gstringize for std::string return types
- */
-template <typename T>
-std::string stringize(const T& item)
+// generic single argument: stream to out, as above
+template <typename CHARTYPE, typename T>
+struct gstringize_impl
{
- return gstringize<char>(item);
+ auto operator()(typename boost::call_traits<T>::param_type arg)
+ {
+ std::basic_ostringstream<CHARTYPE> out;
+ out << arg;
+ return out.str();
+ }
+};
+
+// partially specialize for a single STRING argument -
+// note that ll_convert<T>(T) already handles the trivial case
+template <typename OUTCHAR, typename INCHAR>
+struct gstringize_impl<OUTCHAR, std::basic_string<INCHAR>>
+{
+ auto operator()(const std::basic_string<INCHAR>& arg)
+ {
+ return ll_convert<std::basic_string<OUTCHAR>>(arg);
+ }
+};
+
+// partially specialize for a single CHARTYPE* argument -
+// since it's not a basic_string and we do want to optimize this common case
+template <typename OUTCHAR, typename INCHAR>
+struct gstringize_impl<OUTCHAR, INCHAR*>
+{
+ auto operator()(const INCHAR* arg)
+ {
+ return ll_convert<std::basic_string<OUTCHAR>>(arg);
+ }
+};
+
+// gstringize(single argument)
+template <typename CHARTYPE, typename T>
+auto gstringize(T&& item)
+{
+ // use decay<T> so we don't require separate specializations
+ // for T, const T, T&, const T& ...
+ return gstringize_impl<CHARTYPE, std::decay_t<T>>()(std::forward<T>(item));
}
/**
- * Specialization for generating wstring from string.
- * Both a convenience function and saves a miniscule amount of overhead.
+ * Specialization of gstringize for std::string return types
*/
-inline std::wstring wstringize(const std::string& item)
+template <typename... Items>
+auto stringize(Items&&... items)
{
- // utf8str_to_wstring() returns LLWString, which isn't necessarily the
- // same as std::wstring
- LLWString s(utf8str_to_wstring(item));
- return std::wstring(s.begin(), s.end());
+ return gstringize<char>(std::forward<Items>(items)...);
}
/**
* Specialization of gstringize for std::wstring return types
*/
-template <typename T>
-std::wstring wstringize(const T& item)
+template <typename... Items>
+auto wstringize(Items&&... items)
{
- return gstringize<wchar_t>(item);
+ return gstringize<wchar_t>(std::forward<Items>(items)...);
}
/**
@@ -146,11 +197,9 @@ void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
* std::istringstream in(str);
* in >> item1 >> item2 >> item3 ... ;
* @endcode
- * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
- * more since DESTRINGIZE() should do the right thing with a std::wstring. But
- * until then, the lambda we pass must accept the right std::basic_istream.
*/
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
-#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](auto& in){in >> EXPRESSION;}))
+// legacy name, just use DESTRINGIZE() going forward
+#define DEWSTRINGIZE(STR, EXPRESSION) DESTRINGIZE(STR, EXPRESSION)
#endif /* ! defined(LL_STRINGIZE_H) */
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..c421cc7b1c
--- /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() + 200ms, "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() + 100ms, "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..1d73f7aa0d
--- /dev/null
+++ b/indra/llcommon/tests/workqueue_test.cpp
@@ -0,0 +1,235 @@
+/**
+ * @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 "../test/catch_and_store_what_in.h"
+#include "llcond.h"
+#include "llcoros.h"
+#include "lleventcoro.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 have exhausted the iterations
+ // or we time out waiting
+ for (auto finish = start + 10*interval;
+ WorkQueue::TimePoint::clock::now() < finish &&
+ data.get([](const Shared& data){ return data.size(); }) < 3; )
+ {
+ queue.runPending();
+ std::this_thread::sleep_for(interval/10);
+ }
+ // 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. (Of course the bound variable must
+ // survive until the callback is called.)
+ [&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");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("postTo with void return");
+ WorkQueue main("main");
+ auto qptr = WorkQueue::getInstance("queue");
+ std::string observe;
+ main.postTo(
+ qptr,
+ // The ONLY reason we can get away with binding a reference to
+ // 'observe' in our work callable is because we're directly
+ // calling qptr->runOne() on this same thread. It would be a
+ // mistake to do that if some other thread were servicing 'queue'.
+ [&observe](){ observe = "queue"; },
+ [&observe](){ observe.append(";main"); });
+ qptr->runOne();
+ main.runOne();
+ ensure_equals("failed to run both lambdas", observe, "queue;main");
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("waitForResult");
+ std::string stored;
+ // Try to call waitForResult() on this thread's main coroutine. It
+ // should throw because the main coroutine must service the queue.
+ auto what{ catch_what<WorkQueue::Error>(
+ [this, &stored](){ stored = queue.waitForResult(
+ [](){ return "should throw"; }); }) };
+ ensure("lambda should not have run", stored.empty());
+ ensure_not("waitForResult() should have thrown", what.empty());
+ ensure(STRINGIZE("should mention waitForResult: " << what),
+ what.find("waitForResult") != std::string::npos);
+
+ // Call waitForResult() on a coroutine, with a string result.
+ LLCoros::instance().launch(
+ "waitForResult string",
+ [this, &stored]()
+ { stored = queue.waitForResult(
+ [](){ return "string result"; }); });
+ llcoro::suspend();
+ // Nothing will have happened yet because, even if the coroutine did
+ // run immediately, all it did was to queue the inner lambda on
+ // 'queue'. Service it.
+ queue.runOne();
+ llcoro::suspend();
+ ensure_equals("bad waitForResult return", stored, "string result");
+
+ // Call waitForResult() on a coroutine, with a void callable.
+ stored.clear();
+ bool done = false;
+ LLCoros::instance().launch(
+ "waitForResult void",
+ [this, &stored, &done]()
+ {
+ queue.waitForResult([&stored](){ stored = "ran"; });
+ done = true;
+ });
+ llcoro::suspend();
+ queue.runOne();
+ llcoro::suspend();
+ ensure_equals("didn't run coroutine", stored, "ran");
+ ensure("void waitForResult() didn't return", done);
+ }
+} // namespace tut
diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp
new file mode 100644
index 0000000000..ba914035e2
--- /dev/null
+++ b/indra/llcommon/threadpool.cpp
@@ -0,0 +1,88 @@
+/**
+ * @file threadpool.cpp
+ * @author Nat Goodspeed
+ * @date 2021-10-21
+ * @brief Implementation for threadpool.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "threadpool.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llerror.h"
+#include "llevents.h"
+#include "stringize.h"
+
+LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
+ mQueue(name, capacity),
+ mName("ThreadPool:" + name),
+ mThreadCount(threads)
+{}
+
+void LL::ThreadPool::start()
+{
+ for (size_t i = 0; i < mThreadCount; ++i)
+ {
+ std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) };
+ mThreads.emplace_back(tname, [this, tname]()
+ {
+ LL_PROFILER_SET_THREAD_NAME(tname.c_str());
+ run(tname);
+ });
+ }
+ // Listen on "LLApp", and when the app is shutting down, close the queue
+ // and join the workers.
+ LLEventPumps::instance().obtain("LLApp").listen(
+ mName,
+ [this](const LLSD& stat)
+ {
+ std::string status(stat["status"]);
+ if (status != "running")
+ {
+ // viewer is starting shutdown -- proclaim the end is nigh!
+ LL_DEBUGS("ThreadPool") << mName << " saw " << status << LL_ENDL;
+ close();
+ }
+ return false;
+ });
+}
+
+LL::ThreadPool::~ThreadPool()
+{
+ close();
+}
+
+void LL::ThreadPool::close()
+{
+ if (! mQueue.isClosed())
+ {
+ LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL;
+ mQueue.close();
+ for (auto& pair: mThreads)
+ {
+ LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
+ pair.second.join();
+ }
+ LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL;
+ }
+}
+
+void LL::ThreadPool::run(const std::string& name)
+{
+ LL_DEBUGS("ThreadPool") << name << " starting" << LL_ENDL;
+ run();
+ LL_DEBUGS("ThreadPool") << name << " stopping" << LL_ENDL;
+}
+
+void LL::ThreadPool::run()
+{
+ mQueue.runUntilClose();
+}
diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h
new file mode 100644
index 0000000000..b79c9b9090
--- /dev/null
+++ b/indra/llcommon/threadpool.h
@@ -0,0 +1,71 @@
+/**
+ * @file threadpool.h
+ * @author Nat Goodspeed
+ * @date 2021-10-21
+ * @brief ThreadPool configures a WorkQueue along with a pool of threads to
+ * service it.
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Copyright (c) 2021, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_THREADPOOL_H)
+#define LL_THREADPOOL_H
+
+#include "workqueue.h"
+#include <string>
+#include <thread>
+#include <utility> // std::pair
+#include <vector>
+
+namespace LL
+{
+
+ class ThreadPool
+ {
+ public:
+ /**
+ * Pass ThreadPool a string name. This can be used to look up the
+ * relevant WorkQueue.
+ */
+ ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024);
+ virtual ~ThreadPool();
+
+ /**
+ * Launch the ThreadPool. Until this call, a constructed ThreadPool
+ * launches no threads. That permits coders to derive from ThreadPool,
+ * or store it as a member of some other class, but refrain from
+ * launching it until all other construction is complete.
+ */
+ void start();
+
+ /**
+ * ThreadPool listens for application shutdown messages on the "LLApp"
+ * LLEventPump. Call close() to shut down this ThreadPool early.
+ */
+ void close();
+
+ std::string getName() const { return mName; }
+ size_t getWidth() const { return mThreads.size(); }
+ /// obtain a non-const reference to the WorkQueue to post work to it
+ WorkQueue& getQueue() { return mQueue; }
+
+ /**
+ * Override run() if you need special processing. The default run()
+ * implementation simply calls WorkQueue::runUntilClose().
+ */
+ virtual void run();
+
+ private:
+ void run(const std::string& name);
+
+ WorkQueue mQueue;
+ std::string mName;
+ size_t mThreadCount;
+ std::vector<std::pair<std::string, std::thread>> mThreads;
+ };
+
+} // namespace LL
+
+#endif /* ! defined(LL_THREADPOOL_H) */
diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h
new file mode 100644
index 0000000000..601681d550
--- /dev/null
+++ b/indra/llcommon/threadsafeschedule.h
@@ -0,0 +1,399 @@
+/**
+ * @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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ push(tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass each component of the TimeTuple
+ void push(const TimePoint& time, Args&&... args)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ push(Clock::now(), std::forward<Args>(args)...);
+ }
+
+ /*--------------------------- tryPush() ----------------------------*/
+ /// explicit TimeTuple
+ using super::tryPush;
+
+ /// DataTuple with implicit now
+ bool tryPush(const DataTuple& tuple)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return tryPush(tuple_cons(Clock::now(), tuple));
+ }
+
+ /// individually pass components
+ bool tryPush(const TimePoint& time, Args&&... args)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return tryPush(TimeTuple(time, std::forward<Args>(args)...));
+ }
+
+ /// individually pass components with implicit now
+ bool tryPush(Args&&... args)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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()
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ return tuple_cdr(popWithTime());
+ }
+
+ /// pop TimeTuple by value
+ TimeTuple popWithTime()
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ TimePoint adjusted = until;
+ if (! super::mStorage.empty())
+ {
+ LL_PROFILE_ZONE_NAMED("tpu - adjust");
+ // 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;
+ {
+ LL_PROFILE_ZONE_NAMED("tpu - super");
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // 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/timing.cpp b/indra/llcommon/timing.cpp
deleted file mode 100644
index c2dc695ef3..0000000000
--- a/indra/llcommon/timing.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @file timing.cpp
- * @brief This file will be deprecated in the future.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
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..c74dada2e4
--- /dev/null
+++ b/indra/llcommon/workqueue.cpp
@@ -0,0 +1,158 @@
+/**
+ * @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, size_t capacity):
+ super(makeName(name)),
+ mQueue(capacity)
+{
+ // TODO: register for "LLApp" events so we can implicitly close() on
+ // viewer shutdown.
+}
+
+void LL::WorkQueue::close()
+{
+ mQueue.close();
+}
+
+size_t LL::WorkQueue::size()
+{
+ return mQueue.size();
+}
+
+bool LL::WorkQueue::isClosed()
+{
+ return mQueue.isClosed();
+}
+
+bool LL::WorkQueue::done()
+{
+ return mQueue.done();
+}
+
+void LL::WorkQueue::runUntilClose()
+{
+ try
+ {
+ for (;;)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ // Should we subtract some slop to allow for typical Work execution time?
+ // How much slop?
+ // runUntil() is simply a time-bounded runPending().
+ for (Work work; TimePoint::clock::now() < until && mQueue.tryPop(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;
+}
+
+void LL::WorkQueue::checkCoroutine(const std::string& method)
+{
+ // By convention, the default coroutine on each thread has an empty name
+ // string. See also LLCoros::logname().
+ if (LLCoros::getName().empty())
+ {
+ LLTHROW(Error("Do not call " + method + " from a thread's default coroutine"));
+ }
+}
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
new file mode 100644
index 0000000000..96574a18b9
--- /dev/null
+++ b/indra/llcommon/workqueue.h
@@ -0,0 +1,574 @@
+/**
+ * @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 "llcoros.h"
+#include "llexception.h"
+#include "llinstancetracker.h"
+#include "threadsafeschedule.h"
+#include <chrono>
+#include <exception> // std::current_exception
+#include <functional> // std::function
+#include <string>
+
+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;
+
+ struct Error: public LLException
+ {
+ Error(const std::string& what): LLException(what) {}
+ };
+
+ /**
+ * 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(), size_t capacity=1024);
+
+ /**
+ * 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();
+
+ /**
+ * WorkQueue supports multiple producers and multiple consumers. In
+ * the general case it's misleading to test size(), since any other
+ * thread might change it the nanosecond the lock is released. On that
+ * basis, some might argue against publishing a size() method at all.
+ *
+ * But there are two specific cases in which a test based on size()
+ * might be reasonable:
+ *
+ * * If you're the only producer, noticing that size() == 0 is
+ * meaningful.
+ * * If you're the only consumer, noticing that size() > 0 is
+ * meaningful.
+ */
+ size_t size();
+ /// producer end: are we prevented from pushing any additional items?
+ bool isClosed();
+ /// consumer end: are we done, is the queue entirely drained?
+ bool done();
+
+ /*---------------------- 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 or
+ // postIfOpen(). 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));
+ }
+
+ /**
+ * post work for a particular time, unless the queue is closed before
+ * we can post
+ */
+ template <typename CALLABLE>
+ bool postIfOpen(const TimePoint& time, CALLABLE&& callable)
+ {
+ // Defer reifying an arbitrary CALLABLE until we hit this or
+ // post(). All other methods should accept CALLABLEs of arbitrary
+ // type to avoid multiple levels of std::function indirection.
+ return mQueue.pushIfOpen(TimedWork(time, std::move(callable)));
+ }
+
+ /**
+ * post work, unless the queue is closed before we can post
+ */
+ template <typename CALLABLE>
+ bool postIfOpen(CALLABLE&& callable)
+ {
+ return postIfOpen(TimePoint::clock::now(), std::move(callable));
+ }
+
+ /**
+ * Post work to be run at a specified time to another WorkQueue, which
+ * may or may not still exist and be open. Return true if we were able
+ * to post.
+ */
+ template <typename CALLABLE>
+ static bool postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable);
+
+ /**
+ * Post work to another WorkQueue, which may or may not still exist
+ * and be open. Return true if we were able to post.
+ */
+ template <typename CALLABLE>
+ static bool postMaybe(weak_t target, CALLABLE&& callable)
+ {
+ return postMaybe(target, TimePoint::clock::now(),
+ std::forward<CALLABLE>(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(weak_t target,
+ const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback);
+
+ /**
+ * 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(weak_t target, CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ return postTo(target, TimePoint::clock::now(),
+ std::move(callable), std::move(callback));
+ }
+
+ /**
+ * Post work to another WorkQueue to be run at a specified time,
+ * blocking the calling coroutine until then, returning the result to
+ * caller on completion.
+ *
+ * In general, we assume that each thread's default coroutine is busy
+ * servicing its WorkQueue or whatever. To try to prevent mistakes, we
+ * forbid calling waitForResult() from a thread's default coroutine.
+ */
+ template <typename CALLABLE>
+ auto waitForResult(const TimePoint& time, CALLABLE&& callable);
+
+ /**
+ * Post work to another WorkQueue, blocking the calling coroutine
+ * until then, returning the result to caller on completion.
+ *
+ * In general, we assume that each thread's default coroutine is busy
+ * servicing its WorkQueue or whatever. To try to prevent mistakes, we
+ * forbid calling waitForResult() from a thread's default coroutine.
+ */
+ template <typename CALLABLE>
+ auto waitForResult(CALLABLE&& callable)
+ {
+ return waitForResult(TimePoint::clock::now(), std::move(callable));
+ }
+
+ /*--------------------------- 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)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ 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:
+ template <typename CALLABLE, typename FOLLOWUP>
+ static auto makeReplyLambda(CALLABLE&& callable, FOLLOWUP&& callback);
+ /// general case: arbitrary C++ return type
+ template <typename CALLABLE, typename FOLLOWUP, typename RETURNTYPE>
+ struct MakeReplyLambda;
+ /// specialize for CALLABLE returning void
+ template <typename CALLABLE, typename FOLLOWUP>
+ struct MakeReplyLambda<CALLABLE, FOLLOWUP, void>;
+
+ /// general case: arbitrary C++ return type
+ template <typename CALLABLE, typename RETURNTYPE>
+ struct WaitForResult;
+ /// specialize for CALLABLE returning void
+ template <typename CALLABLE>
+ struct WaitForResult<CALLABLE, void>;
+
+ static void checkCoroutine(const std::string& method);
+ 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(weak_t target,
+ const 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:
+ weak_t mTarget;
+ 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)));
+ }
+
+ /// general case: arbitrary C++ return type
+ template <typename CALLABLE, typename FOLLOWUP, typename RETURNTYPE>
+ struct WorkQueue::MakeReplyLambda
+ {
+ auto operator()(CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ // Call the callable in any case -- but to minimize
+ // copying the result, immediately bind it into the 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().
+ return
+ [result = std::forward<CALLABLE>(callable)(),
+ callback = std::move(callback)]
+ ()
+ { callback(std::move(result)); };
+ }
+ };
+
+ /// specialize for CALLABLE returning void
+ template <typename CALLABLE, typename FOLLOWUP>
+ struct WorkQueue::MakeReplyLambda<CALLABLE, FOLLOWUP, void>
+ {
+ auto operator()(CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ // Call the callable, which produces no result.
+ std::forward<CALLABLE>(callable)();
+ // Our completion callback is simply the caller's callback.
+ return std::move(callback);
+ }
+ };
+
+ template <typename CALLABLE, typename FOLLOWUP>
+ auto WorkQueue::makeReplyLambda(CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ return MakeReplyLambda<CALLABLE, FOLLOWUP,
+ decltype(std::forward<CALLABLE>(callable)())>()
+ (std::move(callable), std::move(callback));
+ }
+
+ template <typename CALLABLE, typename FOLLOWUP>
+ bool WorkQueue::postTo(weak_t target,
+ const TimePoint& time, CALLABLE&& callable, FOLLOWUP&& callback)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // 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)]
+ ()
+ {
+ // Use postMaybe() below in case this originating WorkQueue
+ // has been closed or destroyed. 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.
+ try
+ {
+ // Make a reply lambda to repost to THIS WorkQueue.
+ // Delegate to makeReplyLambda() so we can partially
+ // specialize on void return.
+ postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback)));
+ }
+ catch (...)
+ {
+ // Either variant of makeReplyLambda() is responsible for
+ // calling the caller's callable. If that throws, return
+ // the exception to the originating thread.
+ postMaybe(
+ reply,
+ // Bind the current exception to transport back to the
+ // originating WorkQueue. Once there, rethrow it.
+ [exc = std::current_exception()](){ std::rethrow_exception(exc); });
+ }
+ });
+
+ // looks like we were able to post()
+ return true;
+ }
+
+ template <typename CALLABLE>
+ bool WorkQueue::postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // target is a weak_ptr: have to lock it to check it
+ auto tptr = target.lock();
+ if (tptr)
+ {
+ try
+ {
+ tptr->post(time, std::forward<CALLABLE>(callable));
+ // we were able to post()
+ return true;
+ }
+ catch (const Closed&)
+ {
+ // target WorkQueue still exists, but is Closed
+ }
+ }
+ // either target no longer exists, or its WorkQueue is Closed
+ return false;
+ }
+
+ /// general case: arbitrary C++ return type
+ template <typename CALLABLE, typename RETURNTYPE>
+ struct WorkQueue::WaitForResult
+ {
+ auto operator()(WorkQueue* self, const TimePoint& time, CALLABLE&& callable)
+ {
+ LLCoros::Promise<RETURNTYPE> promise;
+ self->post(
+ time,
+ // We dare to bind a reference to Promise because it's
+ // specifically designed for cross-thread communication.
+ [&promise, callable = std::move(callable)]()
+ {
+ try
+ {
+ // call the caller's callable and trigger promise with result
+ promise.set_value(callable());
+ }
+ catch (...)
+ {
+ promise.set_exception(std::current_exception());
+ }
+ });
+ auto future{ LLCoros::getFuture(promise) };
+ // now, on the calling thread, wait for that result
+ LLCoros::TempStatus st("waiting for WorkQueue::waitForResult()");
+ return future.get();
+ }
+ };
+
+ /// specialize for CALLABLE returning void
+ template <typename CALLABLE>
+ struct WorkQueue::WaitForResult<CALLABLE, void>
+ {
+ void operator()(WorkQueue* self, const TimePoint& time, CALLABLE&& callable)
+ {
+ LLCoros::Promise<void> promise;
+ self->post(
+ time,
+ // &promise is designed for cross-thread access
+ [&promise, callable = std::move(callable)]()
+ {
+ try
+ {
+ callable();
+ promise.set_value();
+ }
+ catch (...)
+ {
+ promise.set_exception(std::current_exception());
+ }
+ });
+ auto future{ LLCoros::getFuture(promise) };
+ // block until set_value()
+ LLCoros::TempStatus st("waiting for void WorkQueue::waitForResult()");
+ future.get();
+ }
+ };
+
+ template <typename CALLABLE>
+ auto WorkQueue::waitForResult(const TimePoint& time, CALLABLE&& callable)
+ {
+ checkCoroutine("waitForResult()");
+ // derive callable's return type so we can specialize for void
+ return WaitForResult<CALLABLE, decltype(std::forward<CALLABLE>(callable)())>()
+ (this, time, std::forward<CALLABLE>(callable));
+ }
+
+} // namespace LL
+
+#endif /* ! defined(LL_WORKQUEUE_H) */
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 8922f46ffe..15b07e5318 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;
}
@@ -2254,9 +2249,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..2cf50e9cd2 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,14 +64,29 @@ 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]);
mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);
mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);
mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]);
-
}
+
+ inline void loadu(const F32* src)
+ {
+ mMatrix[0] = _mm_loadu_ps(src);
+ mMatrix[1] = _mm_loadu_ps(src+4);
+ mMatrix[2] = _mm_loadu_ps(src+8);
+ mMatrix[3] = _mm_loadu_ps(src+12);
+ }
inline void loadu(const LLMatrix3& src)
{
@@ -105,7 +140,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 +186,8 @@ public:
{
affineTransformSSE(v,res);
}
+
+ const LLVector4a& getTranslation() const { return mMatrix[3]; }
};
inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat)
@@ -176,6 +213,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 b036ece71e..c226315e5c 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 93d492b42d..4b13da5586 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1224,17 +1224,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);
}
@@ -1452,7 +1454,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));
}
}
}
@@ -1526,9 +1528,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..dd37b8ce0b 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -31,6 +31,7 @@
#include "llconvexdecomposition.h"
#include "llsdserialize.h"
#include "llvector4a.h"
+#include "llmd5.h"
#ifdef LL_USESYSTEMLIBS
# include <zlib.h>
@@ -1396,7 +1397,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
}
}
- mInvBindMatrix.push_back(mat);
+ mInvBindMatrix.push_back(LLMatrix4a(mat));
}
if (mJointNames.size() != mInvBindMatrix.size())
@@ -1410,13 +1411,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 +1435,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
}
}
- mAlternateBindMatrix.push_back(mat);
+ mAlternateBindMatrix.push_back(LLMatrix4a(mat));
}
}
@@ -1449,6 +1452,8 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
mLockScaleIfJointPosition = false;
}
+
+ updateHash();
}
LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const
@@ -1500,6 +1505,38 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi
return ret;
}
+void LLMeshSkinInfo::updateHash()
+{
+ // get hash of data relevant to render batches
+ LLMD5 hash;
+
+ //mJointNames
+ for (auto& name : mJointNames)
+ {
+ hash.update(name);
+ }
+
+ //mJointNums
+ hash.update((U8*)&(mJointNums[0]), sizeof(S32) * mJointNums.size());
+
+ //mInvBindMatrix
+ F32* src = mInvBindMatrix[0].getF32ptr();
+
+ for (int i = 0; i < mInvBindMatrix.size() * 16; ++i)
+ {
+ S32 t = llround(src[i] * 10000.f);
+ hash.update((U8*)&t, sizeof(S32));
+ }
+ //hash.update((U8*)&(mInvBindMatrix[0]), sizeof(LLMatrix4a) * mInvBindMatrix.size());
+
+ hash.finalize();
+
+ U64 digest[2];
+ hash.raw_digest((U8*) digest);
+
+ mHash = digest[0];
+}
+
LLModel::Decomposition::Decomposition(LLSD& data)
{
fromLLSD(data);
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index 96368d64e5..3881b1338c 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -33,34 +33,44 @@
#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);
void fromLLSD(LLSD& data);
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
+ void updateHash();
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;
+
+ LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
- LLMatrix4 mBindShapeMatrix;
float mPelvisOffset;
bool mLockScaleIfJointPosition;
bool mInvalidJointsScrubbed;
bool mJointNumsInitialized;
-};
+ U64 mHash = 0;
+} LL_ALIGN_POSTFIX(16);
+LL_ALIGN_PREFIX(16)
class LLModel : public LLVolume
{
+ LL_ALIGN_NEW
public:
enum
@@ -284,7 +294,7 @@ public:
// A model/object can only have 8 faces, spillover faces will
// be moved to new model/object and assigned a submodel id.
int mSubmodelID;
-};
+} LL_ALIGN_POSTFIX(16);
typedef std::vector<LLPointer<LLModel> > model_list;
typedef std::queue<LLPointer<LLModel> > model_queue;
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 5947bca670..834084674e 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -47,7 +47,6 @@ bool LLCubeMap::sUseCubeMaps = true;
LLCubeMap::LLCubeMap(bool init_as_srgb)
: mTextureStage(0),
- mTextureCoordStage(0),
mMatrixStage(0),
mIssRGB(init_as_srgb)
{
@@ -150,6 +149,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);
@@ -179,7 +179,6 @@ void LLCubeMap::bind()
void LLCubeMap::enable(S32 stage)
{
enableTexture(stage);
- enableTextureCoords(stage);
}
void LLCubeMap::enableTexture(S32 stage)
@@ -191,35 +190,9 @@ void LLCubeMap::enableTexture(S32 stage)
}
}
-void LLCubeMap::enableTextureCoords(S32 stage)
-{
- mTextureCoordStage = stage;
- if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
- {
- if (stage > 0)
- {
- gGL.getTexUnit(stage)->activate();
- }
-
- glEnable(GL_TEXTURE_GEN_R);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
- glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
-
- if (stage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }
- }
-}
-
void LLCubeMap::disable(void)
{
disableTexture();
- disableTextureCoords();
}
void LLCubeMap::disableTexture(void)
@@ -234,24 +207,6 @@ void LLCubeMap::disableTexture(void)
}
}
-void LLCubeMap::disableTextureCoords(void)
-{
- if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
- {
- if (mTextureCoordStage > 0)
- {
- gGL.getTexUnit(mTextureCoordStage)->activate();
- }
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_GEN_R);
- if (mTextureCoordStage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }
- }
-}
-
void LLCubeMap::setMatrix(S32 stage)
{
mMatrixStage = stage;
@@ -453,6 +408,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/llcubemap.h b/indra/llrender/llcubemap.h
index 95b6d12099..a01636d8d4 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -48,12 +48,10 @@ public:
void enable(S32 stage);
void enableTexture(S32 stage);
- void enableTextureCoords(S32 stage);
S32 getStage(void) { return mTextureStage; }
void disable(void);
void disableTexture(void);
- void disableTextureCoords(void);
void setMatrix(S32 stage);
void restoreMatrix();
void setReflection (void);
@@ -80,7 +78,6 @@ protected:
LLPointer<LLImageGL> mImages[6];
LLPointer<LLImageRaw> mRawImages[6];
S32 mTextureStage;
- S32 mTextureCoordStage;
S32 mMatrixStage;
};
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..18a79d5264 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;
@@ -87,24 +88,32 @@ void APIENTRY gl_debug_callback(GLenum source,
{
if (gGLDebugLoggingEnabled)
{
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- LL_WARNS() << "----- GL ERROR --------" << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "----- GL WARNING -------" << LL_ENDL;
- }
- LL_WARNS() << "Type: " << std::hex << type << LL_ENDL;
- LL_WARNS() << "ID: " << std::hex << id << LL_ENDL;
- LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL;
- LL_WARNS() << "Message: " << message << LL_ENDL;
- LL_WARNS() << "-----------------------" << LL_ENDL;
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- LL_ERRS() << "Halting on GL Error" << LL_ENDL;
- }
-}
+
+ if (severity != GL_DEBUG_SEVERITY_HIGH_ARB &&
+ severity != GL_DEBUG_SEVERITY_MEDIUM_ARB &&
+ severity != GL_DEBUG_SEVERITY_LOW_ARB)
+ { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints)
+ return;
+ }
+
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ LL_WARNS() << "----- GL ERROR --------" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "----- GL WARNING -------" << LL_ENDL;
+ }
+ LL_WARNS() << "Type: " << std::hex << type << LL_ENDL;
+ LL_WARNS() << "ID: " << std::hex << id << LL_ENDL;
+ LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL;
+ LL_WARNS() << "Message: " << message << LL_ENDL;
+ LL_WARNS() << "-----------------------" << LL_ENDL;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ LL_ERRS() << "Halting on GL Error" << LL_ENDL;
+ }
+ }
}
#endif
@@ -152,7 +161,6 @@ LLMatrix4 gGLObliqueProjectionInverse;
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
-// ATI prototypes
#if LL_WINDOWS
PFNGLGETSTRINGIPROC glGetStringi = NULL;
@@ -199,21 +207,6 @@ PFNGLGETSYNCIVPROC glGetSynciv = NULL;
PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE = NULL;
PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE = NULL;
-// vertex object prototypes
-PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI = NULL;
-PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI = NULL;
-PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI = NULL;
-PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI = NULL;
-PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI = NULL;
-PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI = NULL;
-PFNGLARRAYOBJECTATIPROC glArrayObjectATI = NULL;
-PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI = NULL;
-PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI = NULL;
-PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI = NULL;
-PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI = NULL;
-PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI = NULL;
-PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI = NULL;
-
// GL_ARB_occlusion_query
PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;
PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB = NULL;
@@ -434,9 +427,6 @@ LLGLManager::LLGLManager() :
mHasMapBufferRange(FALSE),
mHasFlushBufferRange(FALSE),
mHasPBuffer(FALSE),
- mHasShaderObjects(FALSE),
- mHasVertexShader(FALSE),
- mHasFragmentShader(FALSE),
mNumTextureImageUnits(0),
mHasOcclusionQuery(FALSE),
mHasTimerQuery(FALSE),
@@ -456,14 +446,9 @@ LLGLManager::LLGLManager() :
mHasCubeMap(FALSE),
mHasDebugOutput(FALSE),
- mIsATI(FALSE),
+ mIsAMD(FALSE),
mIsNVIDIA(FALSE),
mIsIntel(FALSE),
- mIsGF2or4MX(FALSE),
- mIsGF3(FALSE),
- mIsGFFX(FALSE),
- mATIOffsetVerticalLines(FALSE),
- mATIOldDriver(FALSE),
#if LL_DARWIN
mIsMobileGF(FALSE),
#endif
@@ -559,7 +544,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;
}
@@ -622,59 +607,17 @@ bool LLGLManager::initGL()
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
+ // NOTE: AMD has been pretty good about not breaking this check, do not rename without good reason
if (mGLVendor.substr(0,4) == "ATI ")
{
- mGLVendorShort = "ATI";
+ mGLVendorShort = "AMD";
// *TODO: Fix this?
- mIsATI = TRUE;
-
-#if LL_WINDOWS && !LL_MESA_HEADLESS
- if (mDriverVersionRelease < 3842)
- {
- mATIOffsetVerticalLines = TRUE;
- }
-#endif // LL_WINDOWS
-
-#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- // count any pre OpenGL 3.0 implementation as an old driver
- if (mGLVersion < 3.f)
- {
- mATIOldDriver = TRUE;
- }
-#endif // (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
+ mIsAMD = TRUE;
}
else if (mGLVendor.find("NVIDIA ") != std::string::npos)
{
mGLVendorShort = "NVIDIA";
mIsNVIDIA = TRUE;
- if ( mGLRenderer.find("GEFORCE4 MX") != std::string::npos
- || mGLRenderer.find("GEFORCE2") != std::string::npos
- || mGLRenderer.find("GEFORCE 2") != std::string::npos
- || mGLRenderer.find("GEFORCE4 460 GO") != std::string::npos
- || mGLRenderer.find("GEFORCE4 440 GO") != std::string::npos
- || mGLRenderer.find("GEFORCE4 420 GO") != std::string::npos)
- {
- mIsGF2or4MX = TRUE;
- }
- else if (mGLRenderer.find("GEFORCE FX") != std::string::npos
- || mGLRenderer.find("QUADRO FX") != std::string::npos
- || mGLRenderer.find("NV34") != std::string::npos)
- {
- mIsGFFX = TRUE;
- }
- else if(mGLRenderer.find("GEFORCE3") != std::string::npos)
- {
- mIsGF3 = TRUE;
- }
-#if LL_DARWIN
- else if ((mGLRenderer.find("9400M") != std::string::npos)
- || (mGLRenderer.find("9600M") != std::string::npos)
- || (mGLRenderer.find("9800M") != std::string::npos))
- {
- mIsMobileGF = TRUE;
- }
-#endif
-
}
else if (mGLVendor.find("INTEL") != std::string::npos
#if LL_LINUX
@@ -775,14 +718,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)
{
@@ -833,12 +771,6 @@ bool LLGLManager::initGL()
//HACK always disable texture multisample, use FXAA instead
mHasTextureMultisample = FALSE;
#if LL_WINDOWS
- if (mIsATI)
- { //using multisample textures on ATI results in black screen for some reason
- mHasTextureMultisample = FALSE;
- }
-
-
if (mIsIntel && mGLVersion <= 3.f)
{ //never try to use framebuffer objects on older intel drivers (crashy)
mHasFramebufferObject = FALSE;
@@ -975,9 +907,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;
@@ -1003,14 +935,9 @@ void LLGLManager::asLLSD(LLSD& info)
info["has_texture_srgb_decode"] = mHasTexturesRGBDecode;
// Vendor-specific extensions
- info["is_ati"] = mIsATI;
+ info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW
info["is_nvidia"] = mIsNVIDIA;
info["is_intel"] = mIsIntel;
- info["is_gf2or4mx"] = mIsGF2or4MX;
- info["is_gf3"] = mIsGF3;
- info["is_gf_gfx"] = mIsGFFX;
- info["ati_offset_vertical_lines"] = mATIOffsetVerticalLines;
- info["ati_old_driver"] = mATIOldDriver;
// Other fields
info["has_requirements"] = mHasRequirements;
@@ -1083,9 +1010,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");
@@ -1105,8 +1029,7 @@ void LLGLManager::initExtensions()
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
- //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
- mHasDepthClamp = FALSE;
+ mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
#ifdef GL_ARB_framebuffer_object
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
@@ -1141,12 +1064,8 @@ void LLGLManager::initExtensions()
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
#if !LL_DARWIN
- mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
+ mHasPointParameters = 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 +1088,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 +1100,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 +1121,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 +1167,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;
@@ -1284,14 +1182,7 @@ void LLGLManager::initExtensions()
LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL;
mHasMipMapGeneration = FALSE;
}
-#if !LL_DARWIN
- if (mIsATI && mHasMipMapGeneration)
- {
- LL_INFOS("RenderInit") << "Disabling mip-map generation for ATI GPUs (performance opt)" << LL_ENDL;
- mHasMipMapGeneration = FALSE;
- }
-#endif
-
+
// Misc
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
@@ -1436,134 +1327,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)
@@ -1974,206 +1863,30 @@ void LLGLState::checkTextureChannels(const std::string& msg)
#endif
}
-void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
-{
- if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
- {
- return;
- }
-
- stop_glerror();
- BOOL error = FALSE;
-
- GLint active_texture;
- glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE_ARB, &active_texture);
-
- if (active_texture != GL_TEXTURE0_ARB)
- {
- LL_WARNS() << "Client active texture corrupted: " << active_texture << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "Client active texture corrupted: " << active_texture << std::endl;
- }
- error = TRUE;
- }
-
- /*glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
- if (active_texture != GL_TEXTURE0_ARB)
- {
- LL_WARNS() << "Active texture corrupted: " << active_texture << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "Active texture corrupted: " << active_texture << std::endl;
- }
- error = TRUE;
- }*/
-
- static const char* label[] =
- {
- "GL_VERTEX_ARRAY",
- "GL_NORMAL_ARRAY",
- "GL_COLOR_ARRAY",
- "GL_TEXTURE_COORD_ARRAY"
- };
-
- static GLint value[] =
- {
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- GL_COLOR_ARRAY,
- GL_TEXTURE_COORD_ARRAY
- };
-
- static const U32 mask[] =
- { //copied from llvertexbuffer.h
- 0x0001, //MAP_VERTEX,
- 0x0002, //MAP_NORMAL,
- 0x0010, //MAP_COLOR,
- 0x0004, //MAP_TEXCOORD
- };
-
-
- for (S32 j = 1; j < 4; j++)
- {
- if (glIsEnabled(value[j]))
- {
- if (!(mask[j] & data_mask))
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL still has " << label[j] << " enabled." << std::endl;
- }
- }
- }
- else
- {
- if (mask[j] & data_mask)
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL does not have " << label[j] << " enabled." << std::endl;
- }
- }
- }
- }
-
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- gGL.getTexUnit(1)->activate();
- if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
- {
- if (!(data_mask & 0x0008))
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
- }
- }
- }
- else
- {
- if (data_mask & 0x0008)
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
- }
- }
- }
-
- /*if (glIsEnabled(GL_TEXTURE_2D))
- {
- if (!(data_mask & 0x0008))
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl;
- }
- }
- }
- else
- {
- if (data_mask & 0x0008)
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
- }
- }
- }*/
-
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- gGL.getTexUnit(0)->activate();
-
- if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
- { //make sure vertex attribs are all disabled
- GLint count;
- glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
- for (GLint i = 0; i < count; i++)
- {
- GLint enabled;
- glGetVertexAttribivARB((GLuint) i, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &enabled);
- if (enabled)
- {
- error = TRUE;
- LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
- if (gDebugSession)
- {
- gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl;
- }
- }
- }
- }
-
- if (error)
- {
- if (gDebugSession)
- {
- ll_fail("LLGLState::checkClientArrays failed.");
- }
- else
- {
- LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
- }
- }
-}
-
///////////////////////////////////////////////////////////////////////
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
- if (LLGLSLShader::sNoFixedFunction)
- { //always ignore state that's deprecated post GL 3.0
- switch (state)
- {
- case GL_ALPHA_TEST:
- case GL_NORMALIZE:
- case GL_TEXTURE_GEN_R:
- case GL_TEXTURE_GEN_S:
- case GL_TEXTURE_GEN_T:
- case GL_TEXTURE_GEN_Q:
- case GL_LIGHTING:
- case GL_COLOR_MATERIAL:
- case GL_FOG:
- case GL_LINE_STIPPLE:
- case GL_POLYGON_STIPPLE:
- mState = 0;
- break;
- }
+ LL_PROFILE_ZONE_SCOPED;
+ switch (state)
+ {
+ case GL_ALPHA_TEST:
+ case GL_NORMALIZE:
+ case GL_TEXTURE_GEN_R:
+ case GL_TEXTURE_GEN_S:
+ case GL_TEXTURE_GEN_T:
+ case GL_TEXTURE_GEN_Q:
+ case GL_LIGHTING:
+ case GL_COLOR_MATERIAL:
+ case GL_FOG:
+ case GL_LINE_STIPPLE:
+ case GL_POLYGON_STIPPLE:
+ mState = 0;
+ break;
}
+
stop_glerror();
if (mState)
{
@@ -2212,6 +1925,7 @@ void LLGLState::setEnabled(S32 enabled)
LLGLState::~LLGLState()
{
+ LL_PROFILE_ZONE_SCOPED;
stop_glerror();
if (mState)
{
@@ -2398,7 +2112,8 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
mModelview = modelview;
mProjection = projection;
- setPlane(p[0], p[1], p[2], p[3]);
+ //flip incoming LLPlane to get consistent behavior compared to frustum culling
+ setPlane(-p[0], -p[1], -p[2], -p[3]);
}
}
@@ -2469,6 +2184,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)
{
@@ -2723,22 +2439,10 @@ LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
, mCullFace(GL_CULL_FACE)
, mSquashClip()
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_LIGHTING);
- glDisable(GL_FOG);
- glDisable(GL_CLIP_PLANE0);
- }
}
LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox()
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glEnable(GL_LIGHTING);
- glEnable(GL_FOG);
- glEnable(GL_CLIP_PLANE0);
- }
}
LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write)
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index a07e2d9bb0..ec97eb0faa 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;
@@ -122,14 +119,9 @@ public:
BOOL mHasTexturesRGBDecode;
// Vendor-specific extensions
- BOOL mIsATI;
+ BOOL mIsAMD;
BOOL mIsNVIDIA;
BOOL mIsIntel;
- BOOL mIsGF2or4MX;
- BOOL mIsGF3;
- BOOL mIsGFFX;
- BOOL mATIOffsetVerticalLines;
- BOOL mATIOldDriver;
#if LL_DARWIN
// Needed to distinguish problem cards on older Macs that break with Materials
@@ -269,7 +261,6 @@ public:
static void dumpStates();
static void checkStates(const std::string& msg = "");
static void checkTextureChannels(const std::string& msg = "");
- static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);
protected:
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
@@ -488,6 +479,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..220e88386a 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -50,7 +50,6 @@ using std::string;
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
-bool LLGLSLShader::sNoFixedFunction = false;
bool LLGLSLShader::sProfileEnabled = false;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
U64 LLGLSLShader::sTotalTimeElapsed = 0;
@@ -208,6 +207,7 @@ void LLGLSLShader::dumpStats()
//static
void LLGLSLShader::startProfile()
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
@@ -218,6 +218,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 +385,8 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
U32 varying_count,
const char** varyings)
{
+ LL_PROFILE_ZONE_SCOPED;
+
unloadInternal();
sInstances.insert(this);
@@ -588,6 +591,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 +654,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 +777,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 +791,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 +936,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 +950,65 @@ 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()
+void LLGLSLShader::bind(bool rigged)
{
- gGL.flush();
- if (gGLManager.mHasShaderObjects)
+ if (rigged)
{
- 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();
+ llassert(mRiggedVariant);
+ mRiggedVariant->bind();
+ }
+ else
+ {
+ bind();
}
}
+void LLGLSLShader::unbind()
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ gGL.flush();
+ 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 +1017,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 +1029,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 +1038,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 +1048,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 +1060,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 +1068,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 +1087,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 +1116,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 +1127,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 +1139,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 +1150,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 +1172,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 +1195,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 +1218,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 +1241,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 +1264,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 +1287,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 +1310,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 +1333,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 +1381,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 +1417,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 +1443,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 +1461,8 @@ GLint LLGLSLShader::getUniformLocation(U32 index)
GLint LLGLSLShader::getAttribLocation(U32 attrib)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (attrib < mAttribute.size())
{
return mAttribute[attrib];
@@ -1432,7 +1479,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 +1495,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 +1512,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 +1528,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 +1545,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 +1561,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 +1577,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 +1593,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 +1610,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 +1654,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..85e83dbcb9 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;
@@ -84,7 +148,6 @@ public:
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
- static bool sNoFixedFunction;
static void initProfile();
static void finishProfile(bool emit_report = true);
@@ -166,6 +229,8 @@ public:
BOOL link(BOOL suppress_errors = FALSE);
void bind();
+ //helper to conditionally bind mRiggedVariant instead of this
+ void bind(bool rigged);
void unbind();
// Unbinds any previously bound shader by explicitly binding no shader.
@@ -190,18 +255,21 @@ 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;
std::string mName;
- boost::unordered_map<std::string, std::string> mDefines;
+ typedef std::unordered_map<std::string, std::string> defines_map_t;
+ defines_map_t mDefines;
//statistcis for profiling shader performance
U32 mTimerQuery;
@@ -219,6 +287,9 @@ public:
std::vector<U32> mTextureMagFilter;
std::vector<U32> mTextureMinFilter;
+ // this pointer should be set to whichever shader represents this shader's rigged variant
+ LLGLSLShader* mRiggedVariant = nullptr;
+
private:
void unloadInternal();
};
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..9931ce7d3e 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -39,6 +39,11 @@
#include "llgl.h"
#include "llglslshader.h"
#include "llrender.h"
+#include "llwindow.h"
+
+#if !LL_IMAGEGL_THREAD_CHECK
+#define checkActiveThread()
+#endif
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
@@ -61,9 +66,11 @@ F32 LLImageGL::sLastFrameTime = 0.f;
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
bool LLImageGL::sCompressTextures = false;
-
std::set<LLImageGL*> LLImageGL::sImageList;
+
+bool LLImageGLThread::sEnabled = false;
+
//****************************************************************************************************
//The below for texture auditing use only
//****************************************************************************************************
@@ -170,15 +177,24 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
+
//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 */, bool multi_threaded /* = false */)
{
+ LL_PROFILE_ZONE_SCOPED;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+
+ if (multi_threaded)
+ {
+ LLImageGLThread::createInstance(window);
+ }
}
//static
void LLImageGL::cleanupClass()
-{
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::deleteSingleton();
}
//static
@@ -258,11 +274,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 +310,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 +385,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 +394,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 +404,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 +422,6 @@ LLImageGL::LLImageGL(
LLGLenum formatPrimary,
LLGLenum formatType,
LLTexUnit::eTextureAddressMode addressMode)
- : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE)
{
init(false);
mTexName = texName;
@@ -438,6 +447,10 @@ LLImageGL::~LLImageGL()
void LLImageGL::init(BOOL usemipmaps)
{
+#if LL_IMAGEGL_THREAD_CHECK
+ mActiveThread = LLThread::currentID();
+#endif
+
// keep these members in the same order as declared in llimagehl.h
// so that it is obvious by visual inspection if we forgot to
// init a field.
@@ -493,6 +506,9 @@ void LLImageGL::init(BOOL usemipmaps)
#endif
mCategory = -1;
+
+ // Sometimes we have to post work for the main thread.
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
}
void LLImageGL::cleanup()
@@ -540,12 +556,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
return false;
}
- if (mTexName)
- {
-// LL_WARNS() << "Setting Size of LLImageGL with existing mTexName = " << mTexName << LL_ENDL;
- destroyGLTexture();
- }
-
// pickmask validity depends on old image size, delete it
freePickMask();
@@ -656,6 +666,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 +674,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 +693,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 +707,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 +737,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 +767,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 +786,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 +876,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 +1071,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 +1168,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 +1189,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 +1205,128 @@ 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;
+ checkActiveThread();
+
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
@@ -1333,6 +1341,7 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ mTexName = 0;
}
@@ -1347,23 +1356,24 @@ 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;
+ checkActiveThread();
+
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 +1393,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 +1462,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
destroyGLTexture();
mCurrentDiscardLevel = discard_level;
mLastBindTime = sLastFrameTime;
+ mGLTextureCreated = false;
return TRUE ;
}
@@ -1459,107 +1471,120 @@ 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;
+ checkActiveThread();
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
- discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
+ llassert(data_in);
+ stop_glerror();
- 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;
-#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;
- }
-#endif
- }
+ 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;
+ }
- 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 (! on_main_thread())
+ {
+ {
+ 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();
+ LL::WorkQueue::postMaybe(
+ mMainQueue,
+ [=]()
+ {
+ 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;
+ checkActiveThread();
+ return TRUE;
}
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
@@ -1673,28 +1698,19 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
return TRUE ;
}
-void LLImageGL::deleteDeadTextures()
-{
- bool reset = false;
-
- if (reset)
- {
- gGL.getTexUnit(0)->activate();
- }
-}
-
void LLImageGL::destroyGLTexture()
{
+ checkActiveThread();
+
if (mTexName != 0)
{
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 ;
@@ -1704,6 +1720,7 @@ void LLImageGL::destroyGLTexture()
//force to invalidate the gl texture, most likely a sculpty texture
void LLImageGL::forceToInvalidateGLTexture()
{
+ checkActiveThread();
if (mTexName != 0)
{
destroyGLTexture();
@@ -2043,7 +2060,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 +2074,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;
@@ -2182,6 +2197,12 @@ void LLImageGL::resetCurTexSizebar()
sCurTexPickSize = -1 ;
}
//----------------------------------------------------------------------------
+#if LL_IMAGEGL_THREAD_CHECK
+void LLImageGL::checkActiveThread()
+{
+ llassert(mActiveThread == LLThread::currentID());
+}
+#endif
//----------------------------------------------------------------------------
@@ -2235,3 +2256,30 @@ 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)
+ // We want exactly one thread, but a very large capacity: we never want
+ // anyone, especially inner-loop render code, to have to block on post()
+ // because we're full.
+ : ThreadPool("LLImageGL", 1, 1024*1024)
+ , mWindow(window)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ sEnabled = true;
+ mFinished = false;
+
+ mContext = mWindow->createSharedContext();
+ ThreadPool::start();
+}
+
+void LLImageGLThread::run()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ // We must perform setup on this thread before actually servicing our
+ // WorkQueue, likewise cleanup afterwards.
+ mWindow->makeContextCurrent(mContext);
+ gGL.init();
+ ThreadPool::run();
+ gGL.shutdown();
+ mWindow->destroySharedContext(mContext);
+}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 61ddc8d59b..d6f4b13a51 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -35,21 +35,26 @@
#include "llrefcount.h"
#include "v2math.h"
#include "llunits.h"
-
+#include "llthreadsafequeue.h"
#include "llrender.h"
-class LLTextureAtlas ;
+#include "threadpool.h"
+#include "workqueue.h"
+
+#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL
+
+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 deleteDeadTextures();
+ static void deleteTextures(S32 numTextures, const U32 *textures);
// Size calculation
static S32 dataFormatBits(S32 dataformat);
@@ -102,13 +107,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);
@@ -184,6 +189,12 @@ public:
BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
void postAddToAtlas() ;
+#if LL_IMAGEGL_THREAD_CHECK
+ // thread debugging
+ std::thread::id mActiveThread;
+ void checkActiveThread();
+#endif
+
public:
// Various GL/Rendering options
S32Bytes mTextureMemory;
@@ -194,6 +205,7 @@ private:
void freePickMask();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
+ LL::WorkQueue::weak_t mMainQueue;
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
U16 mPickMaskWidth;
U16 mPickMaskHeight;
@@ -208,8 +220,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 +278,7 @@ 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, bool multi_threaded = false);
static void cleanupClass() ;
private:
@@ -301,4 +314,28 @@ public:
};
+class LLImageGLThread : public LLSimpleton<LLImageGLThread>, LL::ThreadPool
+{
+public:
+ // follows gSavedSettings "RenderGLMultiThreaded"
+ static bool sEnabled;
+
+ LLImageGLThread(LLWindow* window);
+
+ // post a function to be executed on the LLImageGL background thread
+ template <typename CALLABLE>
+ bool post(CALLABLE&& func)
+ {
+ return getQueue().postIfOpen(std::forward<CALLABLE>(func));
+ }
+
+ void run() override;
+
+private:
+ LLWindow* mWindow;
+ void* mContext = nullptr;
+ LLAtomicBool mFinished;
+};
+
+
#endif // LL_LLIMAGEGL_H
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 03b6aac20c..8b4f250894 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];
@@ -71,18 +71,6 @@ static const GLint sGLAddressMode[] =
GL_CLAMP_TO_EDGE
};
-static const GLenum sGLCompareFunc[] =
-{
- GL_NEVER,
- GL_ALWAYS,
- GL_LESS,
- GL_LEQUAL,
- GL_EQUAL,
- GL_NOTEQUAL,
- GL_GEQUAL,
- GL_GREATER
-};
-
const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
static const GLenum sGLBlendFactor[] =
@@ -102,10 +90,7 @@ static const GLenum sGLBlendFactor[] =
};
LLTexUnit::LLTexUnit(S32 index)
- : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
- mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
- mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
- mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
+ : mCurrTexType(TT_NONE),
mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR),
mHasMipMaps(false),
mIndex(index)
@@ -128,42 +113,15 @@ void LLTexUnit::refreshState(void)
glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
- //
- // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
- // http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
- //
- bool enableDisable = !LLGLSLShader::sNoFixedFunction &&
- (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;
-
if (mCurrTexType != TT_NONE)
{
- if (enableDisable)
- {
- glEnable(sGLTextureType[mCurrTexType]);
- }
-
glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
}
else
{
- if (enableDisable)
- {
- glDisable(GL_TEXTURE_2D);
- }
-
glBindTexture(GL_TEXTURE_2D, 0);
}
- if (mCurrBlendType != TB_COMBINE)
- {
- setTextureBlendType(mCurrBlendType);
- }
- else
- {
- setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
- setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
- }
-
setTextureColorSpace(mTexColorSpace);
}
@@ -196,14 +154,6 @@ void LLTexUnit::enable(eTextureType type)
mCurrTexType = type;
gGL.flush();
- if (!LLGLSLShader::sNoFixedFunction &&
- type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
- mIndex < gGLManager.mNumTextureUnits)
- {
- stop_glerror();
- glEnable(sGLTextureType[type]);
- stop_glerror();
- }
}
}
@@ -216,21 +166,34 @@ void LLTexUnit::disable(void)
activate();
unbind(mCurrTexType);
gGL.flush();
- if (!LLGLSLShader::sNoFixedFunction &&
- mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
- mIndex < gGLManager.mNumTextureUnits)
- {
- glDisable(sGLTextureType[mCurrTexType]);
- }
-
setTextureColorSpace(TCS_LINEAR);
mCurrTexType = TT_NONE;
}
}
+void LLTexUnit::bindFast(LLTexture* texture)
+{
+ LLImageGL* gl_tex = texture->getGLTexture();
+
+ glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ gGL.mCurrTextureUnitIndex = mIndex;
+ mCurrTexture = gl_tex->getTexName();
+ if (!mCurrTexture)
+ {
+ LL_PROFILE_ZONE_NAMED("MISSING TEXTURE");
+ //if deleted, will re-generate it immediately
+ texture->forceImmediateUpdate();
+ gl_tex->forceUpdateBindStats();
+ texture->bindDefaultImage(mIndex);
+ }
+ 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 +257,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 +280,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 +288,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);
@@ -447,7 +412,7 @@ void LLTexUnit::unbind(eTextureType type)
// 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 (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
+ if (type == LLTexUnit::TT_TEXTURE)
{
glBindTexture(sGLTextureType[type], sWhiteTexture);
}
@@ -459,6 +424,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;
@@ -537,55 +524,6 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
}
}
-void LLTexUnit::setTextureBlendType(eTextureBlendType type)
-{
- if (LLGLSLShader::sNoFixedFunction)
- { //texture blend type means nothing when using shaders
- return;
- }
-
- if (mIndex < 0) return;
-
- // Do nothing if it's already correctly set.
- if (mCurrBlendType == type && !gGL.mDirty)
- {
- return;
- }
-
- gGL.flush();
-
- activate();
- mCurrBlendType = type;
- S32 scale_amount = 1;
- switch (type)
- {
- case TB_REPLACE:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- break;
- case TB_ADD:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
- break;
- case TB_MULT:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- break;
- case TB_MULT_X2:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- scale_amount = 2;
- break;
- case TB_ALPHA_BLEND:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- break;
- case TB_COMBINE:
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- break;
- default:
- LL_ERRS() << "Unknown Texture Blend Type: " << type << LL_ENDL;
- break;
- }
- setColorScale(scale_amount);
- setAlphaScale(1);
-}
-
GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
{
switch(src)
@@ -662,159 +600,6 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
}
}
-void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
-{
- if (LLGLSLShader::sNoFixedFunction)
- { //register combiners do nothing when not using fixed function
- return;
- }
-
- if (mIndex < 0) return;
-
- activate();
- if (mCurrBlendType != TB_COMBINE || gGL.mDirty)
- {
- mCurrBlendType = TB_COMBINE;
- gGL.flush();
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- }
-
- // We want an early out, because this function does a LOT of stuff.
- if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
- || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
- {
- return;
- }
-
- gGL.flush();
-
- // Get the gl source enums according to the eTextureBlendSrc sources passed in
- GLint source1 = getTextureSource(src1);
- GLint source2 = getTextureSource(src2);
- // Get the gl operand enums according to the eTextureBlendSrc sources passed in
- GLint operand1 = getTextureSourceType(src1, isAlpha);
- GLint operand2 = getTextureSourceType(src2, isAlpha);
- // Default the scale amount to 1
- S32 scale_amount = 1;
- GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum;
-
- if (isAlpha)
- {
- // Set enums to ALPHA ones
- comb_enum = GL_COMBINE_ALPHA_ARB;
- src0_enum = GL_SOURCE0_ALPHA_ARB;
- src1_enum = GL_SOURCE1_ALPHA_ARB;
- src2_enum = GL_SOURCE2_ALPHA_ARB;
- operand0_enum = GL_OPERAND0_ALPHA_ARB;
- operand1_enum = GL_OPERAND1_ALPHA_ARB;
- operand2_enum = GL_OPERAND2_ALPHA_ARB;
-
- // cache current combiner
- mCurrAlphaOp = op;
- mCurrAlphaSrc1 = src1;
- mCurrAlphaSrc2 = src2;
- }
- else
- {
- // Set enums to RGB ones
- comb_enum = GL_COMBINE_RGB_ARB;
- src0_enum = GL_SOURCE0_RGB_ARB;
- src1_enum = GL_SOURCE1_RGB_ARB;
- src2_enum = GL_SOURCE2_RGB_ARB;
- operand0_enum = GL_OPERAND0_RGB_ARB;
- operand1_enum = GL_OPERAND1_RGB_ARB;
- operand2_enum = GL_OPERAND2_RGB_ARB;
-
- // cache current combiner
- mCurrColorOp = op;
- mCurrColorSrc1 = src1;
- mCurrColorSrc2 = src2;
- }
-
- switch(op)
- {
- case TBO_REPLACE:
- // Slightly special syntax (no second sources), just set all and return.
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
- glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
- (isAlpha) ? setAlphaScale(1) : setColorScale(1);
- return;
-
- case TBO_MULT:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
- break;
-
- case TBO_MULT_X2:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
- scale_amount = 2;
- break;
-
- case TBO_MULT_X4:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
- scale_amount = 4;
- break;
-
- case TBO_ADD:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD);
- break;
-
- case TBO_ADD_SIGNED:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB);
- break;
-
- case TBO_SUBTRACT:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB);
- break;
-
- case TBO_LERP_VERT_ALPHA:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
- glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
- break;
-
- case TBO_LERP_TEX_ALPHA:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
- break;
-
- case TBO_LERP_PREV_ALPHA:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB);
- glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
- break;
-
- case TBO_LERP_CONST_ALPHA:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB);
- glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
- break;
-
- case TBO_LERP_VERT_COLOR:
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
- glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
- glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR);
- break;
-
- default:
- LL_WARNS() << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << LL_ENDL;
- // Slightly special syntax (no second sources), just set all and return.
- glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
- glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
- glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
- (isAlpha) ? setAlphaScale(1) : setColorScale(1);
- return;
- }
-
- // Set sources, operands, and scale accordingly
- glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
- glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
- glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2);
- glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2);
- (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount);
-}
-
void LLTexUnit::setColorScale(S32 scale)
{
if (mCurrColorScale != scale || gGL.mDirty)
@@ -903,26 +688,12 @@ LLLightState::LLLightState(S32 index)
void LLLightState::enable()
{
- if (!mEnabled)
- {
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glEnable(GL_LIGHT0+mIndex);
- }
- mEnabled = true;
- }
+ mEnabled = true;
}
void LLLightState::disable()
{
- if (mEnabled)
- {
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_LIGHT0+mIndex);
- }
- mEnabled = false;
- }
+ mEnabled = false;
}
void LLLightState::setDiffuse(const LLColor4& diffuse)
@@ -931,10 +702,6 @@ void LLLightState::setDiffuse(const LLColor4& diffuse)
{
++gGL.mLightHash;
mDiffuse = diffuse;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
- }
}
}
@@ -962,10 +729,6 @@ void LLLightState::setAmbient(const LLColor4& ambient)
{
++gGL.mLightHash;
mAmbient = ambient;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
- }
}
}
@@ -975,10 +738,6 @@ void LLLightState::setSpecular(const LLColor4& specular)
{
++gGL.mLightHash;
mSpecular = specular;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
- }
}
}
@@ -987,20 +746,11 @@ void LLLightState::setPosition(const LLVector4& position)
//always set position because modelview matrix may have changed
++gGL.mLightHash;
mPosition = position;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
- }
- else
- { //transform position by current modelview matrix
- glh::vec4f pos(position.mV);
-
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_vec(pos);
-
- mPosition.set(pos.v);
- }
-
+ //transform position by current modelview matrix
+ glh::vec4f pos(position.mV);
+ const glh::matrix4f& mat = gGL.getModelviewMatrix();
+ mat.mult_matrix_vec(pos);
+ mPosition.set(pos.v);
}
void LLLightState::setConstantAttenuation(const F32& atten)
@@ -1009,10 +759,6 @@ void LLLightState::setConstantAttenuation(const F32& atten)
{
mConstantAtten = atten;
++gGL.mLightHash;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
- }
}
}
@@ -1022,10 +768,6 @@ void LLLightState::setLinearAttenuation(const F32& atten)
{
++gGL.mLightHash;
mLinearAtten = atten;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
- }
}
}
@@ -1035,10 +777,6 @@ void LLLightState::setQuadraticAttenuation(const F32& atten)
{
++gGL.mLightHash;
mQuadraticAtten = atten;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
- }
}
}
@@ -1048,10 +786,6 @@ void LLLightState::setSpotExponent(const F32& exponent)
{
++gGL.mLightHash;
mSpotExponent = exponent;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
- }
}
}
@@ -1061,10 +795,6 @@ void LLLightState::setSpotCutoff(const F32& cutoff)
{
++gGL.mLightHash;
mSpotCutoff = cutoff;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
- }
}
}
@@ -1073,19 +803,12 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
//always set direction because modelview matrix may have changed
++gGL.mLightHash;
mSpotDirection = direction;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
- }
- else
- { //transform direction by current modelview matrix
- glh::vec3f dir(direction.mV);
-
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_dir(dir);
+ //transform direction by current modelview matrix
+ glh::vec3f dir(direction.mV);
+ const glh::matrix4f& mat = gGL.getModelviewMatrix();
+ mat.mult_matrix_dir(dir);
- mSpotDirection.set(dir.v);
- }
+ mSpotDirection.set(dir.v);
}
LLRender::LLRender()
@@ -1113,8 +836,6 @@ LLRender::LLRender()
mCurrColorMask[i] = true;
}
- mCurrAlphaFunc = CF_DEFAULT;
- mCurrAlphaFuncVal = 0.01f;
mCurrBlendColorSFactor = BF_UNDEF;
mCurrBlendAlphaSFactor = BF_UNDEF;
mCurrBlendColorDFactor = BF_UNDEF;
@@ -1192,7 +913,7 @@ void LLRender::refreshState(void)
setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
- setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
+ flush();
mDirty = false;
}
@@ -1243,9 +964,7 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
- stop_glerror();
-
- static const U32 name[] =
+ static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
LLShaderMgr::PROJECTION_MATRIX,
@@ -1382,41 +1101,6 @@ void LLRender::syncMatrices()
syncLightState();
}
}
- else if (!LLGLSLShader::sNoFixedFunction)
- {
- static const GLenum mode[] =
- {
- GL_MODELVIEW,
- GL_PROJECTION,
- GL_TEXTURE,
- GL_TEXTURE,
- GL_TEXTURE,
- GL_TEXTURE,
- };
-
- for (U32 i = 0; i < MM_TEXTURE0; ++i)
- {
- if (mMatHash[i] != mCurMatHash[i])
- {
- glMatrixMode(mode[i]);
- glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
- mCurMatHash[i] = mMatHash[i];
- }
- }
-
- for (U32 i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
- {
- if (mMatHash[i] != mCurMatHash[i])
- {
- gGL.getTexUnit(i-MM_TEXTURE0)->activate();
- glMatrixMode(mode[i]);
- glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
- mCurMatHash[i] = mMatHash[i];
- }
- }
- }
-
- stop_glerror();
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -1732,55 +1416,6 @@ void LLRender::setSceneBlendType(eBlendType type)
}
}
-void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
-{
- flush();
-
- if (LLGLSLShader::sNoFixedFunction)
- { //glAlphaFunc is deprecated in OpenGL 3.3
- return;
- }
-
- if (mCurrAlphaFunc != func ||
- mCurrAlphaFuncVal != value)
- {
- mCurrAlphaFunc = func;
- mCurrAlphaFuncVal = value;
- if (func == CF_DEFAULT)
- {
- glAlphaFunc(GL_GREATER, 0.01f);
- }
- else
- {
- glAlphaFunc(sGLCompareFunc[func], value);
- }
- }
-
- if (gDebugGL)
- { //make sure cached state is correct
- GLint cur_func = 0;
- glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func);
-
- if (func == CF_DEFAULT)
- {
- func = CF_GREATER;
- }
-
- if (cur_func != sGLCompareFunc[func])
- {
- LL_ERRS() << "Alpha test function corrupted!" << LL_ENDL;
- }
-
- F32 ref = 0.f;
- glGetFloatv(GL_ALPHA_TEST_REF, &ref);
-
- if (ref != value)
- {
- LL_ERRS() << "Alpha test value corrupted!" << LL_ENDL;
- }
- }
-}
-
void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
{
llassert(sfactor < BF_UNDEF);
@@ -1848,14 +1483,11 @@ LLLightState* LLRender::getLight(U32 index)
void LLRender::setAmbientLightColor(const LLColor4& color)
{
+ LL_PROFILE_ZONE_SCOPED
if (color != mAmbientLightColor)
{
++mLightHash;
mAmbientLightColor = color;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.mV);
- }
}
}
@@ -1926,6 +1558,7 @@ void LLRender::flush()
{
if (mCount > 0)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!mUIOffset.empty())
{
sUICalls++;
@@ -2307,7 +1940,7 @@ void LLRender::color3fv(const GLfloat* c)
void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
@@ -2322,7 +1955,7 @@ void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
void LLRender::diffuseColor3fv(const F32* c)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
@@ -2337,7 +1970,7 @@ void LLRender::diffuseColor3fv(const F32* c)
void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
@@ -2352,7 +1985,7 @@ void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
void LLRender::diffuseColor4fv(const F32* c)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
@@ -2367,7 +2000,7 @@ void LLRender::diffuseColor4fv(const F32* c)
void LLRender::diffuseColor4ubv(const U8* c)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
@@ -2382,7 +2015,7 @@ void LLRender::diffuseColor4ubv(const U8* c)
void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+ llassert(shader != NULL);
if (shader)
{
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index af8568f8a3..e2489876e4 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -105,10 +105,7 @@ public:
TBO_LERP_VERT_ALPHA, // Interpolate based on Vertex Alpha (VA): ( Source1 * VA + Source2 * (1-VA) )
TBO_LERP_TEX_ALPHA, // Interpolate based on Texture Alpha (TA): ( Source1 * TA + Source2 * (1-TA) )
TBO_LERP_PREV_ALPHA, // Interpolate based on Previous Alpha (PA): ( Source1 * PA + Source2 * (1-PA) )
- TBO_LERP_CONST_ALPHA, // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) )
- TBO_LERP_VERT_COLOR // Interpolate based on Vertex Col (VC): ( Source1 * VC + Source2 * (1-VC) )
- // *Note* TBO_LERP_VERTEX_COLOR only works with setTextureColorBlend(),
- // and falls back to TBO_LERP_VERTEX_ALPHA for setTextureAlphaBlend().
+ TBO_LERP_CONST_ALPHA // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) )
} eTextureBlendOp;
typedef enum
@@ -158,9 +155,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 +185,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.
@@ -187,15 +198,6 @@ public:
// make sure you want to permanently change the filtering for the bound texture.
void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option);
- void setTextureBlendType(eTextureBlendType type);
-
- inline void setTextureColorBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_COLOR)
- { setTextureCombiner(op, src1, src2, false); }
-
- // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead.
- inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA)
- { setTextureCombiner(op, src1, src2, true); }
-
static U32 getInternalType(eTextureType type);
U32 getCurrTexture(void) { return mCurrTexture; }
@@ -212,13 +214,6 @@ protected:
const S32 mIndex;
U32 mCurrTexture;
eTextureType mCurrTexType;
- eTextureBlendType mCurrBlendType;
- eTextureBlendOp mCurrColorOp;
- eTextureBlendSrc mCurrColorSrc1;
- eTextureBlendSrc mCurrColorSrc2;
- eTextureBlendOp mCurrAlphaOp;
- eTextureBlendSrc mCurrAlphaSrc1;
- eTextureBlendSrc mCurrAlphaSrc2;
eTextureColorSpace mTexColorSpace;
S32 mCurrColorScale;
S32 mCurrAlphaScale;
@@ -229,7 +224,6 @@ protected:
void setAlphaScale(S32 scale);
GLint getTextureSource(eTextureBlendSrc src);
GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
- void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false);
};
class LLLightState
@@ -430,8 +424,6 @@ public:
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
void setSceneBlendType(eBlendType type);
- void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f);
-
// applies blend func to both color and alpha
void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
// applies separate blend functions to color and alpha
@@ -482,8 +474,6 @@ private:
U32 mMode;
U32 mCurrTextureUnitIndex;
bool mCurrColorMask[4];
- eCompareFunc mCurrAlphaFunc;
- F32 mCurrAlphaFuncVal;
LLPointer<LLVertexBuffer> mBuffer;
LLStrider<LLVector3> mVerticesp;
@@ -511,7 +501,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..ad0c6262a4 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -132,40 +132,15 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
}
else
{
- if( gGLManager.mATIOffsetVerticalLines )
- {
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- gGL.begin( LLRender::LINES );
-
- // Verticals
- gGL.vertex2i(left + 1, top);
- gGL.vertex2i(left + 1, bottom);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
-
- // Horizontals
- top--;
- right--;
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
-
- gGL.vertex2i(left, top);
- gGL.vertex2i(right, top);
- gGL.end();
- }
- else
- {
- top--;
- right--;
- gGL.begin( LLRender::LINE_STRIP );
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
- gGL.vertex2i(left, top);
- gGL.end();
- }
+ top--;
+ right--;
+ gGL.begin( LLRender::LINE_STRIP );
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(left, top);
+ gGL.end();
}
stop_glerror();
}
@@ -250,15 +225,6 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
{
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
- {
- x1++;
- x2++;
- y1++;
- y2++;
- }
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin(LLRender::LINES);
@@ -269,15 +235,6 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
{
- // Work around bug in ATI driver: vertical lines are offset by (-1,-1)
- if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
- {
- x1++;
- x2++;
- y1++;
- y2++;
- }
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( color.mV );
@@ -395,15 +352,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
if (solid_color)
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSolidColorProgram.bind();
- }
- else
- {
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
- }
+ gSolidColorProgram.bind();
}
if (center_rect.mLeft == 0.f
@@ -650,14 +599,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
if (solid_color)
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
- else
- {
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
+ gUIProgram.bind();
}
}
@@ -774,10 +716,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
{
- phase = fmod(phase, 1.f);
-
- S32 shift = S32(phase * 4.f) % 4;
-
// Stippled line
LLGLEnable stipple(GL_LINE_STIPPLE);
@@ -786,11 +724,6 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
gGL.flush();
glLineWidth(2.5f);
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLineStipple(2, 0x3333 << shift);
- }
-
gGL.begin(LLRender::LINES);
{
gGL.vertex3fv( start.mV );
@@ -930,52 +863,16 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor
// Draw gray and white checkerboard with black border
void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- // Initialize the first time this is called.
- const S32 PIXELS = 32;
- static GLubyte checkerboard[PIXELS * PIXELS];
- static BOOL first = TRUE;
- if( first )
- {
- for( S32 i = 0; i < PIXELS; i++ )
- {
- for( S32 j = 0; j < PIXELS; j++ )
- {
- checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
- }
- }
- first = FALSE;
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // ...white squares
- gGL.color4f( 1.f, 1.f, 1.f, alpha );
- gl_rect_2d(rect);
-
- // ...gray squares
- gGL.color4f( .7f, .7f, .7f, alpha );
- gGL.flush();
+ //polygon stipple is deprecated, use "Checker" texture
+ LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker");
+ gGL.getTexUnit(0)->bind(img->getImage());
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- glPolygonStipple( checkerboard );
+ LLColor4 color(1.f, 1.f, 1.f, alpha);
+ LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
- LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
- gl_rect_2d(rect);
- }
- else
- { //polygon stipple is deprecated, use "Checker" texture
- LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker");
- gGL.getTexUnit(0)->bind(img->getImage());
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
- LLColor4 color(1.f, 1.f, 1.f, alpha);
- LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
-
- gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
- img->getImage(), color, uv_rect);
- }
+ gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), img->getImage(), color, uv_rect);
gGL.flush();
}
@@ -1083,8 +980,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 +989,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 +1148,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 +1335,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/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index e8c6295930..c100c182dd 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -165,6 +165,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasObjectSkinning)
{
+ shader->mRiggedVariant = shader;
if (!shader->attachVertexObject("avatar/objectSkinV.glsl"))
{
return FALSE;
@@ -599,7 +600,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string&
}
}
-GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
+GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
// endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl)
@@ -774,14 +775,14 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (defines)
{
- for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
+ for (std::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
extra_code_text[extra_code_count++] = (GLcharARB *) strdup(define.c_str());
}
}
- if( gGLManager.mIsATI )
+ if( gGLManager.mIsAMD )
{
extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" );
}
@@ -1053,43 +1054,6 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL;
}
-#if LL_DARWIN
-
- // For some reason this absolutely kills the frame rate when VBO's are enabled
- if (0)
- {
- // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
- // per Apple's suggestion
- LLGLSLShader::sNoFixedFunction = false;
-
- glUseProgramObjectARB(obj);
-
- gGL.begin(LLRender::TRIANGLES);
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.vertex3f(0.0f, 0.0f, 0.0f);
- gGL.end();
- gGL.flush();
-
- glUseProgramObjectARB(0);
-
- LLGLSLShader::sNoFixedFunction = true;
-
- // Query whether the shader can or cannot run in hardware
- // http://developer.apple.com/qa/qa2007/qa1502.html
- GLint vertexGPUProcessing, fragmentGPUProcessing;
- CGLContextObj ctx = CGLGetCurrentContext();
- CGLGetParameter(ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
- CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
- if (!fragmentGPUProcessing || !vertexGPUProcessing)
- {
- LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
- success = GL_FALSE;
- suppress_errors = FALSE;
- }
- }
-
-#else
std::string log = get_object_log(obj);
LLStringUtil::toLower(log);
if (log.find("software") != std::string::npos)
@@ -1098,7 +1062,6 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
success = GL_FALSE;
suppress_errors = FALSE;
}
-#endif
return success;
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 3908efd4ec..67c0d6ab10 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -264,7 +264,7 @@ public:
void dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
- GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
+ GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
// Implemented in the application to actually point to the shader directory.
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
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..9926447ef8 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();
@@ -150,11 +157,12 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
-volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
+U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
+ LL_PROFILE_ZONE_SCOPED
llassert(vbo_block_size(size) == size);
- volatile U8* ret = NULL;
+ U8* ret = NULL;
U32 i = vbo_block_index(size);
@@ -248,7 +256,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
return ret;
}
-void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
+void LLVBOPool::release(U32 name, U8* buffer, U32 size)
{
llassert(vbo_block_size(size) == size);
@@ -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();
@@ -430,135 +441,26 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
data_mask = data_mask & ~MAP_TEXTURE_INDEX;
}
- if (LLGLSLShader::sNoFixedFunction)
+ for (U32 i = 0; i < TYPE_MAX; ++i)
{
- for (U32 i = 0; i < TYPE_MAX; ++i)
- {
- S32 loc = i;
+ S32 loc = i;
- U32 mask = 1 << i;
-
- if (sLastMask & (1 << i))
- { //was enabled
- if (!(data_mask & mask))
- { //needs to be disabled
- glDisableVertexAttribArrayARB(loc);
- }
- }
- else
- { //was disabled
- if (data_mask & mask)
- { //needs to be enabled
- glEnableVertexAttribArrayARB(loc);
- }
- }
- }
- }
- else
- {
-
- static const GLenum array[] =
- {
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- GL_TEXTURE_COORD_ARRAY,
- GL_COLOR_ARRAY,
- };
-
- static const GLenum mask[] =
- {
- MAP_VERTEX,
- MAP_NORMAL,
- MAP_TEXCOORD0,
- MAP_COLOR
- };
-
-
-
- for (U32 i = 0; i < 4; ++i)
- {
- if (sLastMask & mask[i])
- { //was enabled
- if (!(data_mask & mask[i]))
- { //needs to be disabled
- glDisableClientState(array[i]);
- }
- else if (gDebugGL)
- { //needs to be enabled, make sure it was (DEBUG)
- if (!glIsEnabled(array[i]))
- {
- if (gDebugSession)
- {
- gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
- }
- else
- {
- LL_ERRS() << "Bad client state! " << array[i] << " disabled." << LL_ENDL;
- }
- }
- }
- }
- else
- { //was disabled
- if (data_mask & mask[i])
- { //needs to be enabled
- glEnableClientState(array[i]);
- }
- else if (gDebugGL && glIsEnabled(array[i]))
- { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
- if (gDebugSession)
- {
- gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
- }
- else
- {
- LL_ERRS() << "Bad client state! " << array[i] << " enabled." << LL_ENDL;
- }
- }
- }
- }
-
- static const U32 map_tc[] =
- {
- MAP_TEXCOORD1,
- MAP_TEXCOORD2,
- MAP_TEXCOORD3
- };
+ U32 mask = 1 << i;
- for (U32 i = 0; i < 3; i++)
- {
- if (sLastMask & map_tc[i])
- {
- if (!(data_mask & map_tc[i]))
- { //disable
- glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- }
- else if (data_mask & map_tc[i])
- {
- glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ if (sLastMask & (1 << i))
+ { //was enabled
+ if (!(data_mask & mask))
+ { //needs to be disabled
+ glDisableVertexAttribArrayARB(loc);
}
}
-
- if (sLastMask & MAP_TANGENT)
- {
- if (!(data_mask & MAP_TANGENT))
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ else
+ { //was disabled
+ if (data_mask & mask)
+ { //needs to be enabled
+ glEnableVertexAttribArrayARB(loc);
}
}
- else if (data_mask & MAP_TANGENT)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
}
sLastMask = data_mask;
@@ -566,63 +468,23 @@ 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)
{
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
gGL.syncMatrices();
@@ -634,28 +496,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
@@ -720,7 +581,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
gGL.syncMatrices();
llassert(mNumVerts >= 0);
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+ llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
if (mGLArray)
{
@@ -763,6 +624,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,9 +635,21 @@ 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*)getIndicesPointer()) + 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);
+ llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
mMappable = false;
gGL.syncMatrices();
@@ -814,6 +688,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 +696,53 @@ 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;
- }
- }
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(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
- if (mode >= LLRender::NUM_MODES)
- {
- LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
- return;
- }
+ LLGLSLShader::startProfile();
+ {
+ LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040)
+ glDrawArrays(sGLMode[mode], first, count);
+ }
+ LLGLSLShader::stopProfile(count, mode);
- {
- 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);
- }
-
- stop_glerror();
- placeFence();
+ stop_glerror();
+ placeFence();
}
//static
@@ -964,8 +839,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
}
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage)
-: LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
- LLRefCount(),
+: LLRefCount(),
mNumVerts(0),
mNumIndices(0),
@@ -1110,9 +984,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 +1080,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 +1250,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 +1257,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 +1430,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)
+U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLBuffer(true);
if (mFinal)
{
@@ -1627,14 +1494,13 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
else
{
- volatile U8* src = NULL;
+ U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
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 +1524,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);
@@ -1688,7 +1553,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
llassert(src != NULL);
- mMappedData = LL_NEXT_ALIGNED_ADDRESS<volatile U8>(src);
+ mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedOffset = mMappedData - src;
stop_glerror();
@@ -1744,11 +1609,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)
+U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLIndices(true);
if (mFinal)
{
@@ -1816,14 +1679,13 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
- volatile U8* src = NULL;
+ U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
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 +1697,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 +1720,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 +1770,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 +1778,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 +1828,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 +1836,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 +1864,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 +1910,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 +1934,8 @@ void LLVertexBuffer::unmapBuffer()
mMappedIndexRegions.clear();
}
}
- stop_glerror();
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
- stop_glerror();
+
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
mMappedIndexData = NULL;
}
@@ -2111,7 +1961,7 @@ template <class T,S32 type> struct VertexBufferStrider
{
if (type == LLVertexBuffer::TYPE_INDEX)
{
- volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
+ U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == NULL)
{
@@ -2127,7 +1977,7 @@ template <class T,S32 type> struct VertexBufferStrider
{
S32 stride = LLVertexBuffer::sTypeSize[type];
- volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
+ U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
{
@@ -2208,13 +2058,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 +2080,6 @@ bool LLVertexBuffer::bindGLArray()
return false;
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
-
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
bindGLArray();
@@ -2241,8 +2088,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 +2102,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 +2140,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,11 +2345,39 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
+void LLVertexBuffer::setBufferFast(U32 data_mask)
+{
+ if (useVBOs())
+ {
+ //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++;
+ }
+ }
+ else
+ {
+ //fallback to slow path when not using VBOs
+ setBuffer(data_mask);
+ }
+}
+
+
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
stop_glerror();
- volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+ U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
@@ -2490,144 +2392,191 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL;
}
- if (LLGLSLShader::sNoFixedFunction)
+ if (data_mask & MAP_NORMAL)
{
- 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);
+ 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_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_TEXTURE_INDEX &&
- (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
- {
+ }
+ 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 &&
+ (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
+ {
#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);
+ 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);
- }
- }
- else
- {
- if (data_mask & MAP_NORMAL)
- {
- glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
- }
- if (data_mask & MAP_TEXCOORD3)
- {
- glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD2)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TANGENT)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
- }
- if (data_mask & MAP_COLOR)
- {
- glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
- }
- if (data_mask & MAP_VERTEX)
- {
- glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
- }
}
+ 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);
+ }
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..baf8407fc6 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -64,10 +64,10 @@ public:
const U32 mType;
//size MUST be a power of 2
- volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
+ U8* allocate(U32& name, U32 size, bool for_seed = false);
//size MUST be the size provided to allocate that returned the given name
- void release(U32 name, volatile U8* buffer, U32 size);
+ void release(U32 name, U8* buffer, U32 size);
//batch allocate buffers to be provided to the application on demand
void seedPool();
@@ -82,20 +82,23 @@ public:
{
public:
U32 mGLName;
- volatile U8* mClientData;
+ U8* mClientData;
};
typedef std::list<Record> record_list_t;
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();
@@ -229,13 +234,15 @@ public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
- volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
- volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
+ U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
+ U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
// 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);
@@ -271,14 +278,14 @@ public:
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
- volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
- volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
+ U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
+ U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
U32 getTypeMask() const { return mTypeMask; }
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
S32 getSize() const;
S32 getIndicesSize() const { return mIndicesSize; }
- volatile U8* getMappedData() const { return mMappedData; }
- volatile U8* getMappedIndices() const { return mMappedIndexData; }
+ U8* getMappedData() const { return mMappedData; }
+ U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
@@ -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;
@@ -308,8 +318,8 @@ protected:
U32 mGLIndices; // GL IBO handle
U32 mGLArray; // GL VAO handle
- volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
- volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
+ U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
+ U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
U32 mMappedDataUsingVBOs : 1;
U32 mMappedIndexDataUsingVBOs : 1;
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d96824bbf8..e0579352d3 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -308,6 +308,10 @@ if(LL_TESTS)
${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY}
${WINDOWS_LIBRARIES})
if(NOT LINUX)
- LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
+ if(WINDOWS)
+ LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "imm32;${test_libs}")
+ else(WINDOWS)
+ LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
+ endif(WINDOWS)
endif(NOT LINUX)
endif(LL_TESTS)
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.h b/indra/llui/llviewereventrecorder.h
index 94e66f5dc4..6170005b2b 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -41,12 +41,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..0edf39f6ef 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 void toggleVSync(bool enable_vsync) = 0;
+
+ virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
virtual BOOL getCursorPosition(LLCoordWindow *position) = 0;
+#if LL_WINDOWS
+ 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..410da79623 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 setCursorPosition(LLCoordWindow position) {return FALSE;};
- /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {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*/ void toggleVSync(bool enable_vsync) { }
+ /*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
+ /*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
+#if LL_WINDOWS
+ /*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..0e37e82091 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.
@@ -661,17 +661,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)
- {
- frames_per_swap = 0;
- }
- else
- {
- frames_per_swap = 1;
- }
-
- CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap);
+ toggleVSync(enable_vsync);
//enable multi-threaded OpenGL
if (sUseMultGL)
@@ -698,7 +688,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 +1906,49 @@ 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::toggleVSync(bool enable_vsync)
+{
+ GLint frames_per_swap = 0;
+ if (!enable_vsync)
+ {
+ frames_per_swap = 0;
+ }
+ else
+ {
+ frames_per_swap = 1;
+ }
+
+ CGLSetParameter(mContext, kCGLCPSwapInterval, &frames_per_swap);
+}
+
void LLWindowMacOSX::interruptLanguageTextInput()
{
commitCurrentPreedit(mGLView);
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index bf45238c8d..b0f339e1db 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,27 @@ 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;
+
+ void toggleVSync(bool enable_vsync) 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 +167,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 +178,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 +241,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..e4d771978a 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -45,6 +45,8 @@
#include "lldir.h"
#include "llsdutil.h"
#include "llglslshader.h"
+#include "llthreadsafequeue.h"
+#include "stringize.h"
// System includes
#include <commdlg.h>
@@ -54,6 +56,10 @@
#include <shellapi.h>
#include <fstream>
#include <Imm.h>
+#include <iomanip>
+#include <future>
+#include <sstream>
+#include <utility> // std::pair
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
@@ -77,8 +83,24 @@ const F32 ICON_FLASH_TIME = 0.5f;
#define USER_DEFAULT_SCREEN_DPI 96 // Win7
#endif
+// Claim a couple unused GetMessage() message IDs
+const UINT WM_DUMMY_(WM_USER + 0x0017);
+const UINT WM_POST_FUNCTION_(WM_USER + 0x0018);
+
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;
@@ -161,23 +183,19 @@ DWORD LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;
LLCoordWindow LLWindowWin32::sWinIMEWindowPosition(-1,-1);
// The following class LLWinImm delegates Windows IMM APIs.
-// We need this because some language versions of Windows,
-// e.g., US version of Windows XP, doesn't install IMM32.DLL
-// as a default, and we can't link against imm32.lib statically.
-// I believe DLL loading of this type is best suited to do
-// in a static initialization of a class. What I'm not sure is
-// whether it follows the Linden Conding Standard...
-// See http://wiki.secondlife.com/wiki/Coding_standards#Static_Members
+// It was originally introduced to support US Windows XP, on which we needed
+// to dynamically load IMM32.DLL and use GetProcAddress to resolve its entry
+// points. Now that that's moot, we retain this wrapper only for hooks for
+// metrics.
class LLWinImm
{
public:
- static bool isAvailable() { return sTheInstance.mHImmDll != NULL; }
+ static bool isAvailable() { return true; }
public:
// Wrappers for IMM API.
static BOOL isIME(HKL hkl);
- static HWND getDefaultIMEWnd(HWND hwnd);
static HIMC getContext(HWND hwnd);
static BOOL releaseContext(HWND hwnd, HIMC himc);
static BOOL getOpenStatus(HIMC himc);
@@ -191,236 +209,96 @@ public:
static BOOL setCompositionFont(HIMC himc, LPLOGFONTW logfont);
static BOOL setCandidateWindow(HIMC himc, LPCANDIDATEFORM candidate_form);
static BOOL notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value);
-
-private:
- LLWinImm();
- ~LLWinImm();
-
-private:
- // Pointers to IMM API.
- BOOL (WINAPI *mImmIsIME)(HKL);
- HWND (WINAPI *mImmGetDefaultIMEWnd)(HWND);
- HIMC (WINAPI *mImmGetContext)(HWND);
- BOOL (WINAPI *mImmReleaseContext)(HWND, HIMC);
- BOOL (WINAPI *mImmGetOpenStatus)(HIMC);
- BOOL (WINAPI *mImmSetOpenStatus)(HIMC, BOOL);
- BOOL (WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
- BOOL (WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD);
- BOOL (WINAPI *mImmGetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
- BOOL (WINAPI *mImmSetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
- LONG (WINAPI *mImmGetCompositionString)(HIMC, DWORD, LPVOID, DWORD);
- BOOL (WINAPI *mImmSetCompositionString)(HIMC, DWORD, LPVOID, DWORD, LPVOID, DWORD);
- BOOL (WINAPI *mImmSetCompositionFont)(HIMC, LPLOGFONTW);
- BOOL (WINAPI *mImmSetCandidateWindow)(HIMC, LPCANDIDATEFORM);
- BOOL (WINAPI *mImmNotifyIME)(HIMC, DWORD, DWORD, DWORD);
-
-private:
- HMODULE mHImmDll;
- static LLWinImm sTheInstance;
};
-LLWinImm LLWinImm::sTheInstance;
-
-LLWinImm::LLWinImm() : mHImmDll(NULL)
-{
- // Check system metrics
- if ( !GetSystemMetrics( SM_IMMENABLED ) )
- return;
-
- mHImmDll = LoadLibraryA("Imm32");
- if (mHImmDll != NULL)
- {
- mImmIsIME = (BOOL (WINAPI *)(HKL)) GetProcAddress(mHImmDll, "ImmIsIME");
- mImmGetDefaultIMEWnd = (HWND (WINAPI *)(HWND)) GetProcAddress(mHImmDll, "ImmGetDefaultIMEWnd");
- mImmGetContext = (HIMC (WINAPI *)(HWND)) GetProcAddress(mHImmDll, "ImmGetContext");
- mImmReleaseContext = (BOOL (WINAPI *)(HWND, HIMC)) GetProcAddress(mHImmDll, "ImmReleaseContext");
- mImmGetOpenStatus = (BOOL (WINAPI *)(HIMC)) GetProcAddress(mHImmDll, "ImmGetOpenStatus");
- mImmSetOpenStatus = (BOOL (WINAPI *)(HIMC, BOOL)) GetProcAddress(mHImmDll, "ImmSetOpenStatus");
- mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus");
- mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmSetConversionStatus");
- mImmGetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmGetCompositionWindow");
- mImmSetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM)) GetProcAddress(mHImmDll, "ImmSetCompositionWindow");
- mImmGetCompositionString= (LONG (WINAPI *)(HIMC, DWORD, LPVOID, DWORD)) GetProcAddress(mHImmDll, "ImmGetCompositionStringW");
- mImmSetCompositionString= (BOOL (WINAPI *)(HIMC, DWORD, LPVOID, DWORD, LPVOID, DWORD)) GetProcAddress(mHImmDll, "ImmSetCompositionStringW");
- mImmSetCompositionFont = (BOOL (WINAPI *)(HIMC, LPLOGFONTW)) GetProcAddress(mHImmDll, "ImmSetCompositionFontW");
- mImmSetCandidateWindow = (BOOL (WINAPI *)(HIMC, LPCANDIDATEFORM)) GetProcAddress(mHImmDll, "ImmSetCandidateWindow");
- mImmNotifyIME = (BOOL (WINAPI *)(HIMC, DWORD, DWORD, DWORD)) GetProcAddress(mHImmDll, "ImmNotifyIME");
-
- if (mImmIsIME == NULL ||
- mImmGetDefaultIMEWnd == NULL ||
- mImmGetContext == NULL ||
- mImmReleaseContext == NULL ||
- mImmGetOpenStatus == NULL ||
- mImmSetOpenStatus == NULL ||
- mImmGetConversionStatus == NULL ||
- mImmSetConversionStatus == NULL ||
- mImmGetCompostitionWindow == NULL ||
- mImmSetCompostitionWindow == NULL ||
- mImmGetCompositionString == NULL ||
- mImmSetCompositionString == NULL ||
- mImmSetCompositionFont == NULL ||
- mImmSetCandidateWindow == NULL ||
- mImmNotifyIME == NULL)
- {
- // If any of the above API entires are not found, we can't use IMM API.
- // So, turn off the IMM support. We should log some warning message in
- // the case, since it is very unusual; these APIs are available from
- // the beginning, and all versions of IMM32.DLL should have them all.
- // Unfortunately, this code may be executed before initialization of
- // the logging channel (LL_WARNS()), and we can't do it here... Yes, this
- // is one of disadvantages to use static constraction to DLL loading.
- FreeLibrary(mHImmDll);
- mHImmDll = NULL;
-
- // If we unload the library, make sure all the function pointers are cleared
- mImmIsIME = NULL;
- mImmGetDefaultIMEWnd = NULL;
- mImmGetContext = NULL;
- mImmReleaseContext = NULL;
- mImmGetOpenStatus = NULL;
- mImmSetOpenStatus = NULL;
- mImmGetConversionStatus = NULL;
- mImmSetConversionStatus = NULL;
- mImmGetCompostitionWindow = NULL;
- mImmSetCompostitionWindow = NULL;
- mImmGetCompositionString = NULL;
- mImmSetCompositionString = NULL;
- mImmSetCompositionFont = NULL;
- mImmSetCandidateWindow = NULL;
- mImmNotifyIME = NULL;
- }
- }
-}
-
-
// static
-BOOL LLWinImm::isIME(HKL hkl)
+BOOL LLWinImm::isIME(HKL hkl)
{
- if ( sTheInstance.mImmIsIME )
- return sTheInstance.mImmIsIME(hkl);
- return FALSE;
+ return ImmIsIME(hkl);
}
// static
HIMC LLWinImm::getContext(HWND hwnd)
{
- if ( sTheInstance.mImmGetContext )
- return sTheInstance.mImmGetContext(hwnd);
- return 0;
+ return ImmGetContext(hwnd);
}
//static
BOOL LLWinImm::releaseContext(HWND hwnd, HIMC himc)
{
- if ( sTheInstance.mImmIsIME )
- return sTheInstance.mImmReleaseContext(hwnd, himc);
- return FALSE;
+ return ImmReleaseContext(hwnd, himc);
}
// static
BOOL LLWinImm::getOpenStatus(HIMC himc)
{
- if ( sTheInstance.mImmGetOpenStatus )
- return sTheInstance.mImmGetOpenStatus(himc);
- return FALSE;
+ return ImmGetOpenStatus(himc);
}
// static
-BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
+BOOL LLWinImm::setOpenStatus(HIMC himc, BOOL status)
{
- if ( sTheInstance.mImmSetOpenStatus )
- return sTheInstance.mImmSetOpenStatus(himc, status);
- return FALSE;
+ return ImmSetOpenStatus(himc, status);
}
// static
BOOL LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)
{
- if ( sTheInstance.mImmGetConversionStatus )
- return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence);
- return FALSE;
+ return ImmGetConversionStatus(himc, conversion, sentence);
}
// static
BOOL LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)
{
- if ( sTheInstance.mImmSetConversionStatus )
- return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence);
- return FALSE;
+ return ImmSetConversionStatus(himc, conversion, sentence);
}
// static
BOOL LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
{
- if ( sTheInstance.mImmGetCompostitionWindow )
- return sTheInstance.mImmGetCompostitionWindow(himc, form);
- return FALSE;
+ return ImmGetCompositionWindow(himc, form);
}
// static
BOOL LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)
{
- if ( sTheInstance.mImmSetCompostitionWindow )
- return sTheInstance.mImmSetCompostitionWindow(himc, form);
- return FALSE;
+ return ImmSetCompositionWindow(himc, form);
}
// static
LONG LLWinImm::getCompositionString(HIMC himc, DWORD index, LPVOID data, DWORD length)
{
- if ( sTheInstance.mImmGetCompositionString )
- return sTheInstance.mImmGetCompositionString(himc, index, data, length);
- return FALSE;
+ return ImmGetCompositionString(himc, index, data, length);
}
// static
BOOL LLWinImm::setCompositionString(HIMC himc, DWORD index, LPVOID pComp, DWORD compLength, LPVOID pRead, DWORD readLength)
{
- if ( sTheInstance.mImmSetCompositionString )
- return sTheInstance.mImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength);
- return FALSE;
+ return ImmSetCompositionString(himc, index, pComp, compLength, pRead, readLength);
}
// static
BOOL LLWinImm::setCompositionFont(HIMC himc, LPLOGFONTW pFont)
{
- if ( sTheInstance.mImmSetCompositionFont )
- return sTheInstance.mImmSetCompositionFont(himc, pFont);
- return FALSE;
+ return ImmSetCompositionFont(himc, pFont);
}
// static
BOOL LLWinImm::setCandidateWindow(HIMC himc, LPCANDIDATEFORM form)
{
- if ( sTheInstance.mImmSetCandidateWindow )
- return sTheInstance.mImmSetCandidateWindow(himc, form);
- return FALSE;
+ return ImmSetCandidateWindow(himc, form);
}
// static
BOOL LLWinImm::notifyIME(HIMC himc, DWORD action, DWORD index, DWORD value)
{
- if ( sTheInstance.mImmNotifyIME )
- return sTheInstance.mImmNotifyIME(himc, action, index, value);
- return FALSE;
+ return ImmNotifyIME(himc, action, index, value);
}
-
-// ----------------------------------------------------------------------------------------
-LLWinImm::~LLWinImm()
-{
- if (mHImmDll != NULL)
- {
- FreeLibrary(mHImmDll);
- mHImmDll = NULL;
- }
-}
-
-
class LLMonitorInfo
{
public:
@@ -454,16 +332,83 @@ private:
static LLMonitorInfo sMonitorInfo;
+
+// Thread that owns the Window Handle
+// This whole struct is private to LLWindowWin32, which needs to mess with its
+// members, which is why it's a struct rather than a class. In effect, we make
+// the containing class a friend.
+struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
+{
+ static const int MAX_QUEUE_SIZE = 2048;
+
+ LLThreadSafeQueue<MSG> mMessageQueue;
+
+ LLWindowWin32Thread();
+
+ void run() override;
+
+ /// called by main thread to post work to this window thread
+ template <typename CALLABLE>
+ void post(CALLABLE&& func)
+ {
+ try
+ {
+ getQueue().post(std::forward<CALLABLE>(func));
+ }
+ catch (const LLThreadSafeQueueInterrupt&)
+ {
+ // Shutdown timing is tricky. The main thread can end up trying
+ // to post a cursor position after having closed the WorkQueue.
+ }
+ }
+
+ /**
+ * Like post(), Post() is a way of conveying a single work item to this
+ * thread. Its virtue is that it will definitely be executed "soon" rather
+ * than potentially waiting for the next frame: it uses PostMessage() to
+ * break us out of the window thread's blocked GetMessage() call. It's
+ * more expensive, though, not only from the Windows API latency of
+ * PostMessage() and GetMessage(), but also because it involves heap
+ * allocation and release.
+ *
+ * Require HWND from caller, even though we store an HWND locally.
+ * Otherwise, if our mWindowHandle was accessed from both threads, we'd
+ * have to protect it with a mutex.
+ */
+ template <typename CALLABLE>
+ void Post(HWND windowHandle, CALLABLE&& func)
+ {
+ // Move func to the heap. If we knew FuncType could fit into LPARAM,
+ // we could simply instantiate FuncType and pass it by value. But
+ // since we don't, we must put that on the heap as well as the
+ // internal heap allocation it likely requires to store func.
+ auto ptr = new FuncType(std::move(func));
+ WPARAM wparam{ 0xF1C };
+ LL_DEBUGS("Window") << "PostMessage(" << std::hex << windowHandle
+ << ", " << WM_POST_FUNCTION_
+ << ", " << wparam << std::dec << LL_ENDL;
+ PostMessage(windowHandle, WM_POST_FUNCTION_, wparam, LPARAM(ptr));
+ }
+
+ using FuncType = std::function<void()>;
+ // call GetMessage() and pull enqueue messages for later processing
+ void gatherInput();
+ HWND mWindowHandle = NULL;
+ HDC mhDC = 0;
+};
+
+
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();
//MAINT-516 -- force a load of opengl32.dll just in case windows went sideways
LoadLibrary(L"opengl32.dll");
@@ -471,7 +416,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mIconResource = gIconResource;
mOverrideAspectRatio = 0.f;
mNativeAspectRatio = 0.f;
- mMousePositionModified = FALSE;
mInputProcessingPaused = FALSE;
mPreeditor = NULL;
mKeyCharCode = 0;
@@ -483,6 +427,9 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp));
mCustomGammaSet = FALSE;
mWindowHandle = NULL;
+
+ mRect = {0, 0, 0, 0};
+ mClientRect = {0, 0, 0, 0};
if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))
{
@@ -535,7 +482,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
// Make an instance of our window then define the window class
mhInstance = GetModuleHandle(NULL);
- mWndProc = NULL;
// Init Direct Input - needed for joystick / Spacemouse
@@ -784,7 +730,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 +739,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 +764,8 @@ LLWindowWin32::~LLWindowWin32()
delete [] mWindowClassName;
mWindowClassName = NULL;
+
+ delete mWindowThread;
}
void LLWindowWin32::show()
@@ -850,7 +805,7 @@ void LLWindowWin32::restore()
// I'm turning off optimizations for this part to be sure code executes as intended
// (it is a straw, but I have no idea why else __try can get overruled)
#pragma optimize("", off)
-bool destroy_window_handler(HWND &hWnd)
+bool destroy_window_handler(HWND hWnd)
{
bool res;
__try
@@ -930,26 +885,33 @@ 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
- {
- // 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;
- }
+ 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;
+ });
+ // Even though the above lambda might not yet have run, we've already
+ // bound mWindowHandle into it by value, which should suffice for the
+ // operations we're asking. That's the last time WE should touch it.
+ mWindowHandle = NULL;
+ mWindowThread->close();
}
BOOL LLWindowWin32::isValid()
@@ -996,49 +958,22 @@ BOOL LLWindowWin32::getFullscreen()
BOOL LLWindowWin32::getPosition(LLCoordScreen *position)
{
- RECT window_rect;
-
- if (!mWindowHandle ||
- !GetWindowRect(mWindowHandle, &window_rect) ||
- NULL == position)
- {
- return FALSE;
- }
-
- position->mX = window_rect.left;
- position->mY = window_rect.top;
+ position->mX = mRect.left;
+ position->mY = mRect.top;
return TRUE;
}
BOOL LLWindowWin32::getSize(LLCoordScreen *size)
{
- RECT window_rect;
-
- if (!mWindowHandle ||
- !GetWindowRect(mWindowHandle, &window_rect) ||
- NULL == size)
- {
- return FALSE;
- }
-
- size->mX = window_rect.right - window_rect.left;
- size->mY = window_rect.bottom - window_rect.top;
+ size->mX = mRect.right - mRect.left;
+ size->mY = mRect.bottom - mRect.top;
return TRUE;
}
BOOL LLWindowWin32::getSize(LLCoordWindow *size)
{
- RECT client_rect;
-
- if (!mWindowHandle ||
- !GetClientRect(mWindowHandle, &client_rect) ||
- NULL == size)
- {
- return FALSE;
- }
-
- size->mX = client_rect.right - client_rect.left;
- size->mY = client_rect.bottom - client_rect.top;
+ size->mX = mClientRect.right - mClientRect.left;
+ size->mY = mClientRect.bottom - mClientRect.top;
return TRUE;
}
@@ -1065,14 +1000,17 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size)
return FALSE;
}
- WINDOWPLACEMENT placement;
- placement.length = sizeof(WINDOWPLACEMENT);
-
- if (!GetWindowPlacement(mWindowHandle, &placement)) return FALSE;
-
- placement.showCmd = SW_RESTORE;
+ mWindowThread->post([=]()
+ {
+ WINDOWPLACEMENT placement;
+ placement.length = sizeof(WINDOWPLACEMENT);
- if (!SetWindowPlacement(mWindowHandle, &placement)) return FALSE;
+ if (GetWindowPlacement(mWindowHandle, &placement))
+ {
+ placement.showCmd = SW_RESTORE;
+ SetWindowPlacement(mWindowHandle, &placement);
+ }
+ });
moveWindow(position, size);
return TRUE;
@@ -1084,177 +1022,165 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size)
DWORD dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
DWORD dw_style = WS_OVERLAPPEDWINDOW;
- AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
+ AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
return setSizeImpl(LLCoordScreen(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top));
}
// 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))
- {
- 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);
+
+ recreateWindow(window_rect, dw_ex_style, dw_style);
if (mWindowHandle)
{
@@ -1288,7 +1214,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 +1508,17 @@ const S32 max_format = (S32)num_formats - 1;
mhDC = 0; // Zero The Device Context
}
- // Destroy The Window
- if (mWindowHandle && !destroy_window_handler(mWindowHandle))
+ recreateWindow(window_rect, dw_ex_style, dw_style);
+
+ RECT rect;
+ RECT client_rect;
+ //initialize immediately on main thread
+ if (GetWindowRect(mWindowHandle, &rect) &&
+ GetClientRect(mWindowHandle, &client_rect))
{
- 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);
-
+ mRect = rect;
+ mClientRect = client_rect;
+ };
if (mWindowHandle)
{
@@ -1612,7 +1530,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 +1605,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 +1619,8 @@ const S32 max_format = (S32)num_formats - 1;
return FALSE;
}
+ LL_PROFILER_GPU_CONTEXT
+
if (!gGLManager.initGL())
{
close();
@@ -1756,15 +1629,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 +1655,177 @@ const S32 max_format = (S32)num_formats - 1;
return TRUE;
}
+void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style)
+{
+ auto oldHandle = mWindowHandle;
+
+ // zero out mWindowHandle and mhDC before destroying window so window
+ // thread falls back to peekmessage
+ mWindowHandle = 0;
+ mhDC = 0;
+
+ std::promise<std::pair<HWND, HDC>> promise;
+ // What follows must be done on the window thread.
+ auto window_work =
+ [this,
+ self=mWindowThread,
+ oldHandle,
+ // bind CreateWindowEx() parameters by value instead of
+ // back-referencing LLWindowWin32 members
+ windowClassName=mWindowClassName,
+ windowTitle=mWindowTitle,
+ hInstance=mhInstance,
+ window_rect,
+ dw_ex_style,
+ dw_style,
+ &promise]
+ ()
+ {
+ LL_DEBUGS("Window") << "recreateWindow(): window_work entry" << LL_ENDL;
+ self->mWindowHandle = 0;
+ self->mhDC = 0;
+
+ // important to call DestroyWindow() from the window thread
+ if (oldHandle && !destroy_window_handler(oldHandle))
+ {
+ LL_WARNS("Window") << "Failed to properly close window before recreating it!"
+ << LL_ENDL;
+ }
+
+ auto handle = CreateWindowEx(dw_ex_style,
+ windowClassName,
+ windowTitle,
+ 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,
+ hInstance,
+ NULL);
+
+ if (! handle)
+ {
+ // Failed to create window: clear the variables. This
+ // assignment is valid because we're running on mWindowThread.
+ self->mWindowHandle = NULL;
+ self->mhDC = 0;
+ }
+ else
+ {
+ // Update mWindowThread's own mWindowHandle and mhDC.
+ self->mWindowHandle = handle;
+ self->mhDC = GetDC(handle);
+ }
+
+ updateWindowRect();
+
+ // It's important to wake up the future either way.
+ promise.set_value(std::make_pair(self->mWindowHandle, self->mhDC));
+ LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL;
+ };
+ // But how we pass window_work to the window thread depends on whether we
+ // already have a window handle.
+ if (! oldHandle)
+ {
+ // Pass window_work using the WorkQueue: without an existing window
+ // handle, the window thread can't call GetMessage().
+ LL_DEBUGS("Window") << "posting window_work to WorkQueue" << LL_ENDL;
+ mWindowThread->post(window_work);
+ }
+ else
+ {
+ // Pass window_work using PostMessage(). We can still
+ // PostMessage(oldHandle) because oldHandle won't be destroyed until
+ // the window thread has retrieved and executed window_work.
+ LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL;
+ mWindowThread->Post(oldHandle, window_work);
+ }
+
+ auto future = promise.get_future();
+ // This blocks until mWindowThread processes CreateWindowEx() and calls
+ // promise.set_value().
+ auto pair = future.get();
+ mWindowHandle = pair.first;
+ mhDC = pair.second;
+}
+
+void* LLWindowWin32::createSharedContext()
+{
+ S32 attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
+ WGL_CONTEXT_MINOR_VERSION_ARB, 6,
+ 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 = 0;
+
+ 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;
+ }
+ }
+
+ 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 )
@@ -1808,66 +1844,106 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre
// THIS CAUSES DEV-15484 and DEV-15949
//ShowWindow(mWindowHandle, SW_RESTORE);
// NOW we can call MoveWindow
- MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);
+ mWindowThread->post([=]()
+ {
+ 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?)
+ mWindowThread->post([=]()
+ {
+ 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 +2045,8 @@ void LLWindowWin32::initCursors()
void LLWindowWin32::updateCursor()
{
+ ASSERT_MAIN_THREAD();
+ LL_PROFILE_ZONE_SCOPED
if (mNextCursor == UI_CURSOR_ARROW
&& mBusyCount > 0)
{
@@ -1978,7 +2056,11 @@ void LLWindowWin32::updateCursor()
if( mCurrentCursor != mNextCursor )
{
mCurrentCursor = mNextCursor;
- SetCursor( mCursor[mNextCursor] );
+ auto nextCursor = mCursor[mNextCursor];
+ mWindowThread->post([=]()
+ {
+ SetCursor(nextCursor);
+ });
}
}
@@ -1994,13 +2076,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 +2086,1006 @@ 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->getQueue().size())
+ {
+ LL_PROFILE_ZONE_NAMED("gi - PostMessage");
+ kickWindowThread();
+ }
+
+ while (mWindowThread->mMessageQueue.tryPopBack(msg))
+ {
+ LL_PROFILE_ZONE_NAMED("gi - message queue");
+ if (mInputProcessingPaused)
+ {
+ continue;
+ }
- // 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);
- }
- }
+ // For async host by name support. Really hacky.
+ if (gAsyncMsgCallback && (LL_WM_HOST_RESOLVED == msg.message))
+ {
+ LL_PROFILE_ZONE_NAMED("gi - callback");
+ 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;
+ ASSERT_WINDOW_THREAD();
+ LL_PROFILE_ZONE_SCOPED;
- 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;
+ LL_DEBUGS("Window") << "mainWindowProc(" << std::hex << h_wnd
+ << ", " << u_msg
+ << ", " << w_param << ")" << std::dec << LL_ENDL;
- 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;
-
- 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;
-
- 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;
+ if (u_msg == WM_POST_FUNCTION_)
+ {
+ LL_DEBUGS("Window") << "WM_POST_FUNCTION_" << LL_ENDL;
+ // from LLWindowWin32Thread::Post()
+ // Cast l_param back to the pointer to the heap FuncType
+ // allocated by Post(). Capture in unique_ptr so we'll delete
+ // once we're done with it.
+ std::unique_ptr<LLWindowWin32Thread::FuncType>
+ ptr(reinterpret_cast<LLWindowWin32Thread::FuncType*>(l_param));
+ (*ptr)();
+ 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;
+ // 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_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;
+ // 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;
- window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
- LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
+ LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA);
- 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;
- }
+ bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window");
- // 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;
+ if (NULL != window_imp)
+ {
+ // 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_MOVE:
+ {
+ window_imp->updateWindowRect();
+ return 0;
+ }
+ case WM_SIZE:
+ {
+ LL_PROFILE_ZONE_NAMED("mwp - WM_SIZE");
+ window_imp->updateWindowRect();
+ 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;
+ 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;
+ }
+ }
+ }
- break;
+ //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_WINDOWPOSCHANGING:
+ case WM_WINDOWPOSCHANGED:
+ 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);
- }
+ 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 +3264,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;
@@ -3214,43 +3296,46 @@ void LLWindowWin32::setMouseClipping( BOOL b )
BOOL LLWindowWin32::getClientRectInScreenSpace( RECT* rectp )
{
- BOOL success = FALSE;
+ BOOL success = FALSE;
- RECT client_rect;
- if( mWindowHandle && GetClientRect(mWindowHandle, &client_rect) )
- {
- POINT top_left;
- top_left.x = client_rect.left;
- top_left.y = client_rect.top;
- ClientToScreen(mWindowHandle, &top_left);
-
- POINT bottom_right;
- bottom_right.x = client_rect.right;
- bottom_right.y = client_rect.bottom;
- ClientToScreen(mWindowHandle, &bottom_right);
-
- SetRect( rectp,
- top_left.x,
- top_left.y,
- bottom_right.x,
- bottom_right.y );
-
- success = TRUE;
- }
+ RECT client_rect;
+ if (mWindowHandle && GetClientRect(mWindowHandle, &client_rect))
+ {
+ POINT top_left;
+ top_left.x = client_rect.left;
+ top_left.y = client_rect.top;
+ ClientToScreen(mWindowHandle, &top_left);
+
+ POINT bottom_right;
+ bottom_right.x = client_rect.right;
+ bottom_right.y = client_rect.bottom;
+ ClientToScreen(mWindowHandle, &bottom_right);
+
+ SetRect(rectp,
+ top_left.x,
+ top_left.y,
+ bottom_right.x,
+ bottom_right.y);
+
+ success = TRUE;
+ }
- return success;
+ return success;
}
void LLWindowWin32::flashIcon(F32 seconds)
{
- FLASHWINFO flash_info;
-
- flash_info.cbSize = sizeof(FLASHWINFO);
- flash_info.hwnd = mWindowHandle;
- flash_info.dwFlags = FLASHW_TRAY;
- flash_info.uCount = UINT(seconds / ICON_FLASH_TIME);
- flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds
- FlashWindowEx(&flash_info);
+ mWindowThread->post([=]()
+ {
+ FLASHWINFO flash_info;
+
+ flash_info.cbSize = sizeof(FLASHWINFO);
+ flash_info.hwnd = mWindowHandle;
+ flash_info.dwFlags = FLASHW_TRAY;
+ flash_info.uCount = UINT(seconds / ICON_FLASH_TIME);
+ flash_info.dwTimeout = DWORD(1000.f * ICON_FLASH_TIME); // milliseconds
+ FlashWindowEx(&flash_info);
+ });
}
F32 LLWindowWin32::getGamma()
@@ -3260,6 +3345,7 @@ F32 LLWindowWin32::getGamma()
BOOL LLWindowWin32::restoreGamma()
{
+ ASSERT_MAIN_THREAD();
if (mCustomGammaSet != FALSE)
{
LL_DEBUGS("Window") << "Restoring gamma" << LL_ENDL;
@@ -3271,6 +3357,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 +3396,7 @@ BOOL LLWindowWin32::setGamma(const F32 gamma)
void LLWindowWin32::setFSAASamples(const U32 fsaa_samples)
{
+ ASSERT_MAIN_THREAD();
mFSAASamples = fsaa_samples;
}
@@ -3319,6 +3407,7 @@ U32 LLWindowWin32::getFSAASamples()
LLWindow::LLWindowResolution* LLWindowWin32::getSupportedResolutions(S32 &num_resolutions)
{
+ ASSERT_MAIN_THREAD();
if (!mSupportedResolutions)
{
mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS];
@@ -3473,7 +3562,11 @@ BOOL LLWindowWin32::resetDisplayResolution()
void LLWindowWin32::swapBuffers()
{
+ LL_PROFILE_ZONE_SCOPED;
+ ASSERT_MAIN_THREAD();
SwapBuffers(mhDC);
+
+ LL_PROFILER_GPU_COLLECT
}
@@ -3698,13 +3791,19 @@ void *LLWindowWin32::getPlatformWindow()
void LLWindowWin32::bringToFront()
{
- BringWindowToTop(mWindowHandle);
+ mWindowThread->post([=]()
+ {
+ BringWindowToTop(mWindowHandle);
+ });
}
// set (OS) window focus back to the client
void LLWindowWin32::focusClient()
{
- SetFocus ( mWindowHandle );
+ mWindowThread->post([=]()
+ {
+ SetFocus(mWindowHandle);
+ });
}
void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
@@ -3946,6 +4045,7 @@ void LLWindowWin32::updateLanguageTextInputArea()
void LLWindowWin32::interruptLanguageTextInput()
{
+ ASSERT_MAIN_THREAD();
if (mPreeditor && LLWinImm::isAvailable())
{
HIMC himc = LLWinImm::getContext(mWindowHandle);
@@ -4148,6 +4248,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 +4297,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 +4505,153 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
#endif // LL_WINDOWS
+
+inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
+ : ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)
+{
+ ThreadPool::start();
+}
+
+/**
+ * LogChange is to log changes in status while trying to avoid spamming the
+ * log with repeated messages, especially in a tight loop. It refuses to log
+ * a continuous run of identical messages, but logs every time the message
+ * changes. (It will happily spam when messages quickly bounce back and
+ * forth.)
+ */
+class LogChange
+{
+public:
+ LogChange(const std::string& tag):
+ mTag(tag)
+ {}
+
+ template <typename... Items>
+ void always(Items&&... items)
+ {
+ // This odd construct ensures that the stringize() call is only
+ // executed if DEBUG logging is enabled for the passed tag.
+ LL_DEBUGS(mTag.c_str());
+ log(LL_CONT, stringize(std::forward<Items>(items)...));
+ LL_ENDL;
+ }
+
+ template <typename... Items>
+ void onChange(Items&&... items)
+ {
+ LL_DEBUGS(mTag.c_str());
+ auto str = stringize(std::forward<Items>(items)...);
+ if (str != mPrev)
+ {
+ log(LL_CONT, str);
+ }
+ LL_ENDL;
+ }
+
+private:
+ void log(std::ostream& out, const std::string& message)
+ {
+ mPrev = message;
+ out << message;
+ }
+ std::string mTag;
+ std::string mPrev;
+};
+
+void LLWindowWin32::LLWindowWin32Thread::run()
+{
+ sWindowThreadId = std::this_thread::get_id();
+ LogChange logger("Window");
+
+ while (! getQueue().done())
+ {
+ LL_PROFILE_ZONE_SCOPED;
+
+ if (mWindowHandle != 0)
+ {
+ MSG msg;
+ BOOL status;
+ if (mhDC == 0)
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - PeekMessage");
+ logger.onChange("PeekMessage(", std::hex, mWindowHandle, ")");
+ status = PeekMessage(&msg, mWindowHandle, 0, 0, PM_REMOVE);
+ }
+ else
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - GetMessage");
+ logger.always("GetMessage(", std::hex, mWindowHandle, ")");
+ status = GetMessage(&msg, NULL, 0, 0);
+ }
+ if (status > 0)
+ {
+ logger.always("got MSG (", std::hex, msg.hwnd, ", ", msg.message,
+ ", ", msg.wParam, ")");
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ mMessageQueue.pushFront(msg);
+ }
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - Function Queue");
+ logger.onChange("runPending()");
+ //process any pending functions
+ getQueue().runPending();
+ }
+
+#if 0
+ {
+ LL_PROFILE_ZONE_NAMED("w32t - Sleep");
+ logger.always("sleep(1)");
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+#endif
+ }
+}
+
+void LLWindowWin32::post(const std::function<void()>& func)
+{
+ mFunctionQueue.pushFront(func);
+}
+
+void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& func)
+{
+ mMouseQueue.pushFront(func);
+}
+
+void LLWindowWin32::kickWindowThread(HWND windowHandle)
+{
+ if (! windowHandle)
+ windowHandle = mWindowHandle;
+ if (windowHandle)
+ {
+ // 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
+ WPARAM wparam{ 0xB0B0 };
+ LL_DEBUGS("Window") << "PostMessage(" << std::hex << windowHandle
+ << ", " << WM_DUMMY_
+ << ", " << wparam << ")" << std::dec << LL_ENDL;
+ PostMessage(windowHandle, WM_DUMMY_, wparam, 0x1337);
+ }
+}
+
+void LLWindowWin32::updateWindowRect()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //called from window thread
+ RECT rect;
+ RECT client_rect;
+
+ if (GetWindowRect(mWindowHandle, &rect) &&
+ GetClientRect(mWindowHandle, &client_rect))
+ {
+ post([=]
+ {
+ mRect = rect;
+ mClientRect = client_rect;
+ });
+ }
+}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 0b3d14fb16..9367f49510 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -33,6 +33,10 @@
#include "llwindow.h"
#include "llwindowcallbacks.h"
#include "lldragdropwin32.h"
+#include "llthread.h"
+#include "llthreadsafequeue.h"
+#include "llmutex.h"
+#include "workqueue.h"
// Hack for async host by name
#define LL_WM_HOST_RESOLVED (WM_APP + 1)
@@ -57,9 +61,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 +133,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,17 +182,24 @@ 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()
WPARAM mLastSizeWParam;
F32 mOverrideAspectRatio;
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 +210,6 @@ protected:
BOOL mCustomGammaSet;
LPWSTR mIconResource;
- BOOL mMousePositionModified;
BOOL mInputProcessingPaused;
// The following variables are for Language Text Input control.
@@ -221,6 +237,20 @@ protected:
BOOL mMouseVanish;
+ // Cached values of GetWindowRect and GetClientRect to be used by app thread
+ void updateWindowRect();
+ RECT mRect;
+ RECT mClientRect;
+
+ struct LLWindowWin32Thread;
+ 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);
+ void recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style);
+ void kickWindowThread(HWND windowHandle=0);
+
friend class LLWindowManager;
};
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 19508becc3..088502c017 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -247,6 +247,7 @@ public:
// generic getter
template<typename T> T get(const std::string& name)
{
+ LL_PROFILE_ZONE_SCOPED;
LLControlVariable* control = getControl(name);
LLSD value;
eControlType type = TYPE_COUNT;
@@ -405,8 +406,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 +416,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 4bce646bf5..ef7c628c71 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -50,6 +50,7 @@ include(OpenSSL)
include(PNG)
include(TemplateCheck)
include(ThreeJS)
+include(Tracy)
include(UI)
include(UnixInstall)
include(ViewerMiscLibs)
@@ -95,6 +96,7 @@ include_directories(
${LIBS_PREBUILT_DIR}/include/collada/1.4
${LLAPPEARANCE_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
+ ${TRACY_INCLUDE_DIR}
)
include_directories(SYSTEM
@@ -282,7 +284,7 @@ set(viewer_SOURCE_FILES
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
- llfloateroutfitphotopreview.cpp
+ llfloateroutfitphotopreview.cpp
llfloateroutfitsnapshot.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
@@ -395,7 +397,6 @@ set(viewer_SOURCE_FILES
llloginhandler.cpp
lllogininstance.cpp
llmachineid.cpp
- llmainlooprepeater.cpp
llmanip.cpp
llmaniprotate.cpp
llmanipscale.cpp
@@ -591,11 +592,8 @@ set(viewer_SOURCE_FILES
llsyntaxid.cpp
llsyswellitem.cpp
llsyswellwindow.cpp
- lltelemetry.cpp
llteleporthistory.cpp
llteleporthistorystorage.cpp
- lltextureatlas.cpp
- lltextureatlasmanager.cpp
lltexturecache.cpp
lltexturectrl.cpp
lltexturefetch.cpp
@@ -1036,7 +1034,6 @@ set(viewer_HEADER_FILES
llloginhandler.h
lllogininstance.h
llmachineid.h
- llmainlooprepeater.h
llmanip.h
llmaniprotate.h
llmanipscale.h
@@ -1225,8 +1222,6 @@ set(viewer_HEADER_FILES
lltable.h
llteleporthistory.h
llteleporthistorystorage.h
- lltextureatlas.h
- lltextureatlasmanager.h
lltexturecache.h
lltexturectrl.h
lltexturefetch.h
@@ -1386,7 +1381,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt"
"${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n")
set_source_files_properties(
- llversioninfo.cpp tests/llversioninfo_test.cpp
+ llversioninfo.cpp tests/llversioninfo_test.cpp
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake
)
@@ -1608,6 +1603,7 @@ if (WINDOWS)
${WINDOWS_LIBRARIES}
comdlg32
dxguid
+ imm32
kernel32
odbc32
odbccp32
@@ -2004,7 +2000,7 @@ endif (WINDOWS)
# one of these being libz where you can find four or more versions in play
# at once. On Linux, libz can be found at link and run time via a number
# of paths:
-#
+#
# => -lfreetype
# => libz.so.1 (on install machine, not build)
# => -lSDL
@@ -2067,6 +2063,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLPHYSICS_LIBRARIES}
${LLPHYSICSEXTENSIONS_LIBRARIES}
${LLAPPEARANCE_LIBRARIES}
+ ${TRACY_LIBRARY}
)
if (USE_BUGSPLAT)
@@ -2175,7 +2172,7 @@ if (DARWIN)
# https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
set(CMAKE_MACOSX_RPATH 1)
-
+
set_target_properties(
${VIEWER_BINARY_NAME}
PROPERTIES
@@ -2377,7 +2374,7 @@ if (LL_TESTS)
llworldmap.cpp
llworldmipmap.cpp
PROPERTIES
- LL_TEST_ADDITIONAL_SOURCE_FILES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
tests/llviewertexture_stub.cpp
#llviewertexturelist.cpp
)
@@ -2411,7 +2408,7 @@ if (LL_TESTS)
llworldmap.cpp
llworldmipmap.cpp
PROPERTIES
- LL_TEST_ADDITIONAL_SOURCE_FILES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
tests/llviewertexture_stub.cpp
#llviewertexturelist.cpp
LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 5e3ec53ea6..826f5ce030 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.5.2
+6.6.0
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/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
index 662f7e39dd..f64937f443 100644
--- a/indra/newview/app_settings/high_graphics.xml
+++ b/indra/newview/app_settings/high_graphics.xml
@@ -6,8 +6,6 @@
<RenderAvatarLODFactor value="1.0"/>
<!--Default for now-->
<RenderAvatarPhysicsLODFactor value="0.9"/>
- <!--NO SHADERS-->
- <RenderAvatarVP value="TRUE"/>
<!--Short Range-->
<RenderFarClip value="128"/>
<!--Default for now-->
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index 0ee8e7a059..b31a040d67 100644
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -6,8 +6,6 @@
<RenderAvatarLODFactor value="0.5"/>
<!--Default for now-->
<RenderAvatarPhysicsLODFactor value="0.0"/>
- <!--NO SHADERS-->
- <RenderAvatarVP value="FALSE"/>
<!--Short Range-->
<RenderFarClip value="64"/>
<!--Default for now-->
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index c89e060307..9c2c17fc60 100644
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -6,8 +6,6 @@
<RenderAvatarLODFactor value="0.5"/>
<!--Default for now-->
<RenderAvatarPhysicsLODFactor value="0.75"/>
- <!--NO SHADERS-->
- <RenderAvatarVP value="TRUE"/>
<!--Short Range-->
<RenderFarClip value="96"/>
<!--Default for now-->
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 12f435f931..0ccf74e923 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>
@@ -3409,10 +3398,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>
@@ -3585,7 +3574,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DoubleClickTeleport</key>
+ <key>DoubleClickTeleport</key>
<map>
<key>Comment</key>
<string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
@@ -3915,6 +3904,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MainWorkTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Max time per frame devoted to mainloop work queue (in milliseconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.1</real>
+ </map>
<key>QueueInventoryFetchTimeout</key>
<map>
<key>Comment</key>
@@ -7074,6 +7074,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>
@@ -8682,28 +8693,6 @@
</array>
</map>
- <key>RenderAlphaBatchFullbrights</key>
- <map>
- <key>Comment</key>
- <string>Render fullbright alpha content more efficiently, but with possible visual differences from prev viewers.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>RenderAlphaBatchEmissives</key>
- <map>
- <key>Comment</key>
- <string>Render emissive alpha content more efficiently, but with possible visual differences from prev viewers.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>RenderAnisotropic</key>
<map>
<key>Comment</key>
@@ -8884,17 +8873,6 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>RenderAvatarVP</key>
- <map>
- <key>Comment</key>
- <string>Use vertex programs to perform hardware skinning of avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>RenderCompressTextures</key>
<map>
<key>Comment</key>
@@ -8906,7 +8884,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderHiDPI</key>
+ <key>RenderHiDPI</key>
<map>
<key>Comment</key>
<string>Enable support for HiDPI displays, like Retina (MacOS X ONLY, requires restart)</string>
@@ -9875,6 +9853,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderGLMultiThreaded</key>
+ <map>
+ <key>Comment</key>
+ <string>Allow OpenGL to use multiple render contexts (reduces frame stutters from loading textures, doesn't play nice with Intel drivers).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderGlow</key>
<map>
<key>Comment</key>
@@ -10178,7 +10167,7 @@
<key>Type</key>
<string>S32</string>
<key>Value</key>
- <integer>512</integer>
+ <integer>4096</integer>
</map>
<key>RenderNameFadeDuration</key>
<map>
@@ -11628,7 +11617,7 @@
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
- </map>
+ </map>
<key>NearbyListShowMap</key>
<map>
<key>Comment</key>
@@ -12722,6 +12711,20 @@
<key>Value</key>
<string />
</map>
+ <key>ThreadPoolSizes</key>
+ <map>
+ <key>Comment</key>
+ <string>Map of size overrides for specific thread pools.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <map>
+ <key>General</key>
+ <integer>4</integer>
+ </map>
+ </map>
<key>ThrottleBandwidthKBPS</key>
<map>
<key>Comment</key>
@@ -14164,17 +14167,6 @@
<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>
<map>
<key>Comment</key>
@@ -16692,8 +16684,8 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
- </map>
+ <integer>1</integer>
+ </map>
<key>360CaptureUseInterestListCap</key>
<map>
<key>Comment</key>
@@ -16773,14 +16765,25 @@
</map>
<key>ResetUIScaleOnFirstRun</key>
<map>
- <key>Comment</key>
- <string>Resets the UI scale factor on first run due to changed display scaling behavior</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
+ <key>Comment</key>
+ <string>Resets the UI scale factor on first run due to changed display scaling behavior</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <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/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index 506118d381..6a93bc2fd2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -105,9 +105,9 @@ void main()
vec4 vert = vec4(position.xyz, 1.0);
pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-#endif
+#endif //IS_AVATAR_SKIN
-#endif
+#endif // HAS_SKIN
#ifdef USE_INDEXED_TEX
passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index ef49b6f4e8..1b16e4eb09 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -40,11 +40,11 @@ VARYING vec4 post_pos;
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
+uniform vec4 color;
void main()
{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
+ float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * color.a;
if (alpha < 0.05) // treat as totally transparent
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index d1d7ece6fe..1c5b142ebd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -30,7 +30,6 @@ uniform float shadow_target_width;
mat4 getSkinnedTransform();
void passTextureIndex();
-ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
@@ -41,7 +40,6 @@ VARYING vec4 post_pos;
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
void main()
{
@@ -68,7 +66,6 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
#if !DEPTH_CLAMP
post_pos = pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
deleted file mode 100644
index 10144f3e16..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file bumpV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 tangent;
-
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-mat4 getObjectSkinnedTransform();
-
-void main()
-{
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
-
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
-
- vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
- vec3 b = cross(n, t) * tangent.w;
-
- vary_mat0 = vec3(t.x, b.x, n.x);
- vary_mat1 = vec3(t.y, b.y, n.y);
- vary_mat2 = vec3(t.z, b.z, n.z);
-
- gl_Position = projection_matrix*vec4(pos, 1.0);
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index 9f9749394e..d90891aa20 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -39,16 +39,32 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+#endif
+
void main()
{
//transform vertex
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
+ gl_Position = projection_matrix*vec4(pos, 1.0);
+
+ vec3 n = normalize((mat * vec4(normal.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+ vec3 t = normalize((mat * vec4(tangent.xyz+position.xyz, 1.0)).xyz-pos.xyz);
+#else
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
vec3 n = normalize(normal_matrix * normal);
vec3 t = normalize(normal_matrix * tangent.xyz);
+#endif
+
vec3 b = cross(n, t) * tangent.w;
-
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
vary_mat2 = vec3(t.z, b.z, n.z);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index 3c026796c8..d64bcefade 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -39,14 +39,28 @@ VARYING vec2 vary_texcoord0;
void passTextureIndex();
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+#endif
+
void main()
{
- //transform vertex
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+ vary_normal = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_normal = normalize(normal_matrix * normal);
+#endif
+
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
passTextureIndex();
- vary_normal = normalize(normal_matrix * normal);
-
+
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
index 5e4f08b017..08b1147ab0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
@@ -40,15 +40,26 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
void main()
{
//transform vertex
- vec4 vert = vec4(position.xyz, 1.0);
- vec4 pos = (modelview_matrix * vert);
passTextureIndex();
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+#else
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 8f6eb79668..2c139430e7 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -25,7 +25,6 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
@@ -47,19 +46,32 @@ VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
VARYING vec4 vary_position;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
+
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
+
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vert;
+ vary_position = gl_Position = projection_matrix * pos;
+ vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
vec4 pos = (modelview_matrix * vert);
vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
vec3 norm = normalize(normal_matrix * normal);
+#endif
vec3 ref = reflect(pos.xyz, -norm);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
+ vary_texcoord1 = transpose(normal_matrix) * ref.xyz;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index bdf3546aa5..e71636f2c9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -45,15 +45,26 @@ VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz, 1.0);
- vec4 pos = (modelview_matrix * vert);
passTextureIndex();
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vert;
+ gl_Position = projection_matrix * pos;
+#else
+ vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
#ifdef WATER_FOG
vary_position = pos.xyz;
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/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
index 2487110624..2b17aea75a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
@@ -1,8 +1,9 @@
/**
- * @file diffuseSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * @file shadowAlphaMaskSkinnedV.glsl
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,38 +23,48 @@
* $/LicenseInfo$
*/
-uniform mat4 projection_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+uniform float shadow_target_width;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-VARYING vec3 vary_normal;
+VARYING vec4 post_pos;
+VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+void passTextureIndex();
+
mat4 getObjectSkinnedTransform();
void main()
{
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
+ //transform vertex
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
- vec4 norm = vec4(position.xyz, 1.0);
- norm.xyz += normal.xyz;
- norm.xyz = (mat*norm).xyz;
- norm.xyz = normalize(norm.xyz-pos.xyz);
+ vec4 pos = mat * pre_pos;
+ pos = projection_matrix * pos;
- vary_normal = norm.xyz;
-
- vertex_color = diffuse_color;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+ post_pos = pos;
+
+#if !defined(DEPTH_CLAMP)
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
- gl_Position = projection_matrix*vec4(pos, 1.0);
+ passTextureIndex();
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
index df31b5a79f..bdf8e0854d 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
@@ -1,6 +1,7 @@
/**
- * @file simpleSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * @file shadowSkinnedV.glsl
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@@ -22,44 +23,30 @@
* $/LicenseInfo$
*/
-uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+VARYING vec4 post_pos;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
void main()
{
//transform vertex
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- vec4 norm = vec4(position.xyz, 1.0);
- norm.xyz += normal.xyz;
- norm.xyz = (mat*norm).xyz;
- norm.xyz = normalize(norm.xyz-pos.xyz);
-
- calcAtmospherics(pos.xyz);
+ vec4 pos = (mat*vec4(position.xyz, 1.0));
+ pos = projection_matrix*pos;
+
+ post_pos = pos;
+
+#if !defined(DEPTH_CLAMP)
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+#else
+ gl_Position = pos;
+#endif
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
- vertex_color = color;
-
- gl_Position = projection_matrix*vec4(pos, 1.0);
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
index 9064904191..d9ca6d3a46 100644
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
@@ -1,7 +1,7 @@
/**
- * @file emissiveSkinnedV.glsl
+ * @file treeShadowV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@@ -23,34 +23,31 @@
* $/LicenseInfo$
*/
-uniform mat4 projection_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
-
+uniform mat4 projection_matrix;
+
ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 emissive;
ATTRIBUTE vec2 texcoord0;
-VARYING vec4 vertex_color;
+VARYING vec4 post_pos;
VARYING vec2 vary_texcoord0;
-
-void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
void main()
{
//transform vertex
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- mat4 mat = getObjectSkinnedTransform();
+ mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
- vertex_color = emissive;
-
- calcAtmospherics(pos.xyz);
-
- gl_Position = projection_matrix*vec4(pos, 1.0);
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ pos = projection_matrix * pos;
+
+ post_pos = pos;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+
+ vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
index f4d704577a..153998f1d5 100644
--- a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
@@ -27,8 +27,21 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+#endif
+
void main()
{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz,1.0);
+ gl_Position = projection_matrix * pos;
+#else
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
index 9bf7b60eb7..0b362cf46c 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
@@ -31,10 +31,23 @@ ATTRIBUTE vec2 texcoord0;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+#endif
+
void main()
{
//transform vertex
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz,1.0);
+ gl_Position = projection_matrix * pos;
+#else
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl
index eff75435a9..7305065a05 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl
@@ -1,6 +1,7 @@
/**
- * @file fullbrightSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * @file occlusionSkinnedV.glsl
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
@@ -23,35 +24,17 @@
*/
uniform mat4 projection_matrix;
-uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-void calcAtmospherics(vec3 inPositionEye);
mat4 getObjectSkinnedTransform();
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
void main()
{
- //transform vertex
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
mat4 mat = getObjectSkinnedTransform();
-
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = diffuse_color;
-
gl_Position = projection_matrix*vec4(pos, 1.0);
-
-
}
+
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
index 5fcdf3107c..89be8195f0 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
@@ -56,5 +56,6 @@ void fullbright_lighting()
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
frag_color = color;
+
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
index a7738087dc..ee9970bc70 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
@@ -33,10 +33,23 @@ ATTRIBUTE vec2 texcoord1;
VARYING vec2 vary_texcoord0;
VARYING vec2 vary_texcoord1;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+uniform mat4 modelview_matrix;
+#endif
+
void main()
{
//transform vertex
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+#else
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
index e984deb0c8..d762239e51 100644
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
@@ -37,20 +37,30 @@ VARYING vec2 vary_texcoord0;
void calcAtmospherics(vec3 inPositionEye);
-
-
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
void main()
{
//transform vertex
passTextureIndex();
+
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+#else
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+
calcAtmospherics(pos.xyz);
vertex_color = emissive;
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
deleted file mode 100644
index 1e244d9dfd..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @file shinySimpleSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
-uniform mat4 modelview_matrix;
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
-
-
-void calcAtmospherics(vec3 inPositionEye);
-mat4 getObjectSkinnedTransform();
-
-void main()
-{
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- mat4 mvp = modelview_matrix * projection_matrix;
- vary_position = mvp * vec4(position, 1.0);
-
- vec4 norm = vec4(position.xyz, 1.0);
- norm.xyz += normal.xyz;
- norm.xyz = (mat*norm).xyz;
- norm.xyz = normalize(norm.xyz-pos.xyz);
-
- vec3 ref = reflect(pos.xyz, -norm.xyz);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = diffuse_color;
-
- gl_Position = projection_matrix*vec4(pos, 1.0);
-
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
index 34bd8d445a..ace2574ac2 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
@@ -25,7 +25,6 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
@@ -46,20 +45,32 @@ VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
+
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vert;
+ gl_Position = projection_matrix * pos;
+ vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
vec3 norm = normalize(normal_matrix * normal);
+#endif
vec3 ref = reflect(pos.xyz, -norm);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
+ vary_texcoord1 = transpose(normal_matrix) * ref;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
index fc20d3270e..5af42f1fcf 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
@@ -33,26 +33,33 @@ ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
-
void calcAtmospherics(vec3 inPositionEye);
-
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vert;
+ gl_Position = projection_matrix * pos;
+#else
+ vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);
vertex_color = diffuse_color;
-
-
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
deleted file mode 100644
index 727bae19c0..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file shinySimpleSkinnedV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
-mat4 getObjectSkinnedTransform();
-
-void main()
-{
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- vec4 norm = vec4(position.xyz, 1.0);
- norm.xyz += normal.xyz;
- norm.xyz = (mat*norm).xyz;
- norm.xyz = normalize(norm.xyz-pos.xyz);
-
- vec3 ref = reflect(pos.xyz, -norm.xyz);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
-
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm.xyz, diffuse_color);
- vertex_color = color;
-
- gl_Position = projection_matrix*vec4(pos, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
index 4ba8194d03..097e42d233 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
@@ -25,7 +25,6 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
@@ -45,19 +44,32 @@ void calcAtmospherics(vec3 inPositionEye);
uniform vec4 origin;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
+
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
+
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vert;
+ gl_Position = projection_matrix * pos;
+ vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
vec3 norm = normalize(normal_matrix * normal);
+#endif
vec3 ref = reflect(pos.xyz, -norm);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
+ vary_texcoord0 = (texture_matrix0*vec4(texcoord0,0,1)).xy;
+ vary_texcoord1 = transpose(normal_matrix) * ref;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 9ef7704b70..2025174f7d 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -44,12 +44,16 @@ void calcAtmospherics(vec3 inPositionEye);
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 projection_matrix;
+#endif
+
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
passTextureIndex();
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
@@ -58,11 +62,23 @@ void main()
if (no_atmo == 1)
{
vertex_color = diffuse_color;
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
}
else
{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+
+ vec4 pos = mat * vert;
+ vec3 norm = normalize((mat*vec4(normal.xyz+vert.xyz,1.0)).xyz-pos.xyz);
+
+ gl_Position = projection_matrix * pos;
+#else
vec4 pos = (modelview_matrix * vert);
vec3 norm = normalize(normal_matrix * normal);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+#endif
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index eb2cd356d9..8462df207b 100644
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -6,8 +6,6 @@
<RenderAvatarLODFactor value="1.0"/>
<!--Default for now-->
<RenderAvatarPhysicsLODFactor value="1.0"/>
- <!--NO SHADERS-->
- <RenderAvatarVP value="TRUE"/>
<!--Short Range-->
<RenderFarClip value="256"/>
<!--Default for now-->
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index f1bf8d76c2..4e56141fde 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 33
+version 34
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -70,37 +70,9 @@ RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
+RenderGLCoreProfile 1 1
+RenderGLMultiThreaded 1 1
-//
-// Low Graphics Settings (fixed function)
-//
-list LowFixedFunction
-RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
-RenderAvatarLODFactor 1 0
-RenderAvatarPhysicsLODFactor 1 0
-RenderAvatarMaxNonImpostors 1 3
-RenderAvatarMaxComplexity 1 25000
-RenderAvatarVP 1 0
-RenderFarClip 1 64
-RenderFlexTimeFactor 1 0
-RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
-RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
-RenderTerrainDetail 1 0
-RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
-RenderTreeLODFactor 1 0
-RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
-RenderFSAASamples 1 0
//
// Low Graphics Settings
@@ -112,7 +84,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 35000
-RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@@ -142,7 +113,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
-RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@@ -172,7 +142,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -202,7 +171,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -232,7 +200,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -262,7 +229,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -291,7 +257,6 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -316,414 +281,45 @@ RenderFSAASamples 1 2
// Class Unknown Hardware (unknown)
//
list Unknown
-RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
//
-// Class 0 Hardware (just old)
-//
-list Class0
-RenderVBOEnable 1 1
-
-//
-// Class 1 Hardware
-//
-list Class1
-RenderVBOEnable 1 1
-
-//
-// Class 2 Hardware
-//
-list Class2
-RenderVBOEnable 1 1
-
-//
-// Class 3 Hardware
-//
-list Class3
-RenderVBOEnable 1 1
-
-//
-// Class 4 Hardware
-//
-list Class4
-RenderVBOEnable 1 1
-
-//
-// Class 5 Hardware
-//
-list Class5
-RenderVBOEnable 1 1
-
-//
// VRAM > 512MB
//
list VRAMGT512
RenderCompressTextures 1 0
//
-// No Pixel Shaders available
-//
-list NoPixelShaders
-RenderAvatarVP 0 0
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderShadowDetail 0 0
-RenderUseAdvancedAtmospherics 0 0
-
-//
-// No Vertex Shaders available
-//
-list NoVertexShaders
-RenderAvatarVP 0 0
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderShadowDetail 0 0
-RenderUseAdvancedAtmospherics 0 0
-
-//
-// GL_ARB_map_buffer_range exists
-//
-list MapBufferRange
-RenderVBOMappingDisable 1 1
-
-
-//
// "Default" setups for safe, low, medium, high
//
list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
-RenderAvatarVP 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
-//
-// CPU based feature masks
-//
-
-// 1Ghz or less (equiv)
-list CPUSlow
-RenderMaxPartCount 1 1024
-
-//
-// RAM based feature masks
-//
-list RAM256MB
-RenderObjectBump 0 0
-
-//
-// Graphics card based feature masks
-//
-list OpenGLPre15
-RenderVBOEnable 1 0
-
-list OpenGLPre30
-RenderDeferred 0 0
-RenderMaxTextureIndex 1 1
-
list Intel
RenderAnisotropic 1 0
-RenderVBOEnable 1 0
RenderFSAASamples 1 0
+RenderGLMultiThreaded 1 0
+RenderGLCoreProfile 1 0
-list GeForce2
-RenderAnisotropic 1 0
-RenderMaxPartCount 1 2048
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 1
-
-list SiS
-UseOcclusion 0 0
-
-
-list Intel_830M
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_845G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_855GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_865G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_900
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_950
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_965
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-UseOcclusion 0 0
-
-list Intel_G33
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_G45
-WindLightUseAtmosShaders 0 0
-
-list Intel_Bear_Lake
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Broadwater
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Brookdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Eaglelake
-WindLightUseAtmosShaders 0 0
-
-list Intel_Montara
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Springdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-
-list ATI_FireGL_5200
-RenderVBOEnable 1 0
-WindLightUseAtmosShaders 0 0
-
-
-list ATI_Mobility_Radeon_7xxx
-RenderVBOEnable 0 0
-
-list ATI_Radeon_7xxx
-RenderVBOEnable 0 0
-
-list ATI_All-in-Wonder_Radeon
-RenderVBOEnable 0 0
-
-list ATI_All-in-Wonder_7500
-RenderVBOEnable 0 0
-
-list ATI_Mobility_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-
-/// tweaked ATI to 96 Draw distance
-
-list ATI_Radeon_9000
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9200
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9500
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-/// tweaked ATI to 128 draw distance
-
-list ATI_Radeon_X300
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X400
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X500
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X600
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X700
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X1300
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-UseStartScreen 0 0
-list ATI_Radeon_X1400
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X1500
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-UseStartScreen 0 0
-list ATI_Radeon_X1600
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Radeon_X1700
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-list ATI_Mobility_Radeon_X1xxx
-Disregard128DefaultDrawDistance 1 0
-RenderVBOEnable 1 0
-
-list ATI_Radeon_HD_2300
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_HD_2400
-Disregard128DefaultDrawDistance 1 0
-list ATI_ASUS_AH24xx
-Disregard128DefaultDrawDistance 1 0
-
-
-// Avatar hardware skinning causes invisible avatars
-// on various ATI chipsets on drivers before 8.2
-
-list ATIOldDriver
-RenderAvatarVP 0 0
-RenderAvatarCloth 0 0
-RenderVBOEnable 1 0
-
-// ATI cards generally perform better when not using VBOs for streaming data
-
-list ATI
+// AMD cards generally perform better when not using VBOs for streaming data
+// AMD cards also prefer an OpenGL Compatibility Profile Context
+list AMD
RenderUseStreamVBO 1 0
+RenderGLCoreProfile 1 0
-// Disable vertex buffer objects by default for ATI cards with little video memory
-list ATIVramLT256
-RenderVBOEnable 1 0
-
-/// Tweaked NVIDIA
-
-list NVIDIA_GeForce_FX_5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5500
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_FX_Go5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5300
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5500
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_6100
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6200
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6500
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6600
-Disregard128DefaultDrawDistance 1 0
-
-list NVIDIA_G73
-Disregard128DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_Go_6100
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6200
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6500
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6600
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6700
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6800
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_7000
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7100
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7200
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7300
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7400
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7500
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7600
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7700
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7800
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_7900
-RenderShaderLightingMaxLevel 1 2
-
-list NVIDIA_GeForce_Go_7200
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7300
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7300_LE
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7400
-Disregard128DefaultDrawDistance 1 0
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7600
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7700
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7800
-RenderShaderLightingMaxLevel 1 2
-list NVIDIA_GeForce_Go_7900
-RenderShaderLightingMaxLevel 1 2
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index bac6fd5708..13ede23a91 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 37
+version 38
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -70,37 +70,8 @@ RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
-
-//
-// Low Graphics Settings (fixed function)
-//
-list LowFixedFunction
-RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
-RenderAvatarLODFactor 1 0
-RenderAvatarPhysicsLODFactor 1 0
-RenderAvatarMaxNonImpostors 1 3
-RenderAvatarMaxComplexity 1 25000
-RenderAvatarVP 1 0
-RenderFarClip 1 64
-RenderFlexTimeFactor 1 0
-RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
-RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
-RenderTerrainDetail 1 0
-RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
-RenderTreeLODFactor 1 0
-RenderVolumeLODFactor 1 0.5
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
-RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
-RenderFSAASamples 1 0
+RenderGLCoreProfile 1 0
+RenderGLMultiThreaded 1 0
//
// Low Graphics Settings
@@ -112,7 +83,6 @@ RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
RenderAvatarMaxComplexity 1 35000
-RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
@@ -142,7 +112,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
-RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@@ -172,7 +141,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -202,7 +170,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -232,7 +199,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -262,7 +228,6 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -291,7 +256,6 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
-RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@@ -316,73 +280,11 @@ RenderFSAASamples 1 2
// Class Unknown Hardware (unknown)
//
list Unknown
-RenderVBOEnable 1 0
RenderShadowDetail 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
-//
-// Class 0 Hardware (just old)
-//
-list Class0
-RenderVBOEnable 1 1
-
-//
-// Class 1 Hardware
-//
-list Class1
-RenderVBOEnable 1 1
-
-//
-// Class 2 Hardware
-//
-list Class2
-RenderVBOEnable 1 1
-
-//
-// Class 3 Hardware
-//
-list Class3
-RenderVBOEnable 1 1
-
-//
-// Class 4 Hardware
-//
-list Class4
-RenderVBOEnable 1 1
-
-//
-// Class 5 Hardware
-//
-list Class5
-RenderVBOEnable 1 1
-
-//
-// No Pixel Shaders available
-//
-list NoPixelShaders
-RenderAvatarVP 0 0
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderUseAdvancedAtmospherics 0 0
-RenderShadowDetail 0 0
-
-//
-// No Vertex Shaders available
-//
-list NoVertexShaders
-RenderAvatarVP 0 0
-RenderAvatarCloth 0 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
-RenderDeferredSSAO 0 0
-RenderUseAdvancedAtmospherics 0 0
-RenderShadowDetail 0 0
//
// VRAM > 512MB
@@ -396,14 +298,12 @@ RenderCompressTextures 1 0
list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
-RenderAvatarVP 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
RenderObjectBump 0 0
RenderLocalLights 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
@@ -411,31 +311,10 @@ RenderDeferredSSAO 0 0
RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
-//
-// CPU based feature masks
-//
-
-// 1Ghz or less (equiv)
-list CPUSlow
-RenderMaxPartCount 1 1024
-
-//
-// RAM based feature masks
-//
-list RAM256MB
-RenderObjectBump 0 0
-
-//
-// Graphics card based feature masks
-//
-list OpenGLPre15
-RenderVBOEnable 1 0
-
-
list TexUnit8orLess
RenderDeferredSSAO 0 0
-list ATI
+list AMD
RenderDeferredSSAO 1 0
list Intel
@@ -443,195 +322,6 @@ RenderAnisotropic 1 0
RenderLocalLights 1 0
RenderFSAASamples 1 0
-list GeForce2
-RenderAnisotropic 1 0
-RenderLocalLights 1 0
-RenderMaxPartCount 1 2048
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 1
-
-list Intel_830M
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_845G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_855GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_865G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_900
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_915G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945GM
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_945G
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_950
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-RenderGround 1 0
-
-list Intel_965
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-UseOcclusion 0 0
-
-list Intel_G33
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Bear_Lake
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Broadwater
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Brookdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_X3100
-WindLightUseAtmosShaders 0 0
-
-list Intel_Montara
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list Intel_Springdale
-RenderTerrainDetail 1 0
-RenderVBOEnable 1 0
-
-list ATI_Mobility_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_8600
-RenderTextureMemoryMultiple 1 1
-UseOcclusion 0 0
-
-/// tweaked ATI to 96 Draw distance
-
-list ATI_Radeon_9000
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9200
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9500
-Disregard96DefaultDrawDistance 1 0
-list ATI_Radeon_9600
-Disregard96DefaultDrawDistance 1 0
-
-/// tweaked ATI to 128 draw distance
-
-list ATI_Radeon_X300
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X400
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X500
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X600
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X700
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1300
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1400
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1500
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1600
-Disregard128DefaultDrawDistance 1 0
-list ATI_Radeon_X1700
-Disregard128DefaultDrawDistance 1 0
-list ATI_Mobility_Radeon_X1xxx
-Disregard128DefaultDrawDistance 1 0
-
-/// Tweaked NVIDIA
-
-list NVIDIA_GeForce_FX_5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_5500
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_FX_Go5100
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5200
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5300
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5500
-Disregard96DefaultDrawDistance 1 0
-list NVIDIA_GeForce_FX_Go5600
-Disregard96DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_6100
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6200
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6500
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_6600
-Disregard128DefaultDrawDistance 1 0
-
-
-list NVIDIA_GeForce_Go_6100
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6200
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6500
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6600
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6700
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6800
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_6
-RenderVBOEnable 1 0
-Disregard128DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_7200
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_7300
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_7400
-Disregard128DefaultDrawDistance 1 0
-
-list NVIDIA_GeForce_Go_7200
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_7300
-Disregard128DefaultDrawDistance 1 0
-list NVIDIA_GeForce_Go_7400
-Disregard128DefaultDrawDistance 1 0
-
list OSX_10_6_8
RenderDeferred 0 0
diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh
index 466898ecda..e019437924 100755
--- a/indra/newview/installers/darwin/apple-notarize.sh
+++ b/indra/newview/installers/darwin/apple-notarize.sh
@@ -16,8 +16,9 @@ if [ -f "$CONFIG_FILE" ]; then
--password $PASSWORD \
--asc-provider $ASC_PROVIDER \
--file "$zip_file" 2>&1)
+ echo $res
+
requestUUID=$(echo $res | awk '/RequestUUID/ { print $NF; }')
-
echo "Apple Notarization RequestUUID: $requestUUID"
if [[ -n $requestUUID ]]; then
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 50e0d1d935..de382d4e23 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 c9d852686e..89e0da3ea7 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"
@@ -233,11 +232,12 @@
#include "llavatariconctrl.h"
#include "llgroupiconctrl.h"
#include "llviewerassetstats.h"
+#include "workqueue.h"
+using namespace LL;
// Include for security api initialization
#include "llsecapi.h"
#include "llmachineid.h"
-#include "llmainlooprepeater.h"
#include "llcleanup.h"
#include "llcoproceduremanager.h"
@@ -363,6 +363,10 @@ BOOL gLogoutInProgress = FALSE;
BOOL gSimulateMemLeak = FALSE;
+// We don't want anyone, especially threads working on the graphics pipeline,
+// to have to block due to this WorkQueue being full.
+WorkQueue gMainloopWork("mainloop", 1024*1024);
+
////////////////////////////////////////////////////////////
// Internal globals... that should be removed.
static std::string gArgs;
@@ -378,42 +382,6 @@ static std::string gLaunchFileOnQuit;
// Used on Win32 for other apps to identify our window (eg, win_setup)
const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
-//-- LLDeferredTaskList ------------------------------------------------------
-
-/**
- * A list of deferred tasks.
- *
- * We sometimes need to defer execution of some code until the viewer gets idle,
- * e.g. removing an inventory item from within notifyObservers() may not work out.
- *
- * Tasks added to this list will be executed in the next LLAppViewer::idle() iteration.
- * All tasks are executed only once.
- */
-class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList>
-{
- LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList);
- LOG_CLASS(LLDeferredTaskList);
-
- friend class LLAppViewer;
- typedef boost::signals2::signal<void()> signal_t;
-
- void addTask(const signal_t::slot_type& cb)
- {
- mSignal.connect(cb);
- }
-
- void run()
- {
- if (!mSignal.empty())
- {
- mSignal();
- mSignal.disconnect_all_slots();
- }
- }
-
- signal_t mSignal;
-};
-
//----------------------------------------------------------------------------
// List of entries from strings.xml to always replace
@@ -598,14 +566,14 @@ static void settings_to_globals()
static void settings_modify()
{
- LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
- LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderTransparentWater && LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
- LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred && gSavedSettings.getBOOL("RenderAvatarVP");
- LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
- LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
- gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
- gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
+ LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
+ LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
+ LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
+ LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4]
+ gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession;
+ gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
class LLFastTimerLogThread : public LLThread
@@ -686,8 +654,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)
{
@@ -856,8 +823,6 @@ bool LLAppViewer::init()
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
- writeSystemInfo();
-
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -964,8 +929,8 @@ bool LLAppViewer::init()
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
- // Initialize the repeater service.
- LLMainLoopRepeater::instance().start();
+ // Initialize event recorder
+ LLViewerEventRecorder::createInstance();
//
// Initialize the window
@@ -974,6 +939,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");
@@ -998,19 +966,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())
{
@@ -1136,7 +1091,7 @@ bool LLAppViewer::init()
{
url = LLTrans::getString("NvidiaDriverPage");
}
- else if (gGLManager.mIsATI)
+ else if (gGLManager.mIsAMD)
{
url = LLTrans::getString("AMDDriverPage");
}
@@ -1321,13 +1276,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)
{
@@ -1360,7 +1318,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");
@@ -1421,13 +1380,26 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame()
{
+ LL_RECORD_BLOCK_TIME(FTM_FRAME);
+
+ if (!LLWorld::instanceExists())
+ {
+ LLWorld::createInstance();
+ }
+
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();
@@ -1435,6 +1407,7 @@ bool LLAppViewer::doFrame()
LL_CLEAR_CALLSTACKS();
{
+ LL_PROFILE_ZONE_NAMED( "df processMiscNativeEvents" )
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
@@ -1443,7 +1416,10 @@ bool LLAppViewer::doFrame()
gViewerWindow->getWindow()->processMiscNativeEvents();
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df gatherInput" )
pingMainloopTimeout("Main:GatherInput");
+ }
if (gViewerWindow)
{
@@ -1467,13 +1443,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
@@ -1494,13 +1478,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))
{
@@ -1520,49 +1510,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()
@@ -1570,8 +1562,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)
@@ -1618,22 +1610,29 @@ 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" )
LLLFSThread::sLocal->pause();
}
//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)
@@ -1642,8 +1641,10 @@ bool LLAppViewer::doFrame()
}
}
+ {
+ LL_PROFILE_ZONE_NAMED( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
-
+ }
pingMainloopTimeout("Main:End");
}
}
@@ -1669,7 +1670,7 @@ bool LLAppViewer::doFrame()
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
- LLPROFILE_UPDATE();
+ LL_PROFILER_FRAME_END
return ! LLApp::isRunning();
}
@@ -1708,6 +1709,11 @@ void LLAppViewer::flushLFSIO()
bool LLAppViewer::cleanup()
{
+ // Since we don't know what functions are going to be queued by
+ // onCleanup(), we have to assume they might rely on some of the things
+ // we're about to destroy below. Run them first.
+ mOnCleanup();
+
LLAtmosphere::cleanupClass();
//ditch LLVOAvatarSelf instance
@@ -1754,6 +1760,7 @@ bool LLAppViewer::cleanup()
LLPluginProcessParent::shutdown();
disconnectViewer();
+ LLViewerCamera::deleteSingleton();
LL_INFOS() << "Viewer disconnected" << LL_ENDL;
@@ -1947,7 +1954,7 @@ bool LLAppViewer::cleanup()
if (LLEnvironment::instanceExists())
{
- //Store environment settings if nessesary
+ //Store environment settings if necessary
LLEnvironment::getInstance()->saveToSettings();
}
@@ -2138,12 +2145,14 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
- LLMainLoopRepeater::instance().stop();
-
ll_close_fail_log();
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
@@ -2326,7 +2335,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;
@@ -2421,6 +2430,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
@@ -2471,12 +2512,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);
@@ -2582,9 +2618,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();
}
@@ -2617,31 +2654,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;
}
@@ -2729,6 +2742,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() --
@@ -3505,11 +3531,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.
}
@@ -4251,12 +4280,12 @@ bool LLAppViewer::initCache()
{
if (mPurgeCache)
{
- LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
- purgeCache();
+ LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
+ purgeCache();
// clear the new C++ file system based cache
LLDiskCache::getInstance()->clearCache();
- }
+ }
else
{
// purge excessive files from the new file system based cache
@@ -4283,12 +4312,12 @@ bool LLAppViewer::initCache()
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
- return true;
+ return true;
}
void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
{
- LLDeferredTaskList::instance().addTask(cb);
+ gMainloopWork.post(cb);
}
void LLAppViewer::loadKeyBindings()
@@ -4690,6 +4719,20 @@ void LLAppViewer::idle()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
+ // Service the WorkQueue we use for replies from worker threads.
+ // Use function statics for the timeslice setting so we only have to fetch
+ // and convert MainWorkTime once.
+ static F32 MainWorkTimeRaw = gSavedSettings.getF32("MainWorkTime");
+ static F32Milliseconds MainWorkTimeMs(MainWorkTimeRaw);
+ // MainWorkTime is specified in fractional milliseconds, but std::chrono
+ // uses integer representations. What if we want less than a microsecond?
+ // Use nanoseconds. We're very sure we will never need to specify a
+ // MainWorkTime that would be larger than we could express in
+ // std::chrono::nanoseconds.
+ static std::chrono::nanoseconds MainWorkTimeNanoSec{
+ std::chrono::nanoseconds::rep(MainWorkTimeMs.value() * 1000000)};
+ gMainloopWork.runFor(MainWorkTimeNanoSec);
+
// Cap out-of-control frame times
// Too low because in menus, swapping, debugger, etc.
// Too high because idle called with no objects in view, etc.
@@ -5062,9 +5105,6 @@ void LLAppViewer::idle()
}
}
- // Execute deferred tasks.
- LLDeferredTaskList::instance().run();
-
// Handle shutdown process, for example,
// wait for floaters to close, send quit message,
// forcibly quit if it has taken too long
@@ -5471,19 +5511,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 0f06889d20..d807cf9765 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -50,6 +50,8 @@
#include "lltimer.h"
#include "llappcorehttp.h"
+#include <boost/signals2.hpp>
+
class LLCommandLineParser;
class LLFrameTimer;
class LLPumpIO;
@@ -69,13 +71,13 @@ public:
LLAppViewer();
virtual ~LLAppViewer();
- /**
- * @brief Access to the LLAppViewer singleton.
- *
- * The LLAppViewer singleton is created in main()/WinMain().
- * So don't use it in pre-entry (static initialization) code.
- */
- static LLAppViewer* instance() {return sInstance; }
+ /**
+ * @brief Access to the LLAppViewer singleton.
+ *
+ * The LLAppViewer singleton is created in main()/WinMain().
+ * So don't use it in pre-entry (static initialization) code.
+ */
+ static LLAppViewer* instance() {return sInstance; }
//
// Main application logic
@@ -93,12 +95,12 @@ public:
void earlyExit(const std::string& name,
const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit.
void earlyExitNoNotify(); // Do not display error dialog then forcibly quit.
- void abortQuit(); // Called to abort a quit request.
+ void abortQuit(); // Called to abort a quit request.
- bool quitRequested() { return mQuitRequested; }
- bool logoutRequestSent() { return mLogoutRequestSent; }
+ bool quitRequested() { return mQuitRequested; }
+ bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
- bool isUpdaterMissing() { return mUpdaterNotFound; }
+ bool isUpdaterMissing() { return mUpdaterNotFound; }
void writeDebugInfo(bool isStatic=true);
@@ -112,7 +114,7 @@ public:
virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism.
// return false if the error trap needed restoration.
static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon.
- void checkForCrash();
+ void checkForCrash();
// Thread accessors
static LLTextureCache* getTextureCache() { return sTextureCache; }
@@ -124,37 +126,37 @@ public:
static U32 getObjectCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
-
+
bool getPurgeCache() const { return mPurgeCache; }
-
+
std::string getSecondLifeTitle() const; // The Second Life title.
std::string getWindowTitle() const; // The window display name.
- void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user.
- void badNetworkHandler(); // Cause a crash state due to bad network packet.
+ void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user.
+ void badNetworkHandler(); // Cause a crash state due to bad network packet.
bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; }
void saveFinalSnapshot();
- void loadNameCache();
- void saveNameCache();
+ void loadNameCache();
+ void saveNameCache();
void loadExperienceCache();
void saveExperienceCache();
void removeMarkerFiles();
-
+
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@@ -187,22 +189,32 @@ public:
// *NOTE:Mani Fix this for login abstraction!!
void handleLoginComplete();
- LLAllocator & getAllocator() { return mAlloc; }
+ LLAllocator & getAllocator() { return mAlloc; }
// On LoginCompleted callback
typedef boost::signals2::signal<void (void)> login_completed_signal_t;
login_completed_signal_t mOnLoginCompleted;
- boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
+ boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb )
+ {
+ return mOnLoginCompleted.connect(cb);
+ }
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
+ typedef boost::signals2::signal<void()> cleanup_signal_t;
+ cleanup_signal_t mOnCleanup;
+ boost::signals2::connection onCleanup(const cleanup_signal_t::slot_type& cb)
+ {
+ return mOnCleanup.connect(cb);
+ }
+
void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; }
void purgeCache(); // Clear the local cache.
void purgeCacheImmediate(); //clear local cache immediately.
S32 updateTextureThreads(F32 max_time);
void loadKeyBindings();
-
+
// mute/unmute the system's master audio
virtual void setMasterSystemAudioMute(bool mute);
virtual bool getMasterSystemAudioMute();
@@ -214,7 +226,7 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
- void updateNameLookupUrl(const LLViewerRegion* regionp);
+ void updateNameLookupUrl(const LLViewerRegion* regionp);
protected:
virtual bool initWindow(); // Initialize the viewer's window.
@@ -225,7 +237,7 @@ protected:
virtual bool sendURLToOtherInstance(const std::string& url);
virtual bool initParseCommandLine(LLCommandLineParser& clp)
- { return true; } // Allow platforms to specify the command line args.
+ { return true; } // Allow platforms to specify the command line args.
virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this.
@@ -253,24 +265,22 @@ private:
void processMarkerFiles();
static void recordMarkerVersion(LLAPRFile& marker_file);
bool markerIsSameVersion(const std::string& marker_name) const;
-
- void idle();
- void idleShutdown();
+
+ void idle();
+ void idleShutdown();
// update avatar SLID and display name caches
void idleExperienceCache();
void idleNameCache();
- void idleNetwork();
-
- void sendLogoutRequest();
- void disconnectViewer();
+ void idleNetwork();
- bool onChangeFrameLimit(LLSD const & evt);
+ void sendLogoutRequest();
+ void disconnectViewer();
// *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;
- bool mSecondInstance; // Is this a second instance of the app?
+ bool mSecondInstance; // Is this a second instance of the app?
bool mUpdaterNotFound; // True when attempt to start updater failed
std::string mMarkerFileName;
@@ -302,8 +312,8 @@ private:
boost::optional<U32> mForceGraphicsLevel;
- bool mQuitRequested; // User wants to quit, may have modified documents open.
- bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
+ bool mQuitRequested; // User wants to quit, may have modified documents open.
+ bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim.
U32 mLastAgentControlFlags;
F32 mLastAgentForceUpdate;
struct SettingsFiles* mSettingsLocationList;
@@ -317,15 +327,12 @@ private:
bool mAgentRegionLastAlive;
LLUUID mAgentRegionLastID;
- LLAllocator mAlloc;
+ LLAllocator mAlloc;
// 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 ee533875b6..a39ec7f51b 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..4a87273372 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);
@@ -299,7 +299,6 @@ void LLControlAvatar::updateVolumeGeom()
mRootVolp->mDrawable->makeActive();
gPipeline.markMoved(mRootVolp->mDrawable);
gPipeline.markTextured(mRootVolp->mDrawable); // face may need to change draw pool to/from POOL_HUD
- mRootVolp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
LLViewerObject::const_child_list_t& child_list = mRootVolp->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -308,7 +307,6 @@ void LLControlAvatar::updateVolumeGeom()
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
gPipeline.markMoved(childp->mDrawable);
}
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..b274fd56b6 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;
@@ -150,21 +149,6 @@ void LLDrawable::unload()
{
LLVOVolume *pVVol = getVOVolume();
pVVol->setNoLOD();
-
- for (S32 i = 0; i < getNumFaces(); i++)
- {
- LLFace* facep = getFace(i);
- if (facep->isState(LLFace::RIGGED))
- {
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
- if (pool) {
- pool->removeRiggedFace(facep);
- }
- facep->setVertexBuffer(NULL);
- }
- facep->clearState(LLFace::RIGGED);
- }
-
pVVol->markForUpdate(TRUE);
}
@@ -261,19 +245,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 +259,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 +306,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 +336,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 +359,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 +382,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 +406,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 +431,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 +456,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 +491,8 @@ void LLDrawable::updateMaterial()
void LLDrawable::makeActive()
{
+ LL_PROFILE_ZONE_SCOPED
+
#if !LL_RELEASE_FOR_DOWNLOAD
if (mVObjp.notNull())
{
@@ -572,6 +556,8 @@ void LLDrawable::makeActive()
void LLDrawable::makeStatic(BOOL warning_enabled)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (isState(ACTIVE) &&
!isState(ACTIVE_CHILD) &&
!mVObjp->isAttachment() &&
@@ -618,6 +604,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 +757,8 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
void LLDrawable::movePartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSpatialPartition* part = getSpatialPartition();
if (part)
{
@@ -813,6 +803,8 @@ BOOL LLDrawable::updateMoveUndamped()
void LLDrawable::updatePartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!getVOVolume())
{
movePartition();
@@ -830,6 +822,8 @@ void LLDrawable::updatePartition()
BOOL LLDrawable::updateMoveDamped()
{
+ LL_PROFILE_ZONE_SCOPED
+
F32 dist_squared = updateXform(FALSE);
mGeneration++;
@@ -853,6 +847,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 +953,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 +1032,8 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
void LLDrawable::updateSpatialExtents()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mVObjp)
{
const LLVector4a* exts = getSpatialExtents();
@@ -1162,19 +1162,26 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp)
LLViewerOctreeEntryData::setGroup(groupp);
}
+/*
+* Get the SpatialPartition this Drawable should use.
+* Checks current SpatialPartition assignment and corrects if it is invalid.
+*/
LLSpatialPartition* LLDrawable::getSpatialPartition()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLSpatialPartition* retval = NULL;
-
+
if (!mVObjp ||
!getVOVolume() ||
isStatic())
{
- retval = gPipeline.getSpatialPartition((LLViewerObject*) mVObjp);
+ retval = gPipeline.getSpatialPartition((LLViewerObject*)mVObjp);
}
else if (isRoot())
{
- if (mSpatialBridge)
+ // determine if the spatial bridge has changed
+ if (mSpatialBridge)
{
U32 partition_type = mSpatialBridge->asPartition()->mPartitionType;
bool is_hud = mVObjp->isHUDAttachment();
@@ -1191,14 +1198,14 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
{
// Was/became part of animesh
// remove obsolete bridge
- mSpatialBridge->markDead();
+ mSpatialBridge->markDead();
setSpatialBridge(NULL);
}
else if ((partition_type == LLViewerRegion::PARTITION_AVATAR) != is_attachment)
{
// Was/became part of avatar
// remove obsolete bridge
- mSpatialBridge->markDead();
+ mSpatialBridge->markDead();
setSpatialBridge(NULL);
}
}
@@ -1209,17 +1216,20 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
{
setSpatialBridge(new LLHUDBridge(this, getRegion()));
}
- else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
- {
- setSpatialBridge(new LLControlAVBridge(this, getRegion()));
- }
+ else if (mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
+ {
+ setSpatialBridge(new LLControlAVBridge(this, getRegion()));
+ }
// check HUD first, because HUD is also attachment
else if (mVObjp->isAttachment())
{
+ // Attachment
+ // Use AvatarBridge of root object in attachment linkset
setSpatialBridge(new LLAvatarBridge(this, getRegion()));
}
else
{
+ // Moving linkset, use VolumeBridge of root object in linkset
setSpatialBridge(new LLVolumeBridge(this, getRegion()));
}
}
@@ -1247,6 +1257,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 +1304,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;
@@ -1392,10 +1403,21 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
ret.setOrigin(delta);
ret.setAxes(lookAt, left_axis, up_axis);
-
+
return ret;
}
+void LLSpatialBridge::transformExtents(const LLVector4a* src, LLVector4a* dst)
+{
+ LLMatrix4 mat = mDrawable->getXform()->getWorldMatrix();
+ mat.invert();
+
+ LLMatrix4a world_to_bridge(mat);
+
+ matMulBoundBox(world_to_bridge, src, dst);
+}
+
+
void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
{
LLViewerOctreeEntryData::setVisible();
@@ -1455,6 +1477,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 +1576,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();
@@ -1723,6 +1749,17 @@ void LLDrawable::updateFaceSize(S32 idx)
}
}
+LLDrawable* LLDrawable::getRoot()
+{
+ LLDrawable* ret = this;
+ while (!ret->isRoot())
+ {
+ ret = ret->getParent();
+ }
+
+ return ret;
+}
+
LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
: LLSpatialPartition(0, FALSE, 0, regionp)
{
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 14d782d6f2..2372ea01a6 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -59,14 +59,15 @@ 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:
+ typedef std::vector<LLFace*> face_list_t;
+
LLDrawable(const LLDrawable& rhs)
- : LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"),
- LLViewerOctreeEntryData(rhs)
+ : LLViewerOctreeEntryData(rhs)
{
*this = rhs;
}
@@ -120,6 +121,7 @@ public:
BOOL isAvatar() const { return mVObjp.notNull() && mVObjp->isAvatar(); }
BOOL isRoot() const { return !mParent || mParent->isAvatar(); }
+ LLDrawable* getRoot();
BOOL isSpatialRoot() const { return !mParent || mParent->isAvatar(); }
virtual BOOL isSpatialBridge() const { return FALSE; }
virtual LLSpatialPartition* asPartition() { return NULL; }
@@ -130,6 +132,7 @@ public:
inline LLFace* getFace(const S32 i) const;
inline S32 getNumFaces() const;
+ face_list_t& getFaces() { return mFaces; }
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
@@ -253,38 +256,34 @@ public:
{
IN_REBUILD_Q1 = 0x00000001,
IN_REBUILD_Q2 = 0x00000002,
- IN_LIGHT_Q = 0x00000004,
- EARLY_MOVE = 0x00000008,
- MOVE_UNDAMPED = 0x00000010,
- ON_MOVE_LIST = 0x00000020,
- USE_BACKLIGHT = 0x00000040,
- UV = 0x00000080,
- UNLIT = 0x00000100,
- LIGHT = 0x00000200,
- LIGHTING_BUILT = 0x00000400,
- REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed
- REBUILD_TCOORD = 0x00001000, //texture coordinates changed
- REBUILD_COLOR = 0x00002000, //color changed
- REBUILD_POSITION= 0x00004000, //vertex positions/normals changed
+ EARLY_MOVE = 0x00000004,
+ MOVE_UNDAMPED = 0x00000008,
+ ON_MOVE_LIST = 0x00000010,
+ UV = 0x00000020,
+ UNLIT = 0x00000040,
+ LIGHT = 0x00000080,
+ REBUILD_VOLUME = 0x00000100, //volume changed LOD or parameters, or vertex buffer changed
+ REBUILD_TCOORD = 0x00000200, //texture coordinates changed
+ REBUILD_COLOR = 0x00000400, //color changed
+ REBUILD_POSITION= 0x00000800, //vertex positions/normals changed
REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR,
REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR,
REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME,
- REBUILD_RIGGED = 0x00008000,
- ON_SHIFT_LIST = 0x00010000,
- BLOCKER = 0x00020000,
- ACTIVE = 0x00040000,
- DEAD = 0x00080000,
- INVISIBLE = 0x00100000, // stay invisible until flag is cleared
- NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet
- BUILT = 0x00400000,
- FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
- REBUILD_SHADOW = 0x02000000,
- HAS_ALPHA = 0x04000000,
- RIGGED = 0x08000000,
- PARTITION_MOVE = 0x10000000,
- ANIMATED_CHILD = 0x20000000,
- ACTIVE_CHILD = 0x40000000,
- FOR_UNLOAD = 0x80000000, //should be unload from memory
+ REBUILD_RIGGED = 0x00001000,
+ ON_SHIFT_LIST = 0x00002000,
+ ACTIVE = 0x00004000,
+ DEAD = 0x00008000,
+ INVISIBLE = 0x00010000, // stay invisible until flag is cleared
+ NEARBY_LIGHT = 0x00020000, // In gPipeline.mNearbyLightSet
+ BUILT = 0x00040000,
+ FORCE_INVISIBLE = 0x00080000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned)
+ HAS_ALPHA = 0x00100000,
+ RIGGED = 0x00200000, //has a rigged face
+ RIGGED_CHILD = 0x00400000, //has a child with a rigged face
+ PARTITION_MOVE = 0x00800000,
+ ANIMATED_CHILD = 0x01000000,
+ ACTIVE_CHILD = 0x02000000,
+ FOR_UNLOAD = 0x04000000, //should be unload from memory
} EDrawableFlags;
public:
@@ -298,8 +297,6 @@ public:
static F32 sCurPixelAngle; //current pixels per radian
private:
- typedef std::vector<LLFace*> face_list_t;
-
U32 mState;
S32 mRenderType;
LLPointer<LLViewerObject> mVObjp;
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index d583a692f9..503ee6d08d 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -50,6 +50,9 @@
#include "lldrawpoolwlsky.h"
#include "llglslshader.h"
#include "llglcommonfunc.h"
+#include "llvoavatar.h"
+#include "llviewershadermgr.h"
+
S32 LLDrawPool::sNumDrawPools = 0;
@@ -385,25 +388,48 @@ LLRenderPass::~LLRenderPass()
}
void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
-{
+{
+ LL_PROFILE_ZONE_SCOPED;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo *pparams = *k;
- if (pparams) {
+ if (pparams)
+ {
pushBatch(*pparams, mask, texture);
}
}
}
-void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
+void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
{
- pushBatches(type, mask, true, batch_textures);
+ LL_PROFILE_ZONE_SCOPED;
+ LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+
+ for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
+ {
+ LLDrawInfo* pparams = *k;
+ if (pparams)
+ {
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, mask, texture);
+ }
+ }
}
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;
@@ -414,27 +440,74 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text
}
}
+void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ if (pparams)
+ {
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, mask, texture, batch_textures);
+ }
+ }
+}
+
void LLRenderPass::pushMaskBatches(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;
if (pparams)
{
- if (LLGLSLShader::sCurBoundShaderPtr)
- {
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff);
- }
-
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, mask, texture, batch_textures);
}
}
}
+void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ if (pparams)
+ {
+ if (LLGLSLShader::sCurBoundShaderPtr)
+ {
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
+ }
+ else
+ {
+ gGL.flush();
+ }
+
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures);
+ }
+ }
+}
+
void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
{
if (params.mModelMatrix != gGLLastMatrix)
@@ -452,6 +525,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 +543,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 +551,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 +563,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)
{
@@ -517,7 +586,30 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
}
}
-void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture)
+// static
+bool LLRenderPass::uploadMatrixPalette(LLDrawInfo& params)
{
- gPipeline.renderGroups(this, type, mask, texture);
+ // upload matrix palette to shader
+ return uploadMatrixPalette(params.mAvatar, params.mSkinInfo);
}
+
+//static
+bool LLRenderPass::uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo)
+{
+ const LLVOAvatar::MatrixPaletteCache& mpc = avatar->updateSkinInfoMatrixPalette(skinInfo);
+ U32 count = mpc.mMatrixPalette.size();
+
+ if (count == 0)
+ {
+ //skin info not loaded yet, don't render
+ return false;
+ }
+
+ LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
+ FALSE,
+ (GLfloat*)&(mpc.mGLMp[0]));
+
+ return true;
+}
+
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index ecd9bd034f..d4f30fc51a 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -37,6 +37,8 @@ class LLViewerTexture;
class LLViewerFetchedTexture;
class LLSpatialGroup;
class LLDrawInfo;
+class LLVOAvatar;
+class LLMeshSkinInfo;
class LLDrawPool
{
@@ -125,38 +127,68 @@ protected:
class LLRenderPass : public LLDrawPool
{
public:
+ // list of possible LLRenderPass types to assign a render batch to
+ // NOTE: "rigged" variant MUST be non-rigged variant + 1
enum
{
PASS_SIMPLE = NUM_POOL_TYPES,
+ PASS_SIMPLE_RIGGED,
PASS_GRASS,
PASS_FULLBRIGHT,
+ PASS_FULLBRIGHT_RIGGED,
PASS_INVISIBLE,
- PASS_INVISI_SHINY,
+ PASS_INVISIBLE_RIGGED,
+ PASS_INVISI_SHINY,
+ PASS_INVISI_SHINY_RIGGED,
PASS_FULLBRIGHT_SHINY,
+ PASS_FULLBRIGHT_SHINY_RIGGED,
PASS_SHINY,
+ PASS_SHINY_RIGGED,
PASS_BUMP,
+ PASS_BUMP_RIGGED,
PASS_POST_BUMP,
+ PASS_POST_BUMP_RIGGED,
PASS_MATERIAL,
+ PASS_MATERIAL_RIGGED,
PASS_MATERIAL_ALPHA,
+ PASS_MATERIAL_ALPHA_RIGGED,
PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask
+ PASS_MATERIAL_ALPHA_MASK_RIGGED,
PASS_MATERIAL_ALPHA_EMISSIVE,
+ PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,
PASS_SPECMAP,
+ PASS_SPECMAP_RIGGED,
PASS_SPECMAP_BLEND,
+ PASS_SPECMAP_BLEND_RIGGED,
PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map)
+ PASS_SPECMAP_MASK_RIGGED,
PASS_SPECMAP_EMISSIVE,
+ PASS_SPECMAP_EMISSIVE_RIGGED,
PASS_NORMMAP,
+ PASS_NORMMAP_RIGGED,
PASS_NORMMAP_BLEND,
+ PASS_NORMMAP_BLEND_RIGGED,
PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map
+ PASS_NORMMAP_MASK_RIGGED,
PASS_NORMMAP_EMISSIVE,
+ PASS_NORMMAP_EMISSIVE_RIGGED,
PASS_NORMSPEC,
- PASS_NORMSPEC_BLEND,
+ PASS_NORMSPEC_RIGGED,
+ PASS_NORMSPEC_BLEND,
+ PASS_NORMSPEC_BLEND_RIGGED,
PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map
+ PASS_NORMSPEC_MASK_RIGGED,
PASS_NORMSPEC_EMISSIVE,
+ PASS_NORMSPEC_EMISSIVE_RIGGED,
PASS_GLOW,
+ PASS_GLOW_RIGGED,
PASS_ALPHA,
PASS_ALPHA_MASK,
+ PASS_ALPHA_MASK_RIGGED,
PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright
+ PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
PASS_ALPHA_INVISIBLE,
+ PASS_ALPHA_INVISIBLE_RIGGED,
NUM_RENDER_TYPES,
};
@@ -169,12 +201,14 @@ public:
static void applyModelMatrix(const LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
+ virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
+ virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+ static bool uploadMatrixPalette(LLDrawInfo& params);
+ static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
- virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
- virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE);
-
+ virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
};
class LLFacePool : public LLDrawPool
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 4ee08e869a..ee1a640f2d 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -48,34 +48,20 @@
#include "lldrawpoolwater.h"
#include "llspatialpartition.h"
#include "llglcommonfunc.h"
+#include "llvoavatar.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
-static BOOL deferred_render = FALSE;
+#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
-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");
+static BOOL deferred_render = FALSE;
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
- LLRenderPass(type), current_shader(NULL), target_shader(NULL),
- simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
+ LLRenderPass(type), target_shader(NULL),
mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
{
-
+
}
LLDrawPoolAlpha::~LLDrawPoolAlpha()
@@ -86,232 +72,188 @@ 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()
{
- if (LLPipeline::sImpostorRender)
- { //skip depth buffer filling pass when rendering impostors
- return 1;
- }
- else if (gSavedSettings.getBOOL("RenderDepthOfField"))
- {
- return 2;
- }
- else
- {
- return 1;
- }
+ return 1;
}
-void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+// set some common parameters on the given shader to prepare for alpha rendering
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+{
+ static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
+ F32 gamma = displayGamma;
+
+ // Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
+ // NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
+ // TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
+ // i.e. shaders\class1\deferred\alphaF.glsl
+ if (deferredEnvironment)
+ {
+ gPipeline.bindDeferredShader( *shader );
+ }
+ else
+ {
+ shader->bind();
+ }
+ shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
- emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+ if (LLPipeline::sImpostorRender)
+ {
+ shader->setMinimumAlpha(0.5f);
+ }
+ else
+ {
+ shader->setMinimumAlpha(0.f);
+ }
+ if (textureGamma)
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
- emissive_shader->bind();
- emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
- emissive_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- emissive_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+ //also prepare rigged variant
+ if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
+ {
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ }
+}
- if (pass == 0)
- {
- fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
- (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
+void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ deferred_render = TRUE;
- fullbright_shader->bind();
- fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- fullbright_shader->unbind();
+ // first pass, regular forward alpha rendering
+ {
+ emissive_shader = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+ prepare_alpha_shader(emissive_shader, true, false);
- simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
- (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
+ prepare_alpha_shader(fullbright_shader, true, false);
- //prime simple shader (loads shadow relevant uniforms)
- gPipeline.bindDeferredShader(*simple_shader);
+ simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
+ prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+
+ forwardRender();
+ }
- simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- }
- else if (!LLPipeline::sImpostorRender)
- {
- //update depth buffer sampler
- gPipeline.mScreen.flush();
- gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
- 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- gPipeline.mDeferredDepth.bindTarget();
- simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
- gObjectFullbrightAlphaMaskProgram.bind();
- gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
- }
+ // second pass, render to depth for depth of field effects
+ if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+ {
+ //update depth buffer sampler
+ gPipeline.mScreen.flush();
+ gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
+ 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ gPipeline.mDeferredDepth.bindTarget();
+ simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+
+ simple_shader->bind();
+ simple_shader->setMinimumAlpha(0.33f);
+
+ // mask off color buffer writes as we're only writing to depth buffer
+ gGL.setColorMask(false, false);
+
+ // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
+ // We don't want the nearly invisible objects to cause of DoF effects
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
+ true); // <--- discard mostly transparent faces
+
+ gPipeline.mDeferredDepth.flush();
+ gPipeline.mScreen.bindTarget();
+ gGL.setColorMask(true, false);
+ }
- deferred_render = TRUE;
- if (mShaderLevel > 0)
- {
- // Start out with no shaders.
- current_shader = target_shader = NULL;
- }
- gPipeline.enableLightsDynamic();
+ deferred_render = FALSE;
}
-void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
-
- if (pass == 1 && !LLPipeline::sImpostorRender)
- {
- gPipeline.mDeferredDepth.flush();
- gPipeline.mScreen.bindTarget();
- gObjectFullbrightAlphaMaskProgram.unbind();
- }
-
- deferred_render = FALSE;
- endRenderPass(pass);
-}
+//set some generic parameters for forward (non-deferred) rendering
+static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha)
+{
+ shader->bind();
+ shader->setMinimumAlpha(minimum_alpha);
+ shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED);
- render(pass);
+ //also prepare rigged variant
+ if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
+ {
+ prepare_forward_shader(shader->mRiggedVariant, minimum_alpha);
+ }
}
-void LLDrawPoolAlpha::beginRenderPass(S32 pass)
+void LLDrawPoolAlpha::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
-
- simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+
+ simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram;
- fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
+ fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram;
- emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+ emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
+ (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+ F32 minimum_alpha = 0.f;
if (LLPipeline::sImpostorRender)
- {
- if (mShaderLevel > 0)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.5f);
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.5f);
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
- }
- }
- else
- {
- if (mShaderLevel > 0)
- {
- fullbright_shader->bind();
- fullbright_shader->setMinimumAlpha(0.f);
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.f);
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
- }
- else
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
+ {
+ minimum_alpha = 0.5f;
}
- gPipeline.enableLightsDynamic();
+ prepare_forward_shader(fullbright_shader, minimum_alpha);
+ prepare_forward_shader(simple_shader, minimum_alpha);
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
+ forwardRender();
}
-void LLDrawPoolAlpha::endRenderPass( S32 pass )
+void LLDrawPoolAlpha::forwardRender()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_SETUP);
- LLRenderPass::endRenderPass(pass);
+ gPipeline.enableLightsDynamic();
- if(gPipeline.canUseWindLightShaders())
- {
- LLGLSLShader::bindNoShader();
- }
-}
+ LLGLSPipelineAlpha gls_pipeline_alpha;
-void LLDrawPoolAlpha::render(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA);
+ //enable writing to alpha for emissive effects
+ gGL.setColorMask(true, true);
- LLGLSPipelineAlpha gls_pipeline_alpha;
+ bool write_depth = LLDrawPoolWater::sSkipScreenCopy
+ // we want depth written so that rendered alpha will
+ // contribute to the alpha mask used for impostors
+ || LLPipeline::sImpostorRenderAlphaDepthPass;
- if (deferred_render && pass == 1)
- { //depth only
- gGL.setColorMask(false, false);
- }
- else
- {
- gGL.setColorMask(true, true);
- }
-
- bool write_depth = LLDrawPoolWater::sSkipScreenCopy
- || (deferred_render && pass == 1)
- // we want depth written so that rendered alpha will
- // contribute to the alpha mask used for impostors
- || LLPipeline::sImpostorRenderAlphaDepthPass;
+ LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
- LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
-
- if (deferred_render && pass == 1)
- {
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
- }
- else
- {
- mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
- mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
- mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
- mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
- }
+ mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
+ mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+ mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
+ mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
- if (mShaderLevel > 0)
- {
- renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
- }
- else
- {
- renderAlpha(getVertexDataMask(), pass);
- }
+ // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
+ // We don't want the nearly invisible objects to cause of DoF effects
+ renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, false);
- if (deferred_render && pass == 1)
- {
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
+ renderDebugAlpha();
+}
+void LLDrawPoolAlpha::renderDebugAlpha()
+{
if (sShowDebugAlpha)
{
- BOOL shaders = gPipeline.canUseVertexShaders();
- if(shaders)
- {
- gHighlightProgram.bind();
- }
- else
- {
- gPipeline.enableLightsFullbright();
- }
+ gHighlightProgram.bind();
+ gGL.diffuseColor4f(1, 0, 0, 1);
+ LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f * 1024.f);
+ gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep);
- gGL.diffuseColor4f(1,0,0,1);
-
- LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
- renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0);
+ renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_TEXCOORD0);
pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
@@ -327,15 +269,31 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.diffuseColor4f(0, 1, 0, 1);
pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- if(shaders)
- {
- gHighlightProgram.unbind();
- }
+ gHighlightProgram.mRiggedVariant->bind();
+ gGL.diffuseColor4f(1, 0, 0, 1);
+
+ pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+
+ // Material alpha mask
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+
+ gGL.diffuseColor4f(0, 1, 0, 1);
+ pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ LLGLSLShader::sCurBoundShaderPtr->unbind();
}
}
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
@@ -353,17 +311,37 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
continue;
}
+ bool rigged = (params.mAvatar != nullptr);
+ gHighlightProgram.bind(rigged);
+ gGL.diffuseColor4f(1, 0, 0, 1);
+
+ if (rigged)
+ {
+ if (lastAvatar != params.mAvatar ||
+ lastMeshId != params.mSkinInfo->mHash)
+ {
+ if (!uploadMatrixPalette(params))
+ {
+ continue;
+ }
+ lastAvatar = params.mAvatar;
+ lastMeshId = params.mSkinInfo->mHash;
+ }
+ }
+
LLRenderPass::applyModelMatrix(params);
if (params.mGroup)
{
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(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
}
+
+ // make sure static version of highlight shader is bound before returning
+ gHighlightProgram.bind();
}
inline bool IsFullbright(LLDrawInfo& params)
@@ -383,47 +361,41 @@ 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)
{
- 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);
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
}
}
- else if (current_shader == simple_shader)
+ else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
{
- 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 +403,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 +423,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,160 +441,66 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
}
}
-void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector<LLDrawInfo*>& simples)
+void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
{
- 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();
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
+ 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::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);
-
- 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 & ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2));
- RestoreTexSetup(tex_setup);
- }
- fullbright_shader->unbind();
-}
-
-void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector<LLDrawInfo*>& materials)
+void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
{
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
+ emissive_shader->bind();
+ emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
- gPipeline.enableLightsDynamic();
- bool use_shaders = gPipeline.canUseVertexShaders();
- for (LLDrawInfo* draw : materials)
+ for (LLDrawInfo* draw : emissives)
{
- 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);
+ bool tex_setup = TexSetup(draw, false);
+ drawEmissive(mask, draw);
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);
-}
-
-void LLDrawPoolAlpha::drawEmissiveInline(U32 mask, LLDrawInfo* draw)
+void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
{
- // install glow-accumulating blend mode
- gGL.blendFunc(
- LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
-
- emissive_shader->bind();
-
- drawEmissive(mask, draw);
+ LLGLSLShader* shader = emissive_shader->mRiggedVariant;
+ shader->bind();
+ shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
- // restore our alpha blend mode
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- current_shader->bind();
-}
-
-void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
-{
- emissive_shader->bind();
- emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
- gPipeline.enableLightsDynamic();
-
- // 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);
+ if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
+ {
+ if (!uploadMatrixPalette(*draw))
+ { // failed to upload matrix palette, skip rendering
+ continue;
+ }
+ lastAvatar = draw->mAvatar;
+ lastMeshId = draw->mSkinInfo->mHash;
+ }
drawEmissive(mask, draw);
RestoreTexSetup(tex_setup);
}
-
- // restore our alpha blend mode
- gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
-
- emissive_shader->unbind();
}
-void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
+void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only)
{
- BOOL batch_fullbrights = gSavedSettings.getBOOL("RenderAlphaBatchFullbrights");
- BOOL batch_emissives = gSavedSettings.getBOOL("RenderAlphaBatchEmissives");
- BOOL initialized_lighting = FALSE;
+ LL_PROFILE_ZONE_SCOPED;
+ BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
-
- BOOL use_shaders = gPipeline.canUseVertexShaders();
-
- for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ LLGLSLShader* lastAvatarShader = nullptr;
+
+ 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 +508,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*> rigged_emissives;
+ emissives.resize(0);
+ rigged_emissives.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 +525,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)
@@ -659,29 +536,21 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
continue;
}
- // Fix for bug - NORSPEC-271
- // If the face is more than 90% transparent, then don't update the Depth buffer for Dof
- // We don't want the nearly invisible objects to cause of DoF effects
- if(pass == 1 && !LLPipeline::sImpostorRender)
+ if(depth_only)
{
+ // when updating depth buffer, discard faces that are more than 90% transparent
LLFace* face = params.mFace;
if(face)
{
const LLTextureEntry* tep = face->getTextureEntry();
if(tep)
- {
+ { // don't render faces that are more than 90% transparent
if(tep->getColor().mV[3] < 0.1f)
continue;
}
}
}
- if (params.mFullbright && batch_fullbrights)
- {
- fullbrights.push_back(&params);
- continue;
- }
-
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
@@ -696,34 +565,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;
}
@@ -739,11 +591,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
target_shader = &(gDeferredMaterialWaterProgram[mask]);
}
+ if (params.mAvatar != nullptr)
+ {
+ llassert(target_shader->mRiggedVariant != nullptr);
+ target_shader = target_shader->mRiggedVariant;
+ }
+
if (current_shader != target_shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_DEFERRED_SHADER_BINDS);
gPipeline.bindDeferredShader(*target_shader);
- current_shader = target_shader;
}
}
else if (!params.mFullbright)
@@ -755,25 +611,23 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
target_shader = fullbright_shader;
}
- if(use_shaders && (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;
- }
+ if (params.mAvatar != nullptr)
+ {
+ target_shader = target_shader->mRiggedVariant;
+ }
+
+ 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).
+ target_shader->bind();
+ }
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;
@@ -782,7 +636,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
if (current_shader)
{
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
}
@@ -792,38 +646,54 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
params.mGroup->rebuildMesh();
}
- bool tex_setup = TexSetup(&params, use_shaders, use_shaders && (mat != nullptr), current_shader);
+ if (params.mAvatar != nullptr)
+ {
+ if (lastAvatar != params.mAvatar ||
+ lastMeshId != params.mSkinInfo->mHash ||
+ lastAvatarShader != LLGLSLShader::sCurBoundShaderPtr)
+ {
+ if (!uploadMatrixPalette(params))
+ {
+ continue;
+ }
+ lastAvatar = params.mAvatar;
+ lastMeshId = params.mSkinInfo->mHash;
+ lastAvatarShader = LLGLSLShader::sCurBoundShaderPtr;
+ }
+ }
+
+ bool tex_setup = TexSetup(&params, (mat != nullptr));
{
- 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));
-
+ U32 drawMask = mask;
+ if (params.mFullbright)
+ {
+ drawMask &= ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
+ }
+ if (params.mAvatar != nullptr)
{
- 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);
+ drawMask |= LLVertexBuffer::MAP_WEIGHT4;
}
+
+ params.mVertexBuffer->setBufferFast(drawMask);
+ params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
- if (current_shader &&
- draw_glow_for_this_partition &&
+ if (draw_glow_for_this_partition &&
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_EMISSIVE);
-
- if (batch_emissives)
+ if (params.mAvatar != nullptr)
{
- emissives.push_back(&params);
+ rigged_emissives.push_back(&params);
}
else
{
- drawEmissiveInline(mask, &params);
- }
+ emissives.push_back(&params);
+ }
}
if (tex_setup)
@@ -835,31 +705,67 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
}
}
- if (batch_fullbrights)
+ // render emissive faces into alpha channel for bloom effects
+ if (!depth_only)
{
- light_enabled = false;
- renderFullbrights(mask, fullbrights);
- }
+ gPipeline.enableLightsDynamic();
- if (batch_emissives)
- {
- light_enabled = true;
- renderEmissives(mask, emissives);
- }
+ // 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);
- if (current_shader)
- {
- current_shader->bind();
+ bool rebind = false;
+ LLGLSLShader* lastShader = current_shader;
+ if (!emissives.empty())
+ {
+ light_enabled = true;
+ renderEmissives(mask, emissives);
+ rebind = true;
+ }
+
+ if (!rigged_emissives.empty())
+ {
+ light_enabled = true;
+ renderRiggedEmissives(mask, rigged_emissives);
+ rebind = true;
+ }
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
+ if (lastShader && rebind)
+ {
+ lastShader->bind();
+ }
}
- }
+ }
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- LLVertexBuffer::unbind();
-
+ LLVertexBuffer::unbind();
+
if (!light_enabled)
{
gPipeline.enableLightsDynamic();
}
}
+
+bool LLDrawPoolAlpha::uploadMatrixPalette(const LLDrawInfo& params)
+{
+ const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo);
+ U32 count = mpc.mMatrixPalette.size();
+
+ if (count == 0)
+ {
+ //skin info not loaded yet, don't render
+ return false;
+ }
+
+ LLGLSLShader::sCurBoundShaderPtr->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
+ FALSE,
+ (GLfloat*)&(mpc.mGLMp[0]));
+
+ return true;
+}
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index a069f805e8..1f6909e282 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -51,39 +51,34 @@ public:
/*virtual*/ ~LLDrawPoolAlpha();
/*virtual*/ S32 getNumPostDeferredPasses();
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
-
- /*virtual*/ void beginRenderPass(S32 pass = 0);
- /*virtual*/ void endRenderPass( S32 pass );
/*virtual*/ S32 getNumPasses() { return 1; }
virtual void render(S32 pass = 0);
+ void forwardRender();
/*virtual*/ void prerender();
+ void renderDebugAlpha();
+
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
- void renderAlpha(U32 mask, S32 pass);
+ void renderAlpha(U32 mask, bool depth_only = false);
void renderAlphaHighlight(U32 mask);
-
+ bool uploadMatrixPalette(const LLDrawInfo& params);
+
static BOOL sShowDebugAlpha;
private:
- LLGLSLShader* current_shader;
LLGLSLShader* target_shader;
- LLGLSLShader* simple_shader;
- 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);
+ // setup by beginFooPass, [0] is static variant, [1] is rigged variant
+ LLGLSLShader* simple_shader = nullptr;
+ LLGLSLShader* fullbright_shader = nullptr;
+ LLGLSLShader* emissive_shader = nullptr;
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);
+ void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
+ void renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
+ bool TexSetup(LLDrawInfo* draw, bool use_material);
void RestoreTexSetup(bool tex_setup);
// our 'normal' alpha blend function for this pass
@@ -91,6 +86,9 @@ private:
LLRender::eBlendFactor mColorDFactor;
LLRender::eBlendFactor mAlphaSFactor;
LLRender::eBlendFactor mAlphaDFactor;
+
+ // if true, we're executing a rigged render pass
+ bool mRigged = false;
};
class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index eb0bd0de4e..e1e57ef319 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,28 +119,27 @@ LLDrawPoolAvatar::~LLDrawPoolAvatar()
// virtual
BOOL LLDrawPoolAvatar::isDead()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!LLFacePool::isDead())
{
return FALSE;
}
- for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
- {
- if (mRiggedFace[i].size() > 0)
- {
- return FALSE;
- }
- }
return TRUE;
}
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;
@@ -155,20 +152,12 @@ void LLDrawPoolAvatar::prerender()
{
sBufferUsage = GL_STREAM_DRAW_ARB;
}
-
- if (!mDrawFace.empty())
- {
- const LLFace *facep = mDrawFace[0];
- if (facep && facep->getDrawable())
- {
- LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
- updateRiggedVertexBuffers(avatarp);
- }
- }
}
LLMatrix4& LLDrawPoolAvatar::getModelView()
{
+ LL_PROFILE_ZONE_SCOPED
+
static LLMatrix4 ret;
ret.initRows(LLVector4(gGLModelView+0),
@@ -187,7 +176,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;
@@ -208,21 +197,12 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
case 2:
beginDeferredSkinned();
break;
- case 3:
- beginDeferredRiggedSimple();
- break;
- case 4:
- beginDeferredRiggedBump();
- break;
- default:
- beginDeferredRiggedMaterial(pass-5);
- break;
}
}
void LLDrawPoolAvatar::endDeferredPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_CHARACTERS);
+ LL_PROFILE_ZONE_SCOPED;
sSkipTransparent = FALSE;
is_deferred_render = false;
@@ -243,58 +223,25 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
case 2:
endDeferredSkinned();
break;
- case 3:
- endDeferredRiggedSimple();
- break;
- case 4:
- endDeferredRiggedBump();
- break;
- default:
- endDeferredRiggedMaterial(pass-5);
- break;
}
}
void LLDrawPoolAvatar::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED
+
render(pass);
}
S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
{
- return 10;
+ return 1;
}
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
{
- switch (pass)
- {
- case 0:
- beginPostDeferredAlpha();
- break;
- case 1:
- beginRiggedFullbright();
- break;
- case 2:
- beginRiggedFullbrightShiny();
- break;
- case 3:
- beginDeferredRiggedAlpha();
- break;
- case 4:
- beginRiggedFullbrightAlpha();
- break;
- case 9:
- beginRiggedGlow();
- break;
- default:
- beginDeferredRiggedMaterialAlpha(pass-5);
- break;
- }
-}
+ LL_PROFILE_ZONE_SCOPED
-void LLDrawPoolAvatar::beginPostDeferredAlpha()
-{
sSkipOpaque = TRUE;
sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarAlphaProgram;
@@ -307,80 +254,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
-void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
-{
- sVertexProgram = &gDeferredSkinnedAlphaProgram;
- gPipeline.bindDeferredShader(*sVertexProgram);
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- gPipeline.enableLightsDynamic();
-}
-
-void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
-{
- switch (pass)
- {
- case 0: pass = 1; break;
- case 1: pass = 5; break;
- case 2: pass = 9; break;
- default: pass = 13; break;
- }
-
- pass += LLMaterial::SHADER_COUNT;
-
- sVertexProgram = &gDeferredMaterialProgram[pass];
-
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &(gDeferredMaterialWaterProgram[pass]);
- }
-
- gPipeline.bindDeferredShader(*sVertexProgram);
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
- gPipeline.enableLightsDynamic();
-}
-
-void LLDrawPoolAvatar::endDeferredRiggedAlpha()
-{
- LLVertexBuffer::unbind();
- gPipeline.unbindDeferredShader(*sVertexProgram);
- sDiffuseChannel = 0;
- normal_channel = -1;
- specular_channel = -1;
- sVertexProgram = NULL;
-}
-
void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
{
- switch (pass)
- {
- case 0:
- endPostDeferredAlpha();
- break;
- case 1:
- endRiggedFullbright();
- break;
- case 2:
- endRiggedFullbrightShiny();
- break;
- case 3:
- endDeferredRiggedAlpha();
- break;
- case 4:
- endRiggedFullbrightAlpha();
- break;
- case 5:
- endRiggedGlow();
- break;
- default:
- endDeferredRiggedAlpha();
- break;
- }
-}
-
-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,29 +268,17 @@ void LLDrawPoolAvatar::endPostDeferredAlpha()
void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
{
- static const S32 actual_pass[] =
- { //map post deferred pass numbers to what render() expects
- 2, //skinned
- 4, // rigged fullbright
- 6, //rigged fullbright shiny
- 7, //rigged alpha
- 8, //rigged fullbright alpha
- 9, //rigged material alpha 1
- 10,//rigged material alpha 2
- 11,//rigged material alpha 3
- 12,//rigged material alpha 4
- 13, //rigged glow
- };
-
- S32 p = actual_pass[pass];
+ LL_PROFILE_ZONE_SCOPED
+ is_post_deferred_render = true;
if (LLPipeline::sImpostorRender)
{ //HACK for impostors so actual pass ends up being proper pass
- p -= 2;
+ render(0);
+ }
+ else
+ {
+ render(2);
}
-
- is_post_deferred_render = true;
- render(p);
is_post_deferred_render = false;
}
@@ -427,7 +291,7 @@ 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)
{
@@ -439,7 +303,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram->bind();
}
- gGL.diffuseColor4f(1,1,1,1);
+ gGL.diffuseColor4f(1, 1, 1, 1);
}
else if (pass == SHADOW_PASS_AVATAR_ALPHA_BLEND)
{
@@ -459,7 +323,7 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram->bind();
}
- gGL.diffuseColor4f(1,1,1,1);
+ gGL.diffuseColor4f(1, 1, 1, 1);
}
else if (pass == SHADOW_PASS_AVATAR_ALPHA_MASK)
{
@@ -479,69 +343,13 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
sVertexProgram->bind();
}
- gGL.diffuseColor4f(1,1,1,1);
- }
- else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_BLEND)
- {
- sVertexProgram = &gDeferredAttachmentAlphaShadowProgram;
-
- // bind diffuse tex so we can reference the alpha channel...
- 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();
- }
-
- gGL.diffuseColor4f(1,1,1,1);
- }
- else if (pass == SHADOW_PASS_ATTACHMENT_ALPHA_MASK)
- {
- sVertexProgram = &gDeferredAttachmentAlphaMaskShadowProgram;
-
- // bind diffuse tex so we can reference the alpha channel...
- 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();
- }
-
- 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();
+ gGL.diffuseColor4f(1, 1, 1, 1);
}
}
void LLDrawPoolAvatar::endShadowPass(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
-
- if (pass == SHADOW_PASS_ATTACHMENT_OPAQUE)
- {
- LLVertexBuffer::unbind();
- }
+ LL_PROFILE_ZONE_SCOPED;
if (sShaderLevel > 0)
{
@@ -554,7 +362,7 @@ void LLDrawPoolAvatar::endShadowPass(S32 pass)
void LLDrawPoolAvatar::renderShadow(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_AVATAR);
+ LL_PROFILE_ZONE_SCOPED;
if (mDrawFace.empty())
{
@@ -574,10 +382,9 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
}
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
- if (oa == LLVOAvatar::AOA_INVISIBLE ||
- (impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
+ if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
{
- // No shadows for jellydolled or invisible avs.
+ // No shadows for impostored (including jellydolled) or invisible avs.
return;
}
@@ -601,79 +408,23 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
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);
- renderRigged(avatarp, RIGGED_ALPHA);
- renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
- renderRigged(avatarp, RIGGED_GLOW);
- renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
- 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_GLOW);
- LLDrawPoolAvatar::sSkipOpaque = false;
- }
- else // rigged opaque (SHADOW_PASS_ATTACHMENT_OPAQUE
- {
- LLDrawPoolAvatar::sSkipTransparent = true;
- 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);
- LLDrawPoolAvatar::sSkipTransparent = false;
- }
}
S32 LLDrawPoolAvatar::getNumPasses()
{
- if (LLPipeline::sImpostorRender)
- {
- return 8;
- }
- else
- {
- return 10;
- }
+ return 3;
}
S32 LLDrawPoolAvatar::getNumDeferredPasses()
{
- if (LLPipeline::sImpostorRender)
- {
- return 19;
- }
- else
- {
- return 21;
- }
+ return 3;
}
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 +436,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();
@@ -705,27 +456,6 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
case 2:
beginSkinned();
break;
- case 3:
- beginRiggedSimple();
- break;
- case 4:
- beginRiggedFullbright();
- break;
- case 5:
- beginRiggedShinySimple();
- break;
- case 6:
- beginRiggedFullbrightShiny();
- break;
- case 7:
- beginRiggedAlpha();
- break;
- case 8:
- beginRiggedFullbrightAlpha();
- break;
- case 9:
- beginRiggedGlow();
- break;
}
if (pass == 0)
@@ -736,7 +466,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)
{
@@ -754,43 +484,21 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
case 2:
endSkinned();
break;
- case 3:
- endRiggedSimple();
- break;
- case 4:
- endRiggedFullbright();
- break;
- case 5:
- endRiggedShinySimple();
- break;
- case 6:
- endRiggedFullbrightShiny();
- break;
- case 7:
- endRiggedAlpha();
- break;
- case 8:
- endRiggedFullbrightAlpha();
- break;
- case 9:
- endRiggedGlow();
- break;
}
}
void LLDrawPoolAvatar::beginImpostor()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (!LLPipeline::sReflectionRender)
{
LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f);
LLVOAvatar::sNumVisibleAvatars = 0;
}
- if (LLGLSLShader::sNoFixedFunction)
- {
gImpostorProgram.bind();
gImpostorProgram.setMinimumAlpha(0.01f);
- }
gPipeline.enableLightsFullbright();
sDiffuseChannel = 0;
@@ -798,16 +506,17 @@ void LLDrawPoolAvatar::beginImpostor()
void LLDrawPoolAvatar::endImpostor()
{
- if (LLGLSLShader::sNoFixedFunction)
- {
+ LL_PROFILE_ZONE_SCOPED
+
gImpostorProgram.unbind();
- }
gPipeline.enableLightsDynamic();
}
void LLDrawPoolAvatar::beginRigid()
{
- if (gPipeline.canUseVertexShaders())
+ LL_PROFILE_ZONE_SCOPED
+
+ if (gPipeline.shadersLoaded())
{
if (LLPipeline::sUnderWaterRender)
{
@@ -840,6 +549,8 @@ void LLDrawPoolAvatar::beginRigid()
void LLDrawPoolAvatar::endRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
if (sVertexProgram != NULL)
{
@@ -849,6 +560,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 +578,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 +591,8 @@ void LLDrawPoolAvatar::endDeferredImpostor()
void LLDrawPoolAvatar::beginDeferredRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
@@ -892,6 +609,8 @@ void LLDrawPoolAvatar::beginDeferredRigid()
void LLDrawPoolAvatar::endDeferredRigid()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
@@ -901,6 +620,8 @@ void LLDrawPoolAvatar::endDeferredRigid()
void LLDrawPoolAvatar::beginSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (sShaderLevel > 0)
{
if (LLPipeline::sUnderWaterRender)
@@ -943,7 +664,7 @@ void LLDrawPoolAvatar::beginSkinned()
}
else
{
- if(gPipeline.canUseVertexShaders())
+ if(gPipeline.shadersLoaded())
{
// software skinning, use a basic shader for windlight.
// TODO: find a better fallback method for software skinning.
@@ -959,14 +680,13 @@ void LLDrawPoolAvatar::beginSkinned()
}
}
- if (LLGLSLShader::sNoFixedFunction)
- {
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
- }
}
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)
{
@@ -978,7 +698,7 @@ void LLDrawPoolAvatar::endSkinned()
}
else
{
- if(gPipeline.canUseVertexShaders())
+ if(gPipeline.shadersLoaded())
{
// software skinning, use a basic shader for windlight.
// TODO: find a better fallback method for software skinning.
@@ -989,424 +709,10 @@ void LLDrawPoolAvatar::endSkinned()
gGL.getTexUnit(0)->activate();
}
-void LLDrawPoolAvatar::beginRiggedSimple()
-{
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gSkinnedObjectSimpleWaterProgram;
- }
- else
- {
- sVertexProgram = &gSkinnedObjectSimpleProgram;
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectSimpleNonIndexedWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectSimpleNonIndexedProgram;
- }
- }
-
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sDiffuseChannel = 0;
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
-}
-
-void LLDrawPoolAvatar::endRiggedSimple()
-{
- LLVertexBuffer::unbind();
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sVertexProgram->unbind();
- sVertexProgram = NULL;
- }
-}
-
-void LLDrawPoolAvatar::beginRiggedAlpha()
-{
- beginRiggedSimple();
-}
-
-void LLDrawPoolAvatar::endRiggedAlpha()
-{
- endRiggedSimple();
-}
-
-
-void LLDrawPoolAvatar::beginRiggedFullbrightAlpha()
-{
- beginRiggedFullbright();
-}
-
-void LLDrawPoolAvatar::endRiggedFullbrightAlpha()
-{
- endRiggedFullbright();
-}
-
-void LLDrawPoolAvatar::beginRiggedGlow()
-{
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gSkinnedObjectEmissiveWaterProgram;
- }
- else
- {
- sVertexProgram = &gSkinnedObjectEmissiveProgram;
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectEmissiveNonIndexedWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectEmissiveNonIndexedProgram;
- }
- }
-
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sDiffuseChannel = 0;
- sVertexProgram->bind();
-
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
-
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
- }
-}
-
-void LLDrawPoolAvatar::endRiggedGlow()
-{
- endRiggedFullbright();
-}
-
-void LLDrawPoolAvatar::beginRiggedFullbright()
-{
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gSkinnedObjectFullbrightWaterProgram;
- }
- else
- {
- if (LLPipeline::sRenderDeferred)
- {
- sVertexProgram = &gDeferredSkinnedFullbrightProgram;
- }
- else
- {
- sVertexProgram = &gSkinnedObjectFullbrightProgram;
- }
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectFullbrightNonIndexedWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectFullbrightNonIndexedProgram;
- }
- }
-
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sDiffuseChannel = 0;
- sVertexProgram->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else if (LLPipeline::sRenderDeferred)
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
- }
- else
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
-}
-
-void LLDrawPoolAvatar::endRiggedFullbright()
-{
- LLVertexBuffer::unbind();
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sVertexProgram->unbind();
- sVertexProgram = NULL;
- }
-}
-
-void LLDrawPoolAvatar::beginRiggedShinySimple()
-{
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gSkinnedObjectShinySimpleWaterProgram;
- }
- else
- {
- sVertexProgram = &gSkinnedObjectShinySimpleProgram;
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectShinyNonIndexedWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectShinyNonIndexedProgram;
- }
- }
-
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- }
-}
-
-void LLDrawPoolAvatar::endRiggedShinySimple()
-{
- LLVertexBuffer::unbind();
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- sVertexProgram->unbind();
- sVertexProgram = NULL;
- }
-}
-
-void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
-{
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gSkinnedObjectFullbrightShinyWaterProgram;
- }
- else
- {
- if (LLPipeline::sRenderDeferred)
- {
- sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram;
- }
- else
- {
- sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
- }
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectFullbrightShinyNonIndexedWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectFullbrightShinyNonIndexedProgram;
- }
- }
-
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
-
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else if (LLPipeline::sRenderDeferred)
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- else
- {
- sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
-}
-
-void LLDrawPoolAvatar::endRiggedFullbrightShiny()
-{
- LLVertexBuffer::unbind();
- if (sShaderLevel > 0 || gPipeline.canUseVertexShaders())
- {
- LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
- sVertexProgram->unbind();
- sVertexProgram = NULL;
- }
-}
-
-
-void LLDrawPoolAvatar::beginDeferredRiggedSimple()
-{
- sVertexProgram = &gDeferredSkinnedDiffuseProgram;
- sDiffuseChannel = 0;
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-}
-
-void LLDrawPoolAvatar::endDeferredRiggedSimple()
-{
- LLVertexBuffer::unbind();
- sVertexProgram->unbind();
- sVertexProgram = NULL;
-}
-
-void LLDrawPoolAvatar::beginDeferredRiggedBump()
-{
- sVertexProgram = &gDeferredSkinnedBumpProgram;
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-}
-
-void LLDrawPoolAvatar::endDeferredRiggedBump()
-{
- LLVertexBuffer::unbind();
- sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
- sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sVertexProgram->unbind();
- normal_channel = -1;
- sDiffuseChannel = 0;
- sVertexProgram = NULL;
-}
-
-void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
-{
- if (pass == 1 ||
- pass == 5 ||
- pass == 9 ||
- pass == 13)
- { //skip alpha passes
- return;
- }
- sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
-
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]);
- }
-
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
- sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-}
-
-void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
-{
- if (pass == 1 ||
- pass == 5 ||
- pass == 9 ||
- pass == 13)
- {
- return;
- }
-
- LLVertexBuffer::unbind();
- sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
- sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
- sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sVertexProgram->unbind();
- normal_channel = -1;
- sDiffuseChannel = 0;
- sVertexProgram = NULL;
-}
-
void LLDrawPoolAvatar::beginDeferredSkinned()
{
+ LL_PROFILE_ZONE_SCOPED
+
sShaderLevel = mShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
sRenderingSkinned = TRUE;
@@ -1428,6 +734,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 +747,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 +788,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))
@@ -1565,142 +870,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
- if (pass == 3)
- {
- if (is_deferred_render)
- {
- renderDeferredRiggedSimple(avatarp);
- }
- else
- {
- renderRiggedSimple(avatarp);
-
- if (LLPipeline::sRenderDeferred)
- { //render "simple" materials
- renderRigged(avatarp, RIGGED_MATERIAL);
- renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
- renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
- renderRigged(avatarp, RIGGED_NORMMAP);
- renderRigged(avatarp, RIGGED_NORMMAP_MASK);
- renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
- renderRigged(avatarp, RIGGED_SPECMAP);
- renderRigged(avatarp, RIGGED_SPECMAP_MASK);
- renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
- renderRigged(avatarp, RIGGED_NORMSPEC);
- renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
- renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
- }
- }
- return;
- }
-
- if (pass == 4)
- {
- if (is_deferred_render)
- {
- renderDeferredRiggedBump(avatarp);
- }
- else
- {
- renderRiggedFullbright(avatarp);
- }
-
- return;
- }
-
- if (is_deferred_render && pass >= 5 && pass <= 21)
- {
- S32 p = pass-5;
-
- if (p != 1 &&
- p != 5 &&
- p != 9 &&
- p != 13)
- {
- renderDeferredRiggedMaterial(avatarp, p);
- }
- return;
- }
-
-
-
-
- if (pass == 5)
- {
- renderRiggedShinySimple(avatarp);
-
- return;
- }
-
- if (pass == 6)
- {
- renderRiggedFullbrightShiny(avatarp);
- return;
- }
-
- if (pass >= 7 && pass < 13)
- {
- if (pass == 7)
- {
- renderRiggedAlpha(avatarp);
-
- if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
- { //render transparent materials under water
- LLGLEnable blend(GL_BLEND);
-
- gGL.setColorMask(true, true);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
- LLRender::BF_ZERO,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
- renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
- renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
- renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
- renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
-
- gGL.setColorMask(true, false);
- }
- return;
- }
-
- if (pass == 8)
- {
- renderRiggedFullbrightAlpha(avatarp);
- return;
- }
-
- if (LLPipeline::sRenderDeferred && is_post_deferred_render)
- {
- S32 p = 0;
- switch (pass)
- {
- case 9: p = 1; break;
- case 10: p = 5; break;
- case 11: p = 9; break;
- case 12: p = 13; break;
- }
-
- {
- LLGLEnable blend(GL_BLEND);
- renderDeferredRiggedMaterial(avatarp, p);
- }
- return;
- }
- else if (pass == 9)
- {
- renderRiggedGlow(avatarp);
- return;
- }
- }
-
- if (pass == 13)
- {
- renderRiggedGlow(avatarp);
-
- return;
- }
-
if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
{
LLMatrix4 rot_mat;
@@ -1732,748 +901,15 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
-void LLDrawPoolAvatar::getRiggedGeometry(
- LLFace* face,
- LLPointer<LLVertexBuffer>& buffer,
- U32 data_mask,
- const LLMeshSkinInfo* skin,
- LLVolume* volume,
- const LLVolumeFace& vol_face)
-{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
-
- if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES)
- {
- face->setDrawInfo(NULL);
- }
-
- //rigged faces do not batch textures
- face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES);
-
- if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
- {
- // make a new buffer
- if (sShaderLevel > 0)
- {
- buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
- }
- else
- {
- buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
- }
-
- if (!buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true))
- {
- LL_WARNS("LLDrawPoolAvatar") << "Failed to allocate Vertex Buffer to "
- << vol_face.mNumVertices << " vertices and "
- << vol_face.mNumIndices << " indices" << LL_ENDL;
- // allocate dummy triangle
- buffer->allocateBuffer(1, 3, true);
- memset((U8*)buffer->getMappedData(), 0, buffer->getSize());
- memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize());
- }
- }
- else
- {
- //resize existing buffer
- if(!buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices))
- {
- LL_WARNS("LLDrawPoolAvatar") << "Failed to resize Vertex Buffer to "
- << vol_face.mNumVertices << " vertices and "
- << vol_face.mNumIndices << " indices" << LL_ENDL;
- // allocate dummy triangle
- buffer->resizeBuffer(1, 3);
- memset((U8*)buffer->getMappedData(), 0, buffer->getSize());
- memset((U8*)buffer->getMappedIndices(), 0, buffer->getIndicesSize());
- }
- }
-
- face->setSize(buffer->getNumVerts(), buffer->getNumIndices());
- face->setVertexBuffer(buffer);
-
- U16 offset = 0;
-
- LLMatrix4 mat_vert = skin->mBindShapeMatrix;
- glh::matrix4f m((F32*) mat_vert.mMatrix);
- m = m.inverse().transpose();
-
- F32 mat3[] =
- { m.m[0], m.m[1], m.m[2],
- m.m[4], m.m[5], m.m[6],
- m.m[8], m.m[9], m.m[10] };
-
- LLMatrix3 mat_normal(mat3);
-
- //let getGeometryVolume know if alpha should override shiny
- U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
-
- if (type == LLDrawPool::POOL_ALPHA)
- {
- face->setPoolType(LLDrawPool::POOL_ALPHA);
- }
- else
- {
- face->setPoolType(mType); // either POOL_AVATAR or POOL_CONTROL_AV
- }
-
- //LL_INFOS() << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << LL_ENDL;
-
- // Let getGeometryVolume know if a texture matrix is in play
- if (face->mTextureMatrix)
- {
- face->setState(LLFace::TEXTURE_ANIM);
- }
- else
- {
- face->clearState(LLFace::TEXTURE_ANIM);
- }
- face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
-
- buffer->flush();
-}
-
-void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
- LLVOAvatar* avatar,
- LLFace* face,
- const LLMeshSkinInfo* skin,
- LLVolume* volume,
- LLVolumeFace& vol_face)
-{
- LLVector4a* weights = vol_face.mWeights;
- if (!weights)
- {
- 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
- #define CONDITION_WEIGHT(f) ((U8)llclamp((S32)f, (S32)0, (S32)max_joints-1))
- LLVector4a* just_weights = vol_face.mJustWeights;
- // we need to calculate the separated indices and store just the matrix weights for this vol...
- if (!vol_face.mJointIndices)
- {
- // not very consty after all...
- vol_face.allocateJointIndices(vol_face.mNumVertices);
- just_weights = vol_face.mJustWeights;
-
- U8* joint_indices_cursor = vol_face.mJointIndices;
- for (int i = 0; i < vol_face.mNumVertices; i++)
- {
- F32* w = weights[i].getF32ptr();
- F32* w_ = just_weights[i].getF32ptr();
-
- F32 w0 = floorf(w[0]);
- F32 w1 = floorf(w[1]);
- F32 w2 = floorf(w[2]);
- F32 w3 = floorf(w[3]);
-
- joint_indices_cursor[0] = CONDITION_WEIGHT(w0);
- joint_indices_cursor[1] = CONDITION_WEIGHT(w1);
- joint_indices_cursor[2] = CONDITION_WEIGHT(w2);
- joint_indices_cursor[3] = CONDITION_WEIGHT(w3);
-
- // remove joint portion of combined weight
- w_[0] = w[0] - w0;
- w_[1] = w[1] - w1;
- w_[2] = w[2] - w2;
- w_[3] = w[3] - w3;
-
- joint_indices_cursor += 4;
- }
- }
-#endif
-
- // FIXME ugly const cast
- LLSkinningUtil::scrubInvalidJoints(avatar, const_cast<LLMeshSkinInfo*>(skin));
-
- U32 data_mask = face->getRiggedVertexBufferDataMask();
-
- 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)))
- {
- if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
- {
- //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* facep = drawable->getFace(i);
- U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
- if (face_data_mask)
- {
- LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
- const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
- getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
- }
- }
- drawable->clearState(LLDrawable::REBUILD_ALL);
-
- buffer = face->getVertexBuffer();
- }
- else
- {
- //just rebuild this face
- getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
- }
- }
-
- 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())
- {
- //perform software vertex skinning for this face
- LLStrider<LLVector3> position;
- LLStrider<LLVector3> normal;
-
- bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- buffer->getVertexStrider(position);
-
- if (has_normal)
- {
- buffer->getNormalStrider(normal);
- }
-
- 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;
-
- 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
- {
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
- {
- LLMatrix4a final_mat;
- LLSkinningUtil::getPerVertexSkinMatrix(weights[j].getF32ptr(), mat, false, final_mat, max_joints);
-
- 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;
- }
- }
- }
- }
-}
-
-void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
-{
- if (!avatar->shouldRenderRigged())
- {
- return;
- }
-
- stop_glerror();
-
- for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
- {
- LLFace* face = mRiggedFace[type][i];
-
- S32 offset = face->getIndicesStart();
- U32 count = face->getIndicesCount();
-
- U16 start = face->getGeomStart();
- U16 end = start + face->getGeomCount()-1;
-
- LLDrawable* drawable = face->getDrawable();
- if (!drawable)
- {
- continue;
- }
-
- LLVOVolume* vobj = drawable->getVOVolume();
-
- if (!vobj)
- {
- continue;
- }
-
- LLVolume* volume = vobj->getVolume();
- S32 te = face->getTEOffset();
-
- if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
- {
- 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();
-
- const LLTextureEntry* tex_entry = face->getTextureEntry();
- LLMaterial* mat = tex_entry ? tex_entry->getMaterialParams().get() : nullptr;
-
- if (LLDrawPoolAvatar::sShadowPass >= 0)
- {
- bool is_alpha_blend = false;
- bool is_alpha_mask = false;
-
- LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
- if (tex)
- {
- if (tex->getIsAlphaMask())
- {
- is_alpha_mask = true;
- }
- }
-
- if (tex)
- {
- LLGLenum image_format = tex->getPrimaryFormat();
- if (!is_alpha_mask && (image_format == GL_RGBA || image_format == GL_ALPHA))
- {
- is_alpha_blend = true;
- }
- }
-
- if (tex_entry)
- {
- if (tex_entry->getAlpha() <= 0.99f)
- {
- is_alpha_blend = true;
- }
- }
-
- if (mat)
- {
- switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode()))
- {
- case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
- {
- is_alpha_mask = true;
- is_alpha_blend = false;
- }
- break;
-
- case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
- {
- is_alpha_blend = true;
- is_alpha_mask = false;
- }
- break;
-
- case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
- case LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT:
- case LLMaterial::DIFFUSE_ALPHA_MODE_NONE:
- default:
- is_alpha_blend = false;
- is_alpha_mask = false;
- break;
- }
- }
-
- // if this is alpha mask content and we're doing opaques or a non-alpha-mask shadow pass...
- if (is_alpha_mask && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_MASK))
- {
- return;
- }
-
- // if this is alpha blend content and we're doing opaques or a non-alpha-blend shadow pass...
- if (is_alpha_blend && (LLDrawPoolAvatar::sSkipTransparent || LLDrawPoolAvatar::sShadowPass != SHADOW_PASS_ATTACHMENT_ALPHA_BLEND))
- {
- return;
- }
-
- // if this is opaque content and we're skipping opaques...
- if (!is_alpha_mask && !is_alpha_blend && LLDrawPoolAvatar::sSkipOpaque)
- {
- return;
- }
- }
-
- 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];
-
- mp[idx+8] = m[8];
- mp[idx+9] = m[9];
- mp[idx+10] = m[10];
- mp[idx+11] = m[14];
- }
-
- LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
- count,
- FALSE,
- (GLfloat*) mp);
-
- stop_glerror();
- }
- 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
- //(gGL).mCurrTextureUnitIndex
- LLViewerTexture* specular = NULL;
- if (LLPipeline::sImpostorRender)
- {
- specular = LLViewerTextureManager::findFetchedTexture(gBlackSquareID, TEX_LIST_STANDARD);
- llassert(NULL != specular);
- }
- else
- {
- specular = face->getTexture(LLRender::SPECULAR_MAP);
- }
- if (specular)
- {
- gGL.getTexUnit(specular_channel)->bind(specular);
- }
-
- gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP), false, true);
-
-
- LLColor4 col = mat->getSpecularLightColor();
- F32 spec = mat->getSpecularLightExponent()/255.f;
-
- F32 env = mat->getEnvironmentIntensity()/255.f;
-
- if (mat->getSpecularID().isNull())
- {
- env = tex_entry->getShiny()*0.25f;
- col.set(env,env,env,0);
- spec = env;
- }
-
- BOOL fullbright = tex_entry->getFullbright();
-
- sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
- sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
- sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
-
- if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- {
- F32 cutoff = mat->getAlphaMaskCutoff()/255.f;
- sVertexProgram->setMinimumAlpha(cutoff);
- }
- else
- {
- 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());
- }
- }
- }
- else
- {
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
- sVertexProgram->setMinimumAlpha(0.f);
- if (normal_channel > -1)
- {
- LLDrawPoolBump::bindBumpMap(face, normal_channel);
- }
- }
-
- if (face->mTextureMatrix && vobj->mTexAnimMode)
- {
- U32 tex_index = gGL.getCurrentTexUnitIndex();
-
- if (tex_index <= 1)
- {
- gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
- gGL.pushMatrix();
- gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
- }
-
- buff->setBuffer(data_mask);
- buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
-
- if (tex_index <= 1)
- {
- gGL.matrixMode(LLRender::eMatrixMode(LLRender::MM_TEXTURE0 + tex_index));
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
- }
- else
- {
- buff->setBuffer(data_mask);
- buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- }
-
- gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
- }
- }
-}
-
-void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_DEFERRED_SIMPLE);
-}
-
-void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_DEFERRED_BUMP);
-}
-
-void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
-{
- renderRigged(avatar, pass);
-}
-
static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO");
-void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
-{
- LL_RECORD_BLOCK_TIME(FTM_RIGGED_VBO);
-
- //update rigged vertex buffers
- for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
- {
- for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
- {
- LLFace* face = mRiggedFace[type][i];
- LLDrawable* drawable = face->getDrawable();
- if (!drawable)
- {
- continue;
- }
-
- LLVOVolume* vobj = drawable->getVOVolume();
-
- if (!vobj || vobj->isNoLOD())
- {
- continue;
- }
-
- LLVolume* volume = vobj->getVolume();
- S32 te = face->getTEOffset();
-
- if (!volume || volume->getNumVolumeFaces() <= te)
- {
- continue;
- }
-
- const LLMeshSkinInfo* skin = vobj->getSkinInfo();
- if (!skin)
- {
- continue;
- }
-
- stop_glerror();
-
- LLVolumeFace& vol_face = volume->getVolumeFace(te);
- updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
- }
- }
-}
-
-void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_SIMPLE);
-}
-
-void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_FULLBRIGHT);
-}
-
-
-void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_SHINY);
-}
-
-void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)
-{
- renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY);
-}
-
-void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
-{
- if (!mRiggedFace[RIGGED_ALPHA].empty())
- {
- LLGLEnable blend(GL_BLEND);
-
- gGL.setColorMask(true, true);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
- LLRender::BF_ZERO,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
- renderRigged(avatar, RIGGED_ALPHA);
- gGL.setColorMask(true, false);
- }
-}
-
-void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
-{
- if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty())
- {
- LLGLEnable blend(GL_BLEND);
-
- gGL.setColorMask(true, true);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
- LLRender::BF_ZERO,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
- renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
- gGL.setColorMask(true, false);
- }
-}
-
-void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
-{
- if (!mRiggedFace[RIGGED_GLOW].empty())
- {
- LLGLEnable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.flush();
-
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- gGL.setSceneBlendType(LLRender::BT_ADD);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.setColorMask(false, true);
-
- renderRigged(avatar, RIGGED_GLOW, true);
-
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
-}
-
-
-
//-----------------------------------------------------------------------------
// getDebugTexture()
//-----------------------------------------------------------------------------
LLViewerTexture *LLDrawPoolAvatar::getDebugTexture()
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mReferences.empty())
{
return NULL;
@@ -2495,68 +931,12 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
return LLColor3(0.f, 1.f, 0.f);
}
-void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type)
-{
- llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
- if (facep->getPool() && facep->getPool() != this)
- {
- LL_ERRS() << "adding rigged face that's already in another pool" << LL_ENDL;
- }
- if (type >= NUM_RIGGED_PASSES)
- {
- LL_ERRS() << "Invalid rigged face type." << LL_ENDL;
- }
- if (facep->getRiggedIndex(type) != -1)
- {
- LL_ERRS() << "Tried to add a rigged face that's referenced elsewhere." << LL_ENDL;
- }
-
- facep->setRiggedIndex(type, mRiggedFace[type].size());
- facep->setPool(this);
- mRiggedFace[type].push_back(facep);
-}
-
-void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
-{
- llassert (facep->isState(LLFace::RIGGED));
- llassert(getType() == LLDrawPool::POOL_AVATAR || getType() == LLDrawPool::POOL_CONTROL_AV);
- if (facep->getPool() != this)
- {
- LL_ERRS() << "Tried to remove a rigged face from the wrong pool" << LL_ENDL;
- }
- facep->setPool(NULL);
-
- for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
- {
- S32 index = facep->getRiggedIndex(i);
-
- if (index > -1)
- {
- if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep)
- {
- facep->setRiggedIndex(i,-1);
- mRiggedFace[i].erase(mRiggedFace[i].begin()+index);
- for (U32 j = index; j < mRiggedFace[i].size(); ++j)
- { //bump indexes down for faces referenced after erased face
- mRiggedFace[i][j]->setRiggedIndex(i, j);
- }
- }
- else
- {
- LL_ERRS() << "Face reference data corrupt for rigged type " << i
- << ((mRiggedFace[i].size() <= index) ? "; wrong index (out of bounds)" : (mRiggedFace[i][index] != facep) ? "; wrong face pointer" : "")
- << LL_ENDL;
- }
- }
- }
-}
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..21add39b21 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
{
@@ -58,119 +62,11 @@ public:
~LLDrawPoolAvatar();
/*virtual*/ BOOL isDead();
- typedef enum
- {
- RIGGED_MATERIAL=0,
- RIGGED_MATERIAL_ALPHA,
- RIGGED_MATERIAL_ALPHA_MASK,
- RIGGED_MATERIAL_ALPHA_EMISSIVE,
- RIGGED_SPECMAP,
- RIGGED_SPECMAP_BLEND,
- RIGGED_SPECMAP_MASK,
- RIGGED_SPECMAP_EMISSIVE,
- RIGGED_NORMMAP,
- RIGGED_NORMMAP_BLEND,
- RIGGED_NORMMAP_MASK,
- RIGGED_NORMMAP_EMISSIVE,
- RIGGED_NORMSPEC,
- RIGGED_NORMSPEC_BLEND,
- RIGGED_NORMSPEC_MASK,
- RIGGED_NORMSPEC_EMISSIVE,
- RIGGED_SIMPLE,
- RIGGED_FULLBRIGHT,
- RIGGED_SHINY,
- RIGGED_FULLBRIGHT_SHINY,
- RIGGED_GLOW,
- RIGGED_ALPHA,
- RIGGED_FULLBRIGHT_ALPHA,
- RIGGED_DEFERRED_BUMP,
- RIGGED_DEFERRED_SIMPLE,
- NUM_RIGGED_PASSES,
- RIGGED_UNKNOWN,
- } eRiggedPass;
-
- typedef enum
- {
- RIGGED_MATERIAL_MASK =
- LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK,
- RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK,
- RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK,
- RIGGED_SPECMAP_VMASK =
- LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TEXCOORD2 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK,
- RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK,
- RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK,
- RIGGED_NORMMAP_VMASK =
- LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TANGENT |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TEXCOORD1 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK,
- RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK,
- RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK,
- RIGGED_NORMSPEC_VMASK =
- LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TANGENT |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TEXCOORD1 |
- LLVertexBuffer::MAP_TEXCOORD2 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK,
- RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK,
- RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,
- RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_FULLBRIGHT_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_SHINY_MASK = RIGGED_SIMPLE_MASK,
- RIGGED_FULLBRIGHT_SHINY_MASK = RIGGED_SIMPLE_MASK,
- RIGGED_GLOW_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_EMISSIVE |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_ALPHA_MASK = RIGGED_SIMPLE_MASK,
- RIGGED_FULLBRIGHT_ALPHA_MASK = RIGGED_FULLBRIGHT_MASK,
- RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TANGENT |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4,
- } eRiggedDataMask;
-
typedef enum
{
SHADOW_PASS_AVATAR_OPAQUE,
SHADOW_PASS_AVATAR_ALPHA_BLEND,
SHADOW_PASS_AVATAR_ALPHA_MASK,
- SHADOW_PASS_ATTACHMENT_ALPHA_BLEND,
- SHADOW_PASS_ATTACHMENT_ALPHA_MASK,
- SHADOW_PASS_ATTACHMENT_OPAQUE,
NUM_SHADOW_PASSES
} eShadowPass;
@@ -211,78 +107,19 @@ typedef enum
void endImpostor();
void endSkinned();
- void beginDeferredImpostor();
- void beginDeferredRigid();
- void beginDeferredSkinned();
-
- void endDeferredImpostor();
- void endDeferredRigid();
- void endDeferredSkinned();
-
- void beginPostDeferredAlpha();
- void endPostDeferredAlpha();
-
- void beginRiggedSimple();
- void beginRiggedFullbright();
- void beginRiggedFullbrightShiny();
- void beginRiggedShinySimple();
- void beginRiggedAlpha();
- void beginRiggedFullbrightAlpha();
- void beginRiggedGlow();
- void beginDeferredRiggedAlpha();
- void beginDeferredRiggedMaterial(S32 pass);
- void beginDeferredRiggedMaterialAlpha(S32 pass);
+ void beginDeferredRigid();
+ void beginDeferredImpostor();
+ void beginDeferredSkinned();
- void endRiggedSimple();
- void endRiggedFullbright();
- void endRiggedFullbrightShiny();
- void endRiggedShinySimple();
- void endRiggedAlpha();
- void endRiggedFullbrightAlpha();
- void endRiggedGlow();
- void endDeferredRiggedAlpha();
- void endDeferredRiggedMaterial(S32 pass);
- void endDeferredRiggedMaterialAlpha(S32 pass);
-
- void beginDeferredRiggedSimple();
- void beginDeferredRiggedBump();
-
- void endDeferredRiggedSimple();
- void endDeferredRiggedBump();
-
- 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,
- LLVolume* volume,
- LLVolumeFace& vol_face);
- void updateRiggedVertexBuffers(LLVOAvatar* avatar);
-
- void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false);
- void renderRiggedSimple(LLVOAvatar* avatar);
- void renderRiggedAlpha(LLVOAvatar* avatar);
- void renderRiggedFullbrightAlpha(LLVOAvatar* avatar);
- void renderRiggedFullbright(LLVOAvatar* avatar);
- void renderRiggedShinySimple(LLVOAvatar* avatar);
- void renderRiggedFullbrightShiny(LLVOAvatar* avatar);
- void renderRiggedGlow(LLVOAvatar* avatar);
- void renderDeferredRiggedSimple(LLVOAvatar* avatar);
- void renderDeferredRiggedBump(LLVOAvatar* avatar);
- void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
-
-
-
- void addRiggedFace(LLFace* facep, U32 type);
- void removeRiggedFace(LLFace* facep);
-
- std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES];
+ void endDeferredRigid();
+ void endDeferredImpostor();
+ void endDeferredSkinned();
/*virtual*/ LLViewerTexture *getDebugTexture();
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null.
-
static BOOL sSkipOpaque;
static BOOL sSkipTransparent;
static S32 sShadowPass;
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 14069fa6c2..b01450bba9 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -47,6 +47,7 @@
#include "pipeline.h"
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
+#include "llmodel.h"
//#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h"
@@ -199,32 +200,7 @@ void LLDrawPoolBump::prerender()
// static
S32 LLDrawPoolBump::numBumpPasses()
{
- if (gSavedSettings.getBOOL("RenderObjectBump"))
- {
- if (mShaderLevel > 1)
- {
- if (LLPipeline::sImpostorRender)
- {
- return 2;
- }
- else
- {
- return 3;
- }
- }
- else if (LLPipeline::sImpostorRender)
- {
- return 1;
- }
- else
- {
- return 2;
- }
- }
- else
- {
- return 0;
- }
+ return 1;
}
S32 LLDrawPoolBump::getNumPasses()
@@ -232,140 +208,79 @@ S32 LLDrawPoolBump::getNumPasses()
return numBumpPasses();
}
-void LLDrawPoolBump::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- switch( pass )
- {
- case 0:
- beginShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- beginFullbrightShiny();
- }
- else
- {
- beginBump();
- }
- break;
- case 2:
- beginBump();
- break;
- default:
- llassert(0);
- break;
- }
-}
-
void LLDrawPoolBump::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-
- if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
- {
- return;
- }
-
- switch( pass )
- {
- case 0:
- renderShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- renderFullbrightShiny();
- }
- else
- {
- renderBump();
- }
- break;
- case 2:
- renderBump();
- break;
- default:
- llassert(0);
- break;
- }
-}
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-void LLDrawPoolBump::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- switch( pass )
- {
- case 0:
- endShiny();
- break;
- case 1:
- if (mShaderLevel > 1)
- {
- endFullbrightShiny();
- }
- else
- {
- endBump();
- }
- break;
- case 2:
- endBump();
- break;
- default:
- llassert(0);
- break;
- }
+ if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
+ {
+ return;
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ mRigged = i == 1;
+
+ // first pass -- shiny
+ beginShiny();
+ renderShiny();
+ endShiny();
- //to cleanup texture channels
- LLRenderPass::endRenderPass(pass);
+ //second pass -- fullbright shiny
+ if (mShaderLevel > 1)
+ {
+ beginFullbrightShiny();
+ renderFullbrightShiny();
+ endFullbrightShiny();
+ }
+
+ //third pass -- bump
+ beginBump();
+ renderBump(LLRenderPass::PASS_BUMP);
+ endBump();
+ }
}
+
//static
-void LLDrawPoolBump::beginShiny(bool invisible)
+void LLDrawPoolBump::beginShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
-
+
mShiny = TRUE;
sVertexMask = VERTEX_MASK_SHINY;
// Second pass: environment map
- if (!invisible && mShaderLevel > 1)
+ if (mShaderLevel > 1)
{
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
}
- if (getShaderLevel() > 0)
+ if (LLPipeline::sUnderWaterRender)
{
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectShinyWaterProgram;
- }
- else
- {
- shader = &gObjectShinyProgram;
- }
- shader->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ shader = &gObjectShinyWaterProgram;
}
else
{
- shader = NULL;
+ shader = &gObjectShinyProgram;
}
- bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
+
+ shader->bind();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
+
+ bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
if (mShaderLevel > 1)
{ //indexed texture rendering, channel 0 is always diffuse
@@ -374,12 +289,12 @@ void LLDrawPoolBump::beginShiny(bool invisible)
}
//static
-void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- if (!invisible && shader )
+ if (shader )
{
LLMatrix4 mat;
mat.initRows(LLVector4(gGLModelView+0),
@@ -391,19 +306,16 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
if (shader_level > 1)
{
- cube_map->setMatrix(1);
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
cube_map->enableTexture(cube_channel);
- cube_map->enableTextureCoords(1);
diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
else
{
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
diffuse_channel = -1;
- cube_map->setMatrix(0);
cube_map->enable(cube_channel);
}
gGL.getTexUnit(cube_channel)->bind(cube_map);
@@ -415,49 +327,50 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
diffuse_channel = -1;
gGL.getTexUnit(0)->disable();
cube_map->enable(0);
- cube_map->setMatrix(0);
gGL.getTexUnit(0)->bind(cube_map);
-
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_VERT_ALPHA);
}
}
}
-void LLDrawPoolBump::renderShiny(bool invisible)
+void LLDrawPoolBump::renderShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
-
+
if( gSky.mVOSkyp->getCubeMap() )
{
LLGLEnable blend_enable(GL_BLEND);
- if (!invisible && mShaderLevel > 1)
+ if (mShaderLevel > 1)
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
}
- else if (!invisible)
+ else
{
- renderGroups(LLRenderPass::PASS_SHINY, sVertexMask);
+ if (mRigged)
+ {
+ gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE);
+ }
+ else
+ {
+ gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE);
+ }
}
- //else // invisible (deprecated)
- //{
- //renderGroups(LLRenderPass::PASS_INVISI_SHINY, sVertexMask);
- //}
}
}
//static
-void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible)
+void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
- if (!invisible && shader_level > 1)
+ if (shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -472,29 +385,14 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
// Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
// MAINT-755
cube_map->disable();
- cube_map->restoreMatrix();
- }
-
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.getTexUnit(diffuse_channel)->disable();
- gGL.getTexUnit(cube_channel)->disable();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
}
-void LLDrawPoolBump::endShiny(bool invisible)
+void LLDrawPoolBump::endShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))||
- (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)))
- {
- return;
- }
- unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible);
+ unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
if (shader)
{
shader->unbind();
@@ -508,11 +406,7 @@ void LLDrawPoolBump::endShiny(bool invisible)
void LLDrawPoolBump::beginFullbrightShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
-
+
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
// Second pass: environment map
@@ -533,6 +427,12 @@ void LLDrawPoolBump::beginFullbrightShiny()
}
}
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
+
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
@@ -553,15 +453,13 @@ void LLDrawPoolBump::beginFullbrightShiny()
LLVector3 vec = LLVector3(gShinyOrigin) * mat;
LLVector4 vec4(vec, gShinyOrigin.mV[3]);
- shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
+ shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
- cube_map->setMatrix(1);
// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
// the cube map in the one pass shiny shaders
gGL.getTexUnit(1)->disable();
cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
cube_map->enableTexture(cube_channel);
- cube_map->enableTextureCoords(1);
diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(cube_channel)->bind(cube_map);
@@ -579,10 +477,6 @@ void LLDrawPoolBump::beginFullbrightShiny()
void LLDrawPoolBump::renderFullbrightShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
if( gSky.mVOSkyp->getCubeMap() )
{
@@ -590,11 +484,25 @@ void LLDrawPoolBump::renderFullbrightShiny()
if (mShaderLevel > 1)
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ }
}
else
{
- LLRenderPass::renderTexture(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask);
+ if (mRigged)
+ {
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask);
+ }
+ else
+ {
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask);
+ }
}
}
}
@@ -602,31 +510,14 @@ void LLDrawPoolBump::renderFullbrightShiny()
void LLDrawPoolBump::endFullbrightShiny()
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY))
- {
- return;
- }
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
cube_map->disable();
- cube_map->restoreMatrix();
-
- /*if (diffuse_channel != 0)
- {
- shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);*/
-
shader->unbind();
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
- //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
diffuse_channel = -1;
cube_channel = 0;
mShiny = FALSE;
@@ -677,6 +568,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 +585,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 +601,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;
@@ -724,53 +617,22 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
}
//static
-void LLDrawPoolBump::beginBump(U32 pass)
+void LLDrawPoolBump::beginBump()
{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
-
sVertexMask = VERTEX_MASK_BUMP;
LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
// Optional second pass: emboss bump map
stop_glerror();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectBumpProgram.bind();
- }
- else
- {
- // TEXTURE UNIT 0
- // Output.rgb = texture at texture coord 0
- gGL.getTexUnit(0)->activate();
-
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
+ shader = &gObjectBumpProgram;
- // TEXTURE UNIT 1
- gGL.getTexUnit(1)->activate();
-
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ if (mRigged)
+ {
+ llassert(shader->mRiggedVariant);
+ shader = shader->mRiggedVariant;
+ }
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
- // src = tex0 + (1 - tex1) - 0.5
- // = (bump0/2 + 0.5) + (1 - (bump1/2 + 0.5)) - 0.5
- // = (1 + bump0 - bump1) / 2
-
-
- // Blend: src * dst + dst * src
- // = 2 * src * dst
- // = 2 * ((1 + bump0 - bump1) / 2) * dst [0 - 2 * dst]
- // = (1 + bump0 - bump1) * dst.rgb
- // = dst.rgb + dst.rgb * (bump0 - bump1)
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ shader->bind();
gGL.setSceneBlendType(LLRender::BT_MULT_X2);
stop_glerror();
@@ -779,11 +641,6 @@ void LLDrawPoolBump::beginBump(U32 pass)
//static
void LLDrawPoolBump::renderBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
-
LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
LLGLDisable fog(GL_FOG);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
@@ -798,28 +655,9 @@ void LLDrawPoolBump::renderBump(U32 pass)
//static
void LLDrawPoolBump::endBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(pass))
- {
- return;
- }
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectBumpProgram.unbind();
- }
- else
- {
- // Disable texture blending on unit 1
- gGL.getTexUnit(1)->activate();
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+ gObjectBumpProgram.unbind();
- // Disable texture blending on unit 0
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
-
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
S32 LLDrawPoolBump::getNumDeferredPasses()
@@ -834,101 +672,81 @@ S32 LLDrawPoolBump::getNumDeferredPasses()
}
}
-void LLDrawPoolBump::beginDeferredPass(S32 pass)
-{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- mShiny = TRUE;
- gDeferredBumpProgram.bind();
- diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP);
- gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
-}
-
-void LLDrawPoolBump::endDeferredPass(S32 pass)
-{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- mShiny = FALSE;
- gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP);
- gDeferredBumpProgram.unbind();
- gGL.getTexUnit(0)->activate();
-}
-
void LLDrawPoolBump::renderDeferred(S32 pass)
{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
- {
- return;
- }
LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- U32 type = LLRenderPass::PASS_BUMP;
- LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+ mShiny = TRUE;
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = i == 1;
+ gDeferredBumpProgram.bind(rigged);
+ diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
-
- for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
- {
- LLDrawInfo& params = **i;
+ U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP;
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- gDeferredBumpProgram.setMinimumAlpha(params.mAlphaMaskCutoff);
- LLDrawPoolBump::bindBumpMap(params, bump_channel);
- pushBatch(params, mask, TRUE);
- }
-}
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
-void LLDrawPoolBump::beginPostDeferredPass(S32 pass)
-{
- switch (pass)
- {
- case 0:
- beginFullbrightShiny();
- break;
- case 1:
- beginBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
-}
+ LLVOAvatar* avatar = nullptr;
+ U64 skin = 0;
-void LLDrawPoolBump::endPostDeferredPass(S32 pass)
-{
- switch (pass)
- {
- case 0:
- endFullbrightShiny();
- break;
- case 1:
- endBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ {
+ LLDrawInfo& params = **i;
+
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
+ LLDrawPoolBump::bindBumpMap(params, bump_channel);
+
+ if (rigged)
+ {
+ if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(params);
+ avatar = params.mAvatar;
+ skin = params.mSkinInfo->mHash;
+ }
+ pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE);
+ }
+ else
+ {
+ pushBatch(params, mask, TRUE, FALSE);
+ }
+ }
- //to disable texture channels
- LLRenderPass::endRenderPass(pass);
+ LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+ LLGLSLShader::sCurBoundShaderPtr->unbind();
+ gGL.getTexUnit(0)->activate();
+ }
+
+ mShiny = FALSE;
}
+
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
- switch (pass)
- {
- case 0:
- renderFullbrightShiny();
- break;
- case 1:
- renderBump(LLRenderPass::PASS_POST_BUMP);
- break;
- }
+ for (int i = 0; i < 2; ++i)
+ { // two passes -- static and rigged
+ mRigged = (i == 1);
+
+ // render shiny
+ beginFullbrightShiny();
+ renderFullbrightShiny();
+ endFullbrightShiny();
+
+ //render bump
+ beginBump();
+ renderBump(LLRenderPass::PASS_POST_BUMP);
+ endBump();
+ }
}
+
////////////////////////////////////////////////////////////////
// List of bump-maps created from other textures.
@@ -1061,6 +879,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 +932,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 +955,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 +1026,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 +1080,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 +1105,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 +1137,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 +1172,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 +1182,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);
@@ -1481,8 +1278,17 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
void LLDrawPoolBump::renderBump(U32 type, U32 mask)
{
- LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
+ LLVOAvatar* avatar = nullptr;
+ U64 skin = 0;
+
+ if (mRigged)
+ { // nudge type enum and include skinweights for rigged pass
+ type += 1;
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
@@ -1490,6 +1296,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
if (LLDrawPoolBump::bindBumpMap(params))
{
+ if (mRigged)
+ {
+ if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash)
+ {
+ if (uploadMatrixPalette(params))
+ {
+ avatar = params.mAvatar;
+ skin = params.mSkinInfo->mHash;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
pushBatch(params, mask, FALSE);
}
}
@@ -1497,6 +1318,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 +1329,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 +1344,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 +1360,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 +1373,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 +1384,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);
}
@@ -1588,7 +1396,7 @@ void LLDrawPoolInvisible::render(S32 pass)
{ //render invisiprims
LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
- if (gPipeline.canUseVertexShaders())
+ if (gPipeline.shadersLoaded())
{
gOcclusionProgram.bind();
}
@@ -1600,48 +1408,8 @@ void LLDrawPoolInvisible::render(S32 pass)
gGL.setColorMask(true, false);
glStencilMask(0xFFFFFFFF);
- if (gPipeline.canUseVertexShaders())
+ if (gPipeline.shadersLoaded())
{
gOcclusionProgram.unbind();
}
-
- if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
- {
- beginShiny(true);
- renderShiny(true);
- endShiny(true);
- }
-}
-
-void LLDrawPoolInvisible::beginDeferredPass(S32 pass)
-{
- beginRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::endDeferredPass( S32 pass )
-{
- endRenderPass(pass);
-}
-
-void LLDrawPoolInvisible::renderDeferred( S32 pass )
-{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff
-#if 0
- LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
-
- U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
- glStencilMask(0);
- glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE);
- gGL.setColorMask(false, false);
- pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
- gGL.setColorMask(true, true);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- glStencilMask(0xFFFFFFFF);
-
- if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))
- {
- beginShiny(true);
- renderShiny(true);
- endShiny(true);
- }
-#endif
}
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 476b1d41b7..38744a7d98 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;
@@ -46,52 +48,47 @@ public:
static U32 sVertexMask;
BOOL mShiny;
- virtual U32 getVertexDataMask() { return sVertexMask; }
+ virtual U32 getVertexDataMask() override { return sVertexMask; }
LLDrawPoolBump();
- virtual void render(S32 pass = 0);
- virtual void beginRenderPass( S32 pass );
- virtual void endRenderPass( S32 pass );
- virtual S32 getNumPasses();
- /*virtual*/ void prerender();
- /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+ virtual void render(S32 pass = 0) override;
+ virtual S32 getNumPasses() override;
+ /*virtual*/ void prerender() override;
+ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override;
void renderBump(U32 type, U32 mask);
- void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture);
+ void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) override;
S32 numBumpPasses();
- void beginShiny(bool invisible = false);
- void renderShiny(bool invisible = false);
- void endShiny(bool invisible = false);
+ void beginShiny();
+ void renderShiny();
+ void endShiny();
void beginFullbrightShiny();
void renderFullbrightShiny();
void endFullbrightShiny();
- void beginBump(U32 pass = LLRenderPass::PASS_BUMP);
+ void beginBump();
void renderBump(U32 pass = LLRenderPass::PASS_BUMP);
void endBump(U32 pass = LLRenderPass::PASS_BUMP);
- static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
- static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible);
+ static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel);
+ static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel);
- virtual S32 getNumDeferredPasses();
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
+ virtual S32 getNumDeferredPasses() override;
+ /*virtual*/ void renderDeferred(S32 pass) override;
- virtual S32 getNumPostDeferredPasses() { return 2; }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
- /*virtual*/ void renderPostDeferred(S32 pass);
+ virtual S32 getNumPostDeferredPasses() override { return 1; }
+ /*virtual*/ void renderPostDeferred(S32 pass) override;
static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2);
static BOOL bindBumpMap(LLFace* face, S32 channel = -2);
private:
static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel);
+ bool mRigged = false; // if true, doing a rigged pass
};
@@ -161,17 +158,17 @@ 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;
};
extern LLBumpImageList gBumpImageList;
-class LLDrawPoolInvisible : public LLDrawPoolBump
+class LLDrawPoolInvisible : public LLRenderPass
{
public:
- LLDrawPoolInvisible() : LLDrawPoolBump(LLDrawPool::POOL_INVISIBLE) { }
+ LLDrawPoolInvisible() : LLRenderPass(LLDrawPool::POOL_INVISIBLE) { }
enum
{
@@ -186,11 +183,6 @@ public:
virtual void beginRenderPass( S32 pass ) { }
virtual void endRenderPass( S32 pass ) { }
virtual S32 getNumPasses() {return 1;}
-
- virtual S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
};
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 05b0c1f1a9..fd5850084b 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -31,6 +31,7 @@
#include "llviewershadermgr.h"
#include "pipeline.h"
#include "llglcommonfunc.h"
+#include "llvoavatar.h"
S32 diffuse_channel = -1;
@@ -47,11 +48,18 @@ void LLDrawPoolMaterials::prerender()
S32 LLDrawPoolMaterials::getNumDeferredPasses()
{
- return 12;
+ // 12 render passes times 2 (one for each rigged and non rigged)
+ return 12*2;
}
void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
{
+ bool rigged = false;
+ if (pass >= 12)
+ {
+ rigged = true;
+ pass -= 12;
+ }
U32 shader_idx[] =
{
0, //LLRenderPass::PASS_MATERIAL,
@@ -72,13 +80,22 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
15, //LLRenderPass::PASS_NORMSPEC_GLOW,
};
- mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
-
- if (LLPipeline::sUnderWaterRender)
- {
- mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
- }
-
+ U32 idx = shader_idx[pass];
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ mShader = &(gDeferredMaterialWaterProgram[idx]);
+ }
+ else
+ {
+ mShader = &(gDeferredMaterialProgram[idx]);
+ }
+
+ if (rigged)
+ {
+ llassert(mShader->mRiggedVariant != nullptr);
+ mShader = mShader->mRiggedVariant;
+ }
mShader->bind();
if (LLPipeline::sRenderingHUDs)
@@ -106,6 +123,7 @@ void LLDrawPoolMaterials::endDeferredPass(S32 pass)
void LLDrawPoolMaterials::renderDeferred(S32 pass)
{
+ LL_PROFILE_ZONE_SCOPED;
static const U32 type_list[] =
{
LLRenderPass::PASS_MATERIAL,
@@ -126,9 +144,20 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
+ bool rigged = false;
+ if (pass >= 12)
+ {
+ rigged = true;
+ pass -= 12;
+ }
+
llassert(pass < sizeof(type_list)/sizeof(U32));
U32 type = type_list[pass];
+ if (rigged)
+ {
+ type += 1;
+ }
U32 mask = mShader->mAttributeMask;
@@ -157,7 +186,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, rigged);
+ }
}
}
@@ -171,49 +203,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, bool rigged)
{
+ 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())
{
- 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)->bindFast(params.mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
}
}
@@ -222,11 +242,29 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
params.mGroup->rebuildMesh();
}
+ // upload matrix palette to shader
+ if (rigged)
+ {
+ const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo);
+ U32 count = mpc.mMatrixPalette.size();
+
+ if (count == 0)
+ {
+ //skin info not loaded yet, don't render
+ return;
+ }
+
+ mShader->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
+ FALSE,
+ (GLfloat*)&(mpc.mGLMp[0]));
+ }
+
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..8a3ad923df 100644
--- a/indra/newview/lldrawpoolmaterials.h
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -55,21 +55,21 @@ public:
LLVertexBuffer::MAP_TANGENT
};
- /*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
- /*virtual*/ void render(S32 pass = 0) { }
- /*virtual*/ S32 getNumPasses() {return 0;}
- /*virtual*/ void prerender();
+ void render(S32 pass = 0) override { }
+ S32 getNumPasses() override {return 0;}
+ void prerender() override;
- /*virtual*/ S32 getNumDeferredPasses();
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
+ S32 getNumDeferredPasses() override;
+ void beginDeferredPass(S32 pass) override;
+ void endDeferredPass(S32 pass) override;
+ void renderDeferred(S32 pass) override;
void bindSpecularMap(LLViewerTexture* tex);
void bindNormalMap(LLViewerTexture* tex);
- /*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+ void pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged);
};
#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index f211cf6e27..4ada753355 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -38,71 +38,54 @@
#include "llrender.h"
static LLGLSLShader* simple_shader = NULL;
-static LLGLSLShader* fullbright_shader = NULL;
static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");
static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
-void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
+
+static void setup_simple_shader(LLGLSLShader* shader)
{
- gDeferredEmissiveProgram.bind();
- gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ shader->bind();
+
if (LLPipeline::sRenderingHUDs)
- {
- gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredEmissiveProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ }
+ else
+ {
+ shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ }
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW_PUSH("Glow Push");
-
-void LLDrawPoolGlow::renderPostDeferred(S32 pass)
+static void setup_glow_shader(LLGLSLShader* shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
- LLGLEnable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.flush();
- /// Get rid of z-fighting with non-glow pass.
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- gGL.setSceneBlendType(LLRender::BT_ADD);
-
- 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);
- }
-
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ setup_simple_shader(shader);
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sRenderingHUDs)
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
+ }
}
-void LLDrawPoolGlow::endPostDeferredPass(S32 pass)
+static void setup_fullbright_shader(LLGLSLShader* shader)
{
- gDeferredEmissiveProgram.unbind();
- LLRenderPass::endRenderPass(pass);
+ setup_glow_shader(shader);
+ shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
}
-S32 LLDrawPoolGlow::getNumPasses()
+
+void LLDrawPoolGlow::renderPostDeferred(S32 pass)
{
- if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
- {
- return 1;
- }
- else
- {
- return 0;
- }
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
+ render(&gDeferredEmissiveProgram);
}
-void LLDrawPoolGlow::render(S32 pass)
+void LLDrawPoolGlow::render(LLGLSLShader* shader)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
LLGLEnable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
gGL.flush();
@@ -111,51 +94,33 @@ void LLDrawPoolGlow::render(S32 pass)
glPolygonOffset(-1.0f, -1.0f);
gGL.setSceneBlendType(LLRender::BT_ADD);
- U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-
- //should never get here without basic shaders enabled
- llassert(shader_level > 0);
-
- LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- shader->bind();
- if (LLPipeline::sRenderDeferred)
- {
- shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- }
- else
- {
- shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
- }
-
- if (LLPipeline::sRenderingHUDs)
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
- pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- if (shader_level > 0 && fullbright_shader)
- {
- shader->unbind();
- }
+ //first pass -- static objects
+ setup_glow_shader(shader);
+ pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+
+ // second pass -- rigged objects
+ shader = shader->mRiggedVariant;
+ setup_glow_shader(shader);
+ pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+
+ gGL.setColorMask(true, false);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
-void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+S32 LLDrawPoolGlow::getNumPasses()
{
- //gGL.diffuseColor4ubv(params.mGlowColor.mV);
- LLRenderPass::pushBatch(params, mask, texture, batch_textures);
+ return 1;
}
+void LLDrawPoolGlow::render(S32 pass)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
+ render(shader);
+}
LLDrawPoolSimple::LLDrawPoolSimple() :
LLRenderPass(POOL_SIMPLE)
@@ -167,100 +132,73 @@ void LLDrawPoolSimple::prerender()
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-void LLDrawPoolSimple::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
-
- if (LLPipeline::sImpostorRender)
- {
- simple_shader = &gObjectSimpleImpostorProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectSimpleWaterProgram;
- }
- else
- {
- simple_shader = &gObjectSimpleProgram;
- }
-
- if (mShaderLevel > 0)
- {
- simple_shader->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- else
- {
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
- }
-}
-
-void LLDrawPoolSimple::endRenderPass(S32 pass)
+S32 LLDrawPoolSimple::getNumPasses()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
- stop_glerror();
- LLRenderPass::endRenderPass(pass);
- stop_glerror();
- if (mShaderLevel > 0)
- {
- simple_shader->unbind();
- }
+ return 1;
}
void LLDrawPoolSimple::render(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
+
LLGLDisable blend(GL_BLEND);
+ LLGLSLShader* shader = nullptr;
+ if (LLPipeline::sImpostorRender)
+ {
+ shader = &gObjectSimpleImpostorProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gObjectSimpleWaterProgram;
+ }
+ else
+ {
+ shader = &gObjectSimpleProgram;
+ }
+
{ //render simple
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
+
gPipeline.enableLightsDynamic();
- if (mShaderLevel > 0)
- {
- U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
-
- pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE);
-
- if (LLPipeline::sRenderDeferred)
- { //if deferred rendering is enabled, bump faces aren't registered as simple
- //render bump faces here as simple so bump faces will appear under water
- pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
- }
- }
- else
- {
- LLGLDisable alpha_test(GL_ALPHA_TEST);
- renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
- }
-
+ U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
+
+ // first pass -- static objects
+ {
+ setup_simple_shader(shader);
+ pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE);
+
+ if (LLPipeline::sRenderDeferred)
+ { //if deferred rendering is enabled, bump faces aren't registered as simple
+ //render bump faces here as simple so bump faces will appear under water
+ pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
+ }
+ }
+
+ //second pass, rigged
+ {
+ shader = shader->mRiggedVariant;
+ setup_simple_shader(shader);
+ pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE);
+
+ if (LLPipeline::sRenderDeferred)
+ { //if deferred rendering is enabled, bump faces aren't registered as simple
+ //render bump faces here as simple so bump faces will appear under water
+ pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, mask, TRUE, TRUE);
+ }
+ }
}
}
-
-
-
-
-
-
-
-
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask");
LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
@@ -273,85 +211,36 @@ void LLDrawPoolAlphaMask::prerender()
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-
- if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
- }
- else
- {
- simple_shader = &gObjectSimpleAlphaMaskProgram;
- }
-
- if (mShaderLevel > 0)
- {
- simple_shader->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- else
- {
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
- }
-}
-
-void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- stop_glerror();
- LLRenderPass::endRenderPass(pass);
- stop_glerror();
- if (mShaderLevel > 0)
- {
- simple_shader->unbind();
- }
-}
-
void LLDrawPoolAlphaMask::render(S32 pass)
{
LLGLDisable blend(GL_BLEND);
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
+ LL_PROFILE_ZONE_SCOPED;
- if (mShaderLevel > 0)
- {
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.33f);
+ LLGLSLShader* shader = nullptr;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gObjectSimpleWaterAlphaMaskProgram;
+ }
+ else
+ {
+ shader = &gObjectSimpleAlphaMaskProgram;
+ }
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ // render static
+ setup_simple_shader(shader);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
- else
- {
- LLGLEnable test(GL_ALPHA_TEST);
- pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
+ // render rigged
+ setup_simple_shader(shader->mRiggedVariant);
+ pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
@@ -364,166 +253,70 @@ void LLDrawPoolFullbrightAlphaMask::prerender()
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
+void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectFullbrightWaterAlphaMaskProgram;
- }
- else
- {
- simple_shader = &gObjectFullbrightAlphaMaskProgram;
- }
-
- if (mShaderLevel > 0)
- {
- simple_shader->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- else
- {
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
- }
-}
-
-void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
- stop_glerror();
- LLRenderPass::endRenderPass(pass);
- stop_glerror();
- if (mShaderLevel > 0)
- {
- simple_shader->unbind();
- }
-}
+ LLGLSLShader* shader = nullptr;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gObjectFullbrightWaterAlphaMaskProgram;
+ }
+ else
+ {
+ shader = &gObjectFullbrightAlphaMaskProgram;
+ }
-void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
+ // render static
+ setup_fullbright_shader(shader);
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- if (mShaderLevel > 0)
- {
- if (simple_shader)
- {
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.33f);
-
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- if (LLPipeline::sRenderDeferred)
- {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- }
- else
- {
- simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- }
- }
- }
- pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- //LLGLSLShader::bindNoShader();
- }
- else
- {
- LLGLEnable test(GL_ALPHA_TEST);
- gPipeline.enableLightsFullbright();
- pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
- gPipeline.enableLightsDynamic();
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
- }
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
//===============================
//DEFERRED IMPLEMENTATION
//===============================
-void LLDrawPoolSimple::beginDeferredPass(S32 pass)
+S32 LLDrawPoolSimple::getNumDeferredPasses()
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
- gDeferredDiffuseProgram.bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredDiffuseProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-}
-
-void LLDrawPoolSimple::endDeferredPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
- LLRenderPass::endRenderPass(pass);
-
- gDeferredDiffuseProgram.unbind();
+ return 1;
}
void LLDrawPoolSimple::renderDeferred(S32 pass)
{
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
LLGLDisable blend(GL_BLEND);
LLGLDisable alpha_test(GL_ALPHA_TEST);
- { //render simple
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
- pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
+ //render static
+ setup_simple_shader(&gDeferredDiffuseProgram);
+ pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+
+ //render rigged
+ setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant);
+ pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
-void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
-{
-
-}
void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED);
- gDeferredDiffuseAlphaMaskProgram.bind();
- gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
+ LLGLSLShader* shader = &gDeferredDiffuseAlphaMaskProgram;
- if (LLPipeline::sRenderingHUDs)
- {
- gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ //render static
+ setup_simple_shader(shader);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- gDeferredDiffuseAlphaMaskProgram.unbind();
+ //render rigged
+ setup_simple_shader(shader->mRiggedVariant);
+ pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
-
// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
LLRenderPass(POOL_GRASS)
@@ -566,12 +359,8 @@ void LLDrawPoolGrass::beginRenderPass(S32 pass)
}
else
{
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- LLGLSLShader::bindNoShader();
- }
+ gGL.flush();
+ LLGLSLShader::bindNoShader();
}
}
@@ -586,7 +375,7 @@ void LLDrawPoolGrass::endRenderPass(S32 pass)
}
else
{
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
}
@@ -599,7 +388,7 @@ void LLDrawPoolGrass::render(S32 pass)
LLGLEnable test(GL_ALPHA_TEST);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//render grass
- LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
+ LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());
}
}
@@ -630,7 +419,7 @@ void LLDrawPoolGrass::renderDeferred(S32 pass)
}
//render grass
- LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask());
+ LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());
}
}
@@ -646,77 +435,31 @@ void LLDrawPoolFullbright::prerender()
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
-void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
-{
- if (LLPipeline::sUnderWaterRender)
- {
- gDeferredFullbrightWaterProgram.bind();
- }
- else
- {
- gDeferredFullbrightProgram.bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredFullbrightProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
-
-}
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
-
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
- pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
-}
-void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
-{
- if (LLPipeline::sUnderWaterRender)
- {
- gDeferredFullbrightWaterProgram.unbind();
- }
- else
- {
- gDeferredFullbrightProgram.unbind();
- }
- LLRenderPass::endRenderPass(pass);
-}
-
-void LLDrawPoolFullbright::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
-
- if (LLPipeline::sUnderWaterRender)
- {
- fullbright_shader = &gObjectFullbrightWaterProgram;
- }
- else
- {
- fullbright_shader = &gObjectFullbrightProgram;
- }
-}
-
-void LLDrawPoolFullbright::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
- LLRenderPass::endRenderPass(pass);
-
- stop_glerror();
-
- if (mShaderLevel > 0)
- {
- fullbright_shader->unbind();
- }
+ LLGLSLShader* shader = nullptr;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gDeferredFullbrightWaterProgram;
+ }
+ else
+ {
+ shader = &gDeferredFullbrightProgram;
+ }
- stop_glerror();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
+
+ // render static
+ setup_fullbright_shader(shader);
+ pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE);
}
void LLDrawPoolFullbright::render(S32 pass)
@@ -725,41 +468,34 @@ void LLDrawPoolFullbright::render(S32 pass)
gGL.setSceneBlendType(LLRender::BT_ALPHA);
stop_glerror();
+ LLGLSLShader* shader = nullptr;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gObjectFullbrightWaterProgram;
+ }
+ else
+ {
+ shader = &gObjectFullbrightProgram;
+ }
- if (mShaderLevel > 0)
- {
- fullbright_shader->bind();
- fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
- fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
- if (LLPipeline::sRenderingHUDs)
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
- U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
- pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
- }
- else
- {
- gPipeline.enableLightsFullbright();
- U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
- renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
- pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
- pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask);
- pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask);
- pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);
- }
-
- stop_glerror();
+ // render static
+ setup_fullbright_shader(shader);
+ pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE);
+
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE);
}
S32 LLDrawPoolFullbright::getNumPasses()
@@ -767,65 +503,40 @@ S32 LLDrawPoolFullbright::getNumPasses()
return 1;
}
-
-void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
+void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
{
-
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
+
+ LLGLSLShader* shader = nullptr;
if (LLPipeline::sRenderingHUDs)
{
- gObjectFullbrightAlphaMaskProgram.bind();
- gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
+ shader = &gObjectFullbrightAlphaMaskProgram;
}
- else if (LLPipeline::sRenderDeferred)
- {
+ else if (LLPipeline::sRenderDeferred)
+ {
if (LLPipeline::sUnderWaterRender)
- {
- gDeferredFullbrightAlphaMaskWaterProgram.bind();
- gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredFullbrightAlphaMaskProgram.bind();
- gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
- gDeferredFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
+ {
+ shader = &gDeferredFullbrightAlphaMaskWaterProgram;
+ }
+ else
+ {
+ shader = &gDeferredFullbrightAlphaMaskProgram;
+ }
}
else
{
- gObjectFullbrightAlphaMaskProgram.bind();
- gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
- gObjectFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-}
+ shader = &gObjectFullbrightAlphaMaskProgram;
+ }
-void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
LLGLDisable blend(GL_BLEND);
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
- pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+
+ // render static
+ setup_fullbright_shader(shader);
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE);
}
-void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
-{
- if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
- {
- gObjectFullbrightAlphaMaskProgram.unbind();
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- gDeferredFullbrightAlphaMaskWaterProgram.unbind();
- }
- else
- {
- gDeferredFullbrightAlphaMaskProgram.unbind();
- }
- }
- LLRenderPass::endRenderPass(pass);
-}
-
-
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index 608ad9e1eb..cccbe5e495 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -29,6 +29,8 @@
#include "lldrawpool.h"
+class LLGLSLShader;
+
class LLDrawPoolSimple : public LLRenderPass
{
public:
@@ -39,22 +41,17 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolSimple();
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
+ S32 getNumDeferredPasses() override;
+ void renderDeferred(S32 pass) override;
- /*virtual*/ void beginRenderPass(S32 pass);
- /*virtual*/ void endRenderPass(S32 pass);
/// We need two passes so we can handle emissive materials separately.
- /*virtual*/ S32 getNumPasses() { return 1; }
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
-
+ S32 getNumPasses() override;
+ void render(S32 pass = 0) override;
+ void prerender() override;
};
class LLDrawPoolGrass : public LLRenderPass
@@ -99,13 +96,9 @@ public:
LLDrawPoolAlphaMask();
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
/*virtual*/ S32 getNumPasses() { return 1; }
- /*virtual*/ void beginRenderPass(S32 pass);
- /*virtual*/ void endRenderPass(S32 pass);
/*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
@@ -125,13 +118,9 @@ public:
LLDrawPoolFullbrightAlphaMask();
/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
/*virtual*/ S32 getNumPasses() { return 1; }
- /*virtual*/ void beginRenderPass(S32 pass);
- /*virtual*/ void endRenderPass(S32 pass);
/*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
};
@@ -151,12 +140,8 @@ public:
LLDrawPoolFullbright();
/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
- /*virtual*/ void beginRenderPass(S32 pass);
- /*virtual*/ void endRenderPass(S32 pass);
/*virtual*/ S32 getNumPasses();
/*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
@@ -180,14 +165,13 @@ public:
virtual void prerender() { }
/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
+ void render(LLGLSLShader* shader);
+
/*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..3a1efec91b 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -76,22 +76,8 @@ void LLDrawPoolSky::render(S32 pass)
}
- if (LLGLSLShader::sNoFixedFunction)
- { //just use the UI shader (generic single texture no lighting)
- gOneTextureNoColorProgram.bind();
- }
- else
- {
- // don't use shaders!
- if (gGLManager.mHasShaderObjects)
- {
- // Ironically, we must support shader objects to be
- // able to use this call.
- LLGLSLShader::bindNoShader();
- }
- mShader = NULL;
- }
-
+ //just use the UI shader (generic single texture no lighting)
+ gOneTextureNoColorProgram.bind();
LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 37dc80e2b7..adea1909a3 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
//
@@ -469,8 +467,6 @@ void LLDrawPoolTerrain::renderFull4TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
-
//
// Stage 1: Generate alpha ramp for detail0/detail1 transition
//
@@ -479,10 +475,6 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(1)->activate();
- // Care about alpha only
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
//
// Stage 2: Interpolate detail1 with existing based on ramp
//
@@ -497,8 +489,6 @@ void LLDrawPoolTerrain::renderFull4TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(2)->setTextureColorBlend(LLTexUnit::TBO_LERP_PREV_ALPHA, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_TEX_COLOR);
-
//
// Stage 3: Modulate with primary (vertex) color for lighting
//
@@ -506,9 +496,6 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(3)->activate();
- // Set alpha texture and do lighting modulation
- gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
-
gGL.getTexUnit(0)->activate();
// GL_BLEND disabled by default
@@ -529,8 +516,6 @@ void LLDrawPoolTerrain::renderFull4TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
-
//
// Stage 1: Generate alpha ramp for detail2/detail3 transition
//
@@ -543,10 +528,6 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.loadIdentity();
gGL.translatef(-2.f, 0.f, 0.f);
- // Care about alpha only
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
//
// Stage 2: Interpolate detail2 with existing based on ramp
//
@@ -561,8 +542,6 @@ void LLDrawPoolTerrain::renderFull4TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(2)->setTextureColorBlend(LLTexUnit::TBO_LERP_PREV_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
-
//
// Stage 3: Generate alpha ramp for detail1/detail2 transition
//
@@ -576,10 +555,6 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.translatef(-1.f, 0.f, 0.f);
gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Set alpha texture and do lighting modulation
- gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
- gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
@@ -629,8 +604,6 @@ void LLDrawPoolTerrain::renderFull4TU()
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolTerrain::renderFull2TU()
@@ -669,8 +642,6 @@ void LLDrawPoolTerrain::renderFull2TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
-
drawLoop();
//----------------------------------------------------------------------------
@@ -684,11 +655,6 @@ void LLDrawPoolTerrain::renderFull2TU()
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
- // Care about alpha only
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
-
//
// Stage 1: Write detail1
//
@@ -703,9 +669,6 @@ void LLDrawPoolTerrain::renderFull2TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
@@ -725,10 +688,6 @@ void LLDrawPoolTerrain::renderFull2TU()
gGL.translatef(-1.f, 0.f, 0.f);
gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Care about alpha only
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
//
// Stage 1: Write detail2
//
@@ -743,9 +702,6 @@ void LLDrawPoolTerrain::renderFull2TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
{
LLGLEnable blend(GL_BLEND);
drawLoop();
@@ -765,10 +721,6 @@ void LLDrawPoolTerrain::renderFull2TU()
gGL.translatef(-2.f, 0.f, 0.f);
gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Care about alpha only
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
-
// Stage 1: Write detail3
gGL.getTexUnit(1)->bind(detail_texture3p);
gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
@@ -781,9 +733,6 @@ void LLDrawPoolTerrain::renderFull2TU()
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
gGL.getTexUnit(0)->activate();
{
LLGLEnable blend(GL_BLEND);
@@ -816,7 +765,6 @@ void LLDrawPoolTerrain::renderFull2TU()
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
@@ -839,22 +787,8 @@ void LLDrawPoolTerrain::renderSimple()
tp0.setVec(tscale, 0.f, 0.0f, -1.f*(origin_agent.mV[0]/256.f));
tp1.setVec(0.f, tscale, 0.0f, -1.f*(origin_agent.mV[1]/256.f));
- if (LLGLSLShader::sNoFixedFunction)
- {
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
- sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
- }
- else
- {
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0.mV);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1.mV);
- }
-
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV);
+ sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);
drawLoop();
@@ -863,15 +797,9 @@ void LLDrawPoolTerrain::renderSimple()
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- }
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
//============================================================================
@@ -922,6 +850,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..facfb235c9 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),
@@ -69,7 +68,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
shader = &gTreeProgram;
}
- if (gPipeline.canUseVertexShaders())
+ if (gPipeline.shadersLoaded())
{
shader->bind();
shader->setMinimumAlpha(0.5f);
@@ -78,23 +77,24 @@ void LLDrawPoolTree::beginRenderPass(S32 pass)
else
{
gPipeline.enableLightsDynamic();
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
+ gGL.flush();
}
}
void LLDrawPoolTree::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);
+ LL_PROFILE_ZONE_SCOPED;
if (mDrawFace.empty())
{
return;
}
- LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1);
+ LLGLState test(GL_ALPHA_TEST, 0);
+
+ gGL.getTexUnit(sDiffTex)->bindFast(mTexturep);
+ gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res
- gGL.getTexUnit(sDiffTex)->bind(mTexturep);
-
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
iter != mDrawFace.end(); iter++)
{
@@ -117,9 +117,8 @@ void LLDrawPoolTree::render(S32 pass)
gPipeline.mMatrixOpCount++;
}
- buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
- buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
- gPipeline.addTrianglesDrawn(buff->getNumIndices());
+ buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK);
+ buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
}
}
}
@@ -135,7 +134,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
if (mShaderLevel <= 0)
{
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
}
@@ -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..62706feae3 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -50,8 +50,6 @@
#include "llsettingssky.h"
#include "llsettingswater.h"
-static float sTime;
-
BOOL deferred_render = FALSE;
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
@@ -137,8 +135,16 @@ 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();
+ renderWater();
deferred_render = FALSE;
}
@@ -174,7 +180,7 @@ void LLDrawPoolWater::render(S32 pass)
if ((mShaderLevel > 0) && !sSkipScreenCopy)
{
- shade();
+ renderWater();
return;
}
@@ -233,9 +239,6 @@ void LLDrawPoolWater::render(S32 pass)
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
gGL.getTexUnit(0)->activate();
glClearStencil(1);
@@ -293,8 +296,6 @@ void LLDrawPoolWater::render(S32 pass)
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
iter != mDrawFace.end(); iter++)
{
@@ -311,8 +312,6 @@ void LLDrawPoolWater::render(S32 pass)
}
}
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
gSky.mVOSkyp->getCubeMap()->disable();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -330,29 +329,30 @@ void LLDrawPoolWater::render(S32 pass)
glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
renderReflection(refl_face);
}
-
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
// 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)
+ if (LLPipeline::sUnderWaterRender)
{
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
- }
- else
- {
- shader = &gObjectSimpleNonIndexedTexGenProgram;
- }
-
- shader->bind();
+ shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
}
+ else
+ {
+ shader = &gObjectSimpleNonIndexedTexGenProgram;
+ }
+
+ shader->bind();
stop_glerror();
@@ -438,12 +438,12 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolWater::renderReflection(LLFace* face)
{
+ LL_PROFILE_ZONE_SCOPED;
LLVOSky *voskyp = gSky.mVOSkyp;
if (!voskyp)
@@ -470,330 +470,245 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
face->renderIndexed();
}
-void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
+void LLDrawPoolWater::renderWater()
{
- F32 water_height = LLEnvironment::instance().getWaterHeight();
- F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
- F32 eyedepth = camera_height - water_height;
- bool underwater = eyedepth <= 0.0f;
-
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
-
- shader->bind();
-
-// bind textures for water rendering
- if (deferred_render)
- {
- if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
- {
- glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
- shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
- }
- }
-
- LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor());
- shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
+ LL_PROFILE_ZONE_SCOPED;
+ if (!deferred_render)
+ {
+ gGL.setColorMask(true, true);
+ }
- sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
-
- S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
-
- if (reftex > -1)
- {
- gGL.getTexUnit(reftex)->activate();
- gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
- gGL.getTexUnit(0)->activate();
- }
+ LLGLDisable blend(GL_BLEND);
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ LLColor3 light_diffuse(0, 0, 0);
+ F32 light_exp = 0.0f;
- LLViewerTexture* tex_a = mWaterNormp[0];
- LLViewerTexture* tex_b = mWaterNormp[1];
+ LLEnvironment & environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+ LLVector3 light_dir = environment.getLightDirection();
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal");
+ bool underwater = LLViewerCamera::getInstance()->cameraUnderWater();
- F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
-
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
+ if (sun_up)
{
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
+ light_diffuse += psky->getSunlightColor();
}
- else if (tex_b != tex_a)
+ // moonlight is several orders of magnitude less bright than sunlight,
+ // so only use this color when the moon alone is showing
+ else if (moon_up)
{
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ light_diffuse += psky->getMoonlightColor();
}
-
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
- F32 screenRes[] =
- {
- 1.f/gGLViewport[2],
- 1.f/gGLViewport[3]
- };
-
- S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
- stop_glerror();
-
-// set uniforms for water rendering
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
-
- LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
-
- if (mShaderLevel == 1)
+ // Apply magic numbers translating light direction into intensities
+ light_dir.normalize();
+ F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1];
+ light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f));
+ if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling...
{
- //F32 fog_density_slider_value = param_mgr->mDensitySliderValue;
- //sWaterFogColor.mV[3] = fog_density_slider_value;
- fog_color.mV[VW] = log(fog_density) / log(2);
- }
-
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ light_diffuse *= (1.5f + (6.f * ground_proj_sq));
+ }
- //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
- shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
- if (LLEnvironment::instance().isCloudScrollPaused())
+ // set up normal maps filtering
+ for (auto norm_map : mWaterNormp)
{
- static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} };
-
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
+ if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
}
- else
+
+ LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
+ F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
+ bool edge = false;
+ LLGLSLShader *shader = nullptr;
+ do // twice through, once with normal shader bound & once with edge shader bound
{
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
- }
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+ // select shader
+ if (underwater && LLPipeline::sWaterReflections)
+ {
+ shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
+ }
+ else
+ {
+ if (edge && !deferred_render)
+ {
+ shader = &gWaterEdgeProgram;
+ }
+ else
+ {
+ shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram;
+ }
+ }
+ shader->bind();
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+ // bind textures for water rendering
+ S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
+ if (reftex > -1)
+ {
+ gGL.getTexUnit(reftex)->activate();
+ gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
+ gGL.getTexUnit(0)->activate();
+ }
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ // bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+ LLViewerTexture *tex_a = mWaterNormp[0];
+ LLViewerTexture *tex_b = mWaterNormp[1];
- LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ F32 blend_factor = pwater->getBlendFactor();
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
-
- {
- LLGLDisable cullface(GL_CULL_FACE);
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- if (edge)
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
{
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (face)
- {
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- if (water)
- {
- bool edge_patch = water->getIsEdgePatch();
- if (edge_patch)
- {
- //sNeedsReflectionUpdate = TRUE;
- face->renderIndexed();
- }
- }
- }
- }
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ blend_factor = 0; // only one tex provided, no blending
}
- else
+ else if (tex_b && !tex_a)
{
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (face)
- {
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- if (water)
- {
- bool edge_patch = water->getIsEdgePatch();
- if (!edge_patch)
- {
- sNeedsReflectionUpdate = TRUE;
- sNeedsDistortionUpdate = TRUE;
- face->renderIndexed();
- }
- }
- }
- }
+ gGL.getTexUnit(bumpTex)->bind(tex_b);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ gGL.getTexUnit(bumpTex2)->bind(tex_b);
}
- }
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->unbind();
-}
+ // set uniforms for shader
+ if (deferred_render)
+ {
+ if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
+ {
+ glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
+ shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
+ }
+ }
-void LLDrawPoolWater::shade()
-{
- if (!deferred_render)
- {
- gGL.setColorMask(true, true);
- }
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- if(voskyp == NULL)
- {
- return;
- }
+ if (screentex > -1)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
- LLGLDisable blend(GL_BLEND);
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
- LLColor3 light_diffuse(0,0,0);
- F32 light_exp = 0.0f;
- LLVector3 light_dir;
+ F32 water_height = environment.getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+ shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
- light_dir = environment.getLightDirection();
- light_dir.normalize();
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+ shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ {
+ static const std::array<F32, 2> zerowave {{0.0f, 0.0f}};
- bool sun_up = environment.getIsSunUp();
- bool moon_up = environment.getIsMoonUp();
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
+ }
+ else
+ {
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ }
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- if (sun_up)
- {
- light_diffuse += voskyp->getSun().getColorCached();
- }
- // moonlight is several orders of magnitude less bright than sunlight,
- // so only use this color when the moon alone is showing
- else if (moon_up)
- {
- light_diffuse += psky->getMoonDiffuse();
- }
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
- light_diffuse.normalize();
- light_diffuse *= (light_exp + 0.25f);
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
+ shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= 256.f;
- light_exp = light_exp > 32.f ? light_exp : 32.f;
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- light_diffuse *= 6.f;
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
- LLGLSLShader* shader = nullptr;
- LLGLSLShader* edge_shader = nullptr;
+ LLGLDisable cullface(GL_CULL_FACE);
- F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight();
-
- if (eyedepth < 0.f && LLPipeline::sWaterReflections)
- {
- if (deferred_render)
- {
- shader = &gDeferredUnderWaterProgram;
- }
- else
+ LLVOWater *water = nullptr;
+ for (LLFace *const &face : mDrawFace)
{
- shader = &gUnderWaterProgram;
- }
- }
- else if (deferred_render)
- {
- shader = &gDeferredWaterProgram;
- edge_shader = nullptr;
- }
- else
- {
- shader = &gWaterProgram;
- edge_shader = &gWaterEdgeProgram;
- }
+ if (!face) continue;
+ water = static_cast<LLVOWater *>(face->getViewerObject());
+ if (!water) continue;
- if (mWaterNormp[0])
- {
- if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- {
- mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- }
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
- if (mWaterNormp[1])
- {
- if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- {
- mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- }
+ if (edge == (bool) water->getIsEdgePatch())
+ {
+ face->renderIndexed();
+
+ // Note non-void water being drawn, updates required
+ if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
+ {
+ sNeedsReflectionUpdate = TRUE;
+ sNeedsDistortionUpdate = TRUE;
+ }
+ }
+ }
- shade2(false, shader, light_diffuse, light_dir, light_exp);
- shade2(true, edge_shader ? edge_shader : shader, light_diffuse, light_dir, light_exp);
+ shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
+ shader->disableTexture(LLShaderMgr::BUMP_MAP);
+ shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!deferred_render)
- {
- gGL.setColorMask(true, false);
- }
+ // clean up
+ shader->unbind();
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+
+ edge = !edge;
+ } while (!edge);
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ if (!deferred_render)
+ {
+ gGL.setColorMask(true, false);
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index a5d163e0d7..6f2fc3271d 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -78,8 +78,7 @@ public:
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderReflection(LLFace* face);
- void shade();
- void shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp);
+ void renderWater();
void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId);
void setOpaqueTexture(const LLUUID& opaqueTextureId);
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 0c3d8f3098..80a65947f6 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();
@@ -268,33 +266,14 @@ void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
gGL.pushMatrix();
gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gCustomAlphaProgram.bind();
- gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
- }
- else
- {
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
- gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV);
- }
+ gCustomAlphaProgram.bind();
+ gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
gSky.mVOWLSkyp->drawStars();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
gGL.popMatrix();
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- gCustomAlphaProgram.unbind();
- }
- else
- {
- // and disable the combiner states
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
+ gCustomAlphaProgram.unbind();
}
void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
@@ -406,8 +385,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 +439,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);
@@ -485,7 +460,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
F32 blend_factor = LLEnvironment::instance().getCurrentSky()->getBlendFactor();
- bool can_use_vertex_shaders = gPipeline.canUseVertexShaders();
+ bool can_use_vertex_shaders = gPipeline.shadersLoaded();
bool can_use_windlight_shaders = gPipeline.canUseWindLightShaders();
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 8b8273d183..63e7887d81 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -119,10 +119,13 @@ 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)
+ if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -209,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsATI;
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
if (use_fbo)
{
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..4bec7fa111 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,6 @@ std::string env_selection_to_string(LLEnvironment::EnvSelection_t sel)
#undef RTNENUM
}
-
//-------------------------------------------------------------------------
LLEnvironment::LLEnvironment():
mCloudScrollDelta(),
@@ -879,6 +877,7 @@ void LLEnvironment::cleanupSingleton()
LLEnvironment::~LLEnvironment()
{
+ cleanupSingleton();
}
bool LLEnvironment::canEdit() const
@@ -1471,6 +1470,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 +1488,8 @@ void LLEnvironment::updateEnvironment(LLSettingsBase::Seconds transition, bool f
{
mCurrentEnvironment = pinstance;
}
+
+ updateSettingsUniforms();
}
}
@@ -1614,6 +1616,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 +1652,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 +1704,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 +1717,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 +2657,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..54a043482b 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -56,6 +56,7 @@
#include "llviewertexture.h"
#include "llvoavatar.h"
#include "llsculptidsize.h"
+#include "llmeshrepository.h"
#if LL_LINUX
// Work-around spurious used before init warning on Vector4a
@@ -71,6 +72,7 @@ static LLStaticHashedString sColorIn("color_in");
BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
+
#define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
/*
@@ -127,6 +129,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;
@@ -196,14 +199,7 @@ void LLFace::destroy()
if (mDrawPoolp)
{
- if (this->isState(LLFace::RIGGED) && (mDrawPoolp->getType() == LLDrawPool::POOL_CONTROL_AV || mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR))
- {
- ((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this);
- }
- else
- {
- mDrawPoolp->removeFace(this);
- }
+ mDrawPoolp->removeFace(this);
mDrawPoolp = NULL;
}
@@ -241,6 +237,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 +318,8 @@ void LLFace::setSpecularMap(LLViewerTexture* tex)
void LLFace::dirtyTexture()
{
+ LL_PROFILE_ZONE_SCOPED
+
LLDrawable* drawablep = getDrawable();
if (mVObjp.notNull() && mVObjp->getVolume())
@@ -535,6 +535,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 +587,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 +608,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)
{
@@ -648,7 +653,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
glFogfv(GL_FOG_COLOR, fogCol.mV);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
{
gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
renderFace(mDrawablep, this);
@@ -891,6 +896,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 +1202,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 +1267,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) {
@@ -1304,7 +1281,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
return FALSE;
}
- const LLVolumeFace &vf = volume.getVolumeFace(f);
+ bool rigged = isState(RIGGED);
+
+ const LLVolumeFace &vf = volume.getVolumeFace(f);
S32 num_vertices = (S32)vf.mNumVertices;
S32 num_indices = (S32) vf.mNumIndices;
@@ -1437,7 +1416,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 +1432,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)
@@ -1468,9 +1447,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- LLMatrix4a mat_normal;
- mat_normal.loadu(mat_norm_in);
-
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
bool do_xform = false;
if (rebuild_tcoord)
@@ -1505,6 +1481,45 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
+ const LLMeshSkinInfo* skin = nullptr;
+ LLMatrix4a mat_vert;
+ LLMatrix4a mat_normal;
+
+ // prepare mat_vert
+ if (rebuild_pos)
+ {
+ if (rigged)
+ { //override with bind shape matrix if rigged
+ skin = mSkinInfo;
+ mat_vert = skin->mBindShapeMatrix;
+ }
+ else
+ {
+ mat_vert.loadu(mat_vert_in);
+ }
+ }
+
+ if (rebuild_normal || rebuild_tangent)
+ { //override mat_normal with inverse of skin->mBindShapeMatrix
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - norm mat override");
+ if (rigged)
+ {
+ if (skin == nullptr)
+ {
+ skin = mSkinInfo;
+ }
+
+ //TODO -- cache this (check profile marker above)?
+ glh::matrix4f m((F32*) skin->mBindShapeMatrix.getF32ptr());
+ m = m.inverse().transpose();
+ mat_normal.loadu(m.m);
+ }
+ else
+ {
+ mat_normal.loadu(mat_norm_in);
+ }
+ }
+
static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
@@ -1516,7 +1531,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 +1550,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 +1575,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 +1591,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 +1612,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 +1625,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 +1638,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 +1677,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 );
@@ -1757,7 +1773,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
do_xform = false;
}
- if (getVirtualSize() >= MIN_TEX_ANIM_SIZE || isState(LLFace::RIGGED))
+ if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
{ //don't override texture transform during tc bake
tex_mode = 0;
}
@@ -1784,18 +1800,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 +1851,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 +1862,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 +1907,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,14 +2065,11 @@ 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);
- LLMatrix4a mat_vert;
- mat_vert.loadu(mat_vert_in);
-
+
F32* dst = (F32*) vert.get();
F32* end_f32 = dst+mGeomCount*4;
@@ -2088,53 +2099,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)
@@ -2143,10 +2120,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
-
if (rebuild_normal)
{
- //LL_RECORD_TIME_BLOCK(FTM_FACE_GEOM_NORMAL);
+ LL_PROFILE_ZONE_NAMED("getGeometryVolume - normal");
+
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
F32* normals = (F32*) norm.get();
LLVector4a* src = vf.mNormals;
@@ -2168,7 +2145,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 +2178,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 +2190,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 +2221,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 +2352,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 +2633,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 +2654,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 +2666,8 @@ S32 LLFace::renderIndexed()
S32 LLFace::renderIndexed(U32 mask)
{
+ LL_PROFILE_ZONE_SCOPED
+
if (mVertexBuffer.isNull())
{
return 0;
@@ -2760,56 +2745,6 @@ void LLFace::clearVertexBuffer()
mVertexBuffer = NULL;
}
-//static
-U32 LLFace::getRiggedDataMask(U32 type)
-{
- static const U32 rigged_data_mask[] = {
- LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
- LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
- LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
- LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
- LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
- LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
- LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
- LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
- LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
- LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
- LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
- LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
- LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
- LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
- LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
- LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
- LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
- LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
- LLDrawPoolAvatar::RIGGED_SHINY_MASK,
- LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY_MASK,
- LLDrawPoolAvatar::RIGGED_GLOW_MASK,
- LLDrawPoolAvatar::RIGGED_ALPHA_MASK,
- LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA_MASK,
- LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP_MASK,
- LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE_MASK,
- };
-
- llassert(type < sizeof(rigged_data_mask)/sizeof(U32));
-
- return rigged_data_mask[type];
-}
-
-U32 LLFace::getRiggedVertexBufferDataMask() const
-{
- U32 data_mask = 0;
- for (U32 i = 0; i < mRiggedIndex.size(); ++i)
- {
- if (mRiggedIndex[i] > -1)
- {
- data_mask |= LLFace::getRiggedDataMask(i);
- }
- }
-
- return data_mask;
-}
-
S32 LLFace::getRiggedIndex(U32 type) const
{
if (mRiggedIndex.empty())
@@ -2822,19 +2757,7 @@ S32 LLFace::getRiggedIndex(U32 type) const
return mRiggedIndex[type];
}
-void LLFace::setRiggedIndex(U32 type, S32 index)
+U64 LLFace::getSkinHash()
{
- if (mRiggedIndex.empty())
- {
- mRiggedIndex.resize(LLDrawPoolAvatar::NUM_RIGGED_PASSES);
- for (U32 i = 0; i < mRiggedIndex.size(); ++i)
- {
- mRiggedIndex[i] = -1;
- }
- }
-
- llassert(type < mRiggedIndex.size());
-
- mRiggedIndex[type] = index;
+ return mSkinInfo ? mSkinInfo->mHash : 0;
}
-
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 3611539ff8..79f50f2273 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -47,18 +47,18 @@ class LLTextureEntry;
class LLVertexProgram;
class LLViewerTexture;
class LLGeometryManager;
-class LLTextureAtlasSlot;
class LLDrawInfo;
+class LLMeshSkinInfo;
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(); }
@@ -228,11 +228,7 @@ public:
void setVertexBuffer(LLVertexBuffer* buffer);
void clearVertexBuffer(); //sets mVertexBuffer to NULL
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
- U32 getRiggedVertexBufferDataMask() const;
S32 getRiggedIndex(U32 type) const;
- void setRiggedIndex(U32 type, S32 index);
-
- static U32 getRiggedDataMask(U32 type);
void notifyAboutCreatingTexture(LLViewerTexture *texture);
void notifyAboutMissingAsset(LLViewerTexture *texture);
@@ -261,6 +257,11 @@ public:
LLMatrix4* mSpecMapMatrix;
LLMatrix4* mNormalMapMatrix;
LLDrawInfo* mDrawInfo;
+ LLVOAvatar* mAvatar = nullptr;
+ LLMeshSkinInfo* mSkinInfo = nullptr;
+
+ // return mSkinInfo->mHash or 0 if mSkinInfo is null
+ U64 getSkinHash();
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
@@ -271,10 +272,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..3240f169b3 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -520,7 +520,6 @@ void LLFeatureManager::initSingleton()
void LLFeatureManager::applyRecommendedSettings()
{
- loadGPUClass();
// apply saved settings
// cap the level at 2 (high)
U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
@@ -607,22 +606,6 @@ void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
// if we're passed an invalid level, default to "Low"
std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
- if (features == "Low")
- {
-#if LL_DARWIN
- // This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
- // systems which support them instead of falling back to fixed-function unnecessarily
- // MAINT-2157
- if (gGLManager.mGLVersion < 2.1f)
-#else
- // only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
- if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
-#endif
- {
- // same as Low, but with "Basic Shaders" disabled
- features = "LowFixedFunction";
- }
- }
maskFeatures(features);
@@ -670,46 +653,18 @@ void LLFeatureManager::applyBaseMasks()
}
// now all those wacky ones
- if (!gGLManager.mHasFragmentShader)
- {
- maskFeatures("NoPixelShaders");
- }
- if (!gGLManager.mHasVertexShader || !mGPUSupported)
- {
- maskFeatures("NoVertexShaders");
- }
if (gGLManager.mIsNVIDIA)
{
maskFeatures("NVIDIA");
}
- if (gGLManager.mIsGF2or4MX)
- {
- maskFeatures("GeForce2");
- }
- if (gGLManager.mIsATI)
- {
- maskFeatures("ATI");
- }
- if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256)
+ if (gGLManager.mIsAMD)
{
- maskFeatures("ATIVramLT256");
- }
- if (gGLManager.mATIOldDriver)
- {
- maskFeatures("ATIOldDriver");
- }
- if (gGLManager.mIsGFFX)
- {
- maskFeatures("GeForceFX");
+ maskFeatures("AMD");
}
if (gGLManager.mIsIntel)
{
maskFeatures("Intel");
}
- if (gGLManager.mGLVersion < 1.5f)
- {
- maskFeatures("OpenGLPre15");
- }
if (gGLManager.mGLVersion < 3.f)
{
maskFeatures("OpenGLPre30");
@@ -749,17 +704,6 @@ void LLFeatureManager::applyBaseMasks()
//LL_INFOS() << "Masking features from gpu table match: " << gpustr << LL_ENDL;
maskFeatures(gpustr);
- // now mask cpu type ones
- if (gSysMemory.getPhysicalMemoryKB() <= U32Megabytes(256))
- {
- maskFeatures("RAM256MB");
- }
-
- if (gSysCPU.getMHz() < 1100)
- {
- maskFeatures("CPUSlow");
- }
-
if (isSafe())
{
maskFeatures("safe");
@@ -774,11 +718,9 @@ LLSD LLFeatureManager::getRecommendedSettingsMap()
LLSD map(LLSD::emptyMap());
- loadGPUClass();
U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
LL_INFOS("RenderInit") << "Getting the map of recommended settings for level " << level << LL_ENDL;
- applyBaseMasks();
std::string features(isValidGraphicsLevel(level) ? getNameForGraphicsLevel(level) : "Low");
maskFeatures(features);
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/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 687d820a18..a3037ed651 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1087,10 +1087,7 @@ BOOL LLPreviewAnimation::render()
gGL.pushMatrix();
gGL.loadIdentity();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
LLGLSUIDefault def;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 028c922a4d..89ba687d25 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -664,10 +664,7 @@ BOOL LLImagePreviewAvatar::render()
LLGLSUIDefault def;
gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gl_rect_2d_simple( mFullWidth, mFullHeight );
@@ -866,10 +863,7 @@ BOOL LLImagePreviewSculpted::render()
gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gl_rect_2d_simple( mFullWidth, mFullHeight );
@@ -903,10 +897,7 @@ BOOL LLImagePreviewSculpted::render()
gPipeline.enableLightsAvatar();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectPreviewProgram.bind();
- }
+ gObjectPreviewProgram.bind();
gPipeline.enableLightsPreview();
gGL.pushMatrix();
@@ -920,10 +911,7 @@ BOOL LLImagePreviewSculpted::render()
gGL.popMatrix();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gObjectPreviewProgram.unbind();
- }
+ gObjectPreviewProgram.unbind();
return TRUE;
}
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 d6bb0ec872..c907dfc969 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1370,31 +1370,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;
@@ -1403,68 +1403,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);
@@ -1472,38 +1472,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 da01457126..b7d3701e4a 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1196,14 +1196,11 @@ 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") &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
@@ -1224,37 +1221,14 @@ 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");
bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
// Avatar Mode
- // Enable Avatar Shaders
- LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
// Avatar Render Mode
- LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
-
- bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
- if (LLViewerShaderMgr::sInitialized)
- {
- S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
- avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
- }
-
- ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
-
- if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
- {
- ctrl_avatar_cloth->setEnabled(FALSE);
- }
- else
- {
- ctrl_avatar_cloth->setEnabled(TRUE);
- }
+ getChild<LLCheckBoxCtrl>("AvatarCloth")->setEnabled(TRUE);
// Vertex Shaders, Global Shader Enable
// SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
@@ -1277,9 +1251,7 @@ 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;
ctrl_deferred->setEnabled(enabled);
@@ -1378,7 +1350,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
{
LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
- LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
@@ -1454,30 +1425,6 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
reflections_text->setEnabled(FALSE);
}
- // disabled av
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
- {
- ctrl_avatar_vp->setEnabled(FALSE);
- ctrl_avatar_vp->setValue(FALSE);
-
- ctrl_avatar_cloth->setEnabled(FALSE);
- ctrl_avatar_cloth->setValue(FALSE);
-
- //deferred needs AvatarVP, disable deferred
- ctrl_shadows->setEnabled(FALSE);
- ctrl_shadows->setValue(0);
- shadows_text->setEnabled(FALSE);
-
- ctrl_ssao->setEnabled(FALSE);
- ctrl_ssao->setValue(FALSE);
-
- ctrl_dof->setEnabled(FALSE);
- ctrl_dof->setValue(FALSE);
-
- ctrl_deferred->setEnabled(FALSE);
- ctrl_deferred->setValue(FALSE);
- }
-
// disabled cloth
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
{
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..175f1849cf 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -791,10 +791,7 @@ void LLViewerObjectList::renderObjectBeacons()
LLGLSUIDefault gls_ui;
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -882,10 +879,7 @@ void LLViewerObjectList::renderObjectBeacons()
void LLSky::renderSunMoonBeacons(const LLVector3& pos_agent, const LLVector3& direction, LLColor4 color)
{
LLGLSUIDefault gls_ui;
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLVector3 pos_end;
@@ -993,9 +987,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 +1084,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 +1094,6 @@ F32 gpu_benchmark()
}
LLStrider<LLVector3> v;
- LLStrider<LLVector2> tc;
if (! buff->getVertexStrider(v))
{
@@ -1123,6 +1115,16 @@ F32 gpu_benchmark()
// ensure matched pair of bind() and unbind() calls
ShaderBinder binder(gBenchmarkProgram);
+#ifdef GL_ARB_vertex_array_object
+ U32 glarray = 0;
+
+ if (LLRender::sGLCoreProfile)
+ {
+ glGenVertexArrays(1, &glarray);
+ glBindVertexArray(glarray);
+ }
+#endif
+
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
@@ -1155,6 +1157,15 @@ F32 gpu_benchmark()
}
}
+#ifdef GL_ARB_vertex_array_object
+ if (LLRender::sGLCoreProfile)
+ {
+ glBindVertexArray(0);
+ glDeleteVertexArrays(1, &glarray);
+ }
+#endif
+
+
std::sort(results.begin(), results.end());
F32 gbps = results[results.size()/2];
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..8e296321d2 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);
@@ -322,8 +323,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
// Render label
{
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin();
segment_iter != mLabelSegments.end(); ++segment_iter )
{
@@ -731,6 +730,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/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7c957ac712..9d8bf7f51c 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -188,9 +188,6 @@ void LLHUDText::renderText()
F32 y_offset = (F32)mOffsetY;
// Render label
- {
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
// Render text
{
@@ -573,7 +570,6 @@ void LLHUDText::renderAllHUD()
{
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
{
LLGLEnable color_mat(GL_COLOR_MATERIAL);
@@ -591,7 +587,6 @@ void LLHUDText::renderAllHUD()
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
}
void LLHUDText::shiftAll(const LLVector3& offset)
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..1364067949 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
@@ -389,12 +383,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
{
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogf(GL_FOG_DENSITY, 0);
- glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
- glFogf(GL_FOG_END, 1000000.f);
- }
return;
}
@@ -436,12 +424,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 +448,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]);
@@ -486,10 +478,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogfv(GL_FOG_COLOR, fog.mV);
- }
mGLFogCol = fog;
if (hide_clip_plane)
@@ -497,19 +485,11 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// For now, set the density to extend to the cull distance.
const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
fog_density = f_log/fog_distance;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogi(GL_FOG_MODE, GL_EXP2);
- }
}
else
{
const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
fog_density = (f_log)/fog_distance;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogi(GL_FOG_MODE, GL_EXP);
- }
}
}
else
@@ -535,12 +515,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the density based on what the shaders use
fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
-
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
- glFogi(GL_FOG_MODE, GL_EXP2);
- }
}
mFogColor = sky_fog_color;
@@ -548,13 +522,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
- if (!LLGLSLShader::sNoFixedFunction)
- {
- LLGLSFog gls_fog;
- glFogf(GL_FOG_END, fog_distance*2.2f);
- glFogf(GL_FOG_DENSITY, fog_density);
- glHint(GL_FOG_HINT, GL_NICEST);
- }
stop_glerror();
}
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/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
deleted file mode 100644
index 6736e9a950..0000000000
--- a/indra/newview/llmainlooprepeater.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * @file llmachineid.cpp
- * @brief retrieves unique machine ids
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llapr.h"
-#include "llevents.h"
-#include "llmainlooprepeater.h"
-
-
-
-// LLMainLoopRepeater
-//-----------------------------------------------------------------------------
-
-
-LLMainLoopRepeater::LLMainLoopRepeater(void):
- mQueue(0)
-{
- ; // No op.
-}
-
-
-void LLMainLoopRepeater::start(void)
-{
- if(mQueue != 0) return;
-
- mQueue = new LLThreadSafeQueue<LLSD>(1024);
- mMainLoopConnection = LLEventPumps::instance().
- obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
- mRepeaterConnection = LLEventPumps::instance().
- obtain("mainlooprepeater").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMessage, this, _1));
-}
-
-
-void LLMainLoopRepeater::stop(void)
-{
- mMainLoopConnection.release();
- mRepeaterConnection.release();
-
- delete mQueue;
- mQueue = 0;
-}
-
-
-bool LLMainLoopRepeater::onMainLoop(LLSD const &)
-{
- LLSD message;
- while(mQueue->tryPopBack(message)) {
- std::string pump = message["pump"].asString();
- if(pump.length() == 0 ) continue; // No pump.
- LLEventPumps::instance().obtain(pump).post(message["payload"]);
- }
- return false;
-}
-
-
-bool LLMainLoopRepeater::onMessage(LLSD const & event)
-{
- try {
- mQueue->pushFront(event);
- } catch(LLThreadSafeQueueError & e) {
- LL_WARNS() << "could not repeat message (" << e.what() << ")" <<
- event.asString() << LL_ENDL;
- }
- return false;
-}
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
deleted file mode 100644
index 2ec3a74e4a..0000000000
--- a/indra/newview/llmainlooprepeater.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file llmainlooprepeater.h
- * @brief a service for repeating messages on the main loop.
- *
- * $LicenseInfo:firstyear=2010&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLMAINLOOPREPEATER_H
-#define LL_LLMAINLOOPREPEATER_H
-
-
-#include "llsd.h"
-#include "llthreadsafequeue.h"
-
-
-//
-// A service which creates the pump 'mainlooprepeater' to which any thread can
-// post a message that will be re-posted on the main loop.
-//
-// The posted message should contain two map elements: pump and payload. The
-// pump value is a string naming the pump to which the message should be
-// re-posted. The payload value is what will be posted to the designated pump.
-//
-class LLMainLoopRepeater:
- public LLSingleton<LLMainLoopRepeater>
-{
- LLSINGLETON(LLMainLoopRepeater);
-public:
- // Start the repeater service.
- void start(void);
-
- // Stop the repeater service.
- void stop(void);
-
-private:
- LLTempBoundListener mMainLoopConnection;
- LLTempBoundListener mRepeaterConnection;
- LLThreadSafeQueue<LLSD> * mQueue;
-
- bool onMainLoop(LLSD const &);
- bool onMessage(LLSD const & event);
-};
-
-
-#endif
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 7c942e8b53..452762b09d 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -157,10 +157,7 @@ void LLManipRotate::render()
}
else
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.bind();
- }
+ gDebugProgram.bind();
LLGLEnable cull_face(GL_CULL_FACE);
LLGLDepthTest gls_depth(GL_FALSE);
@@ -213,10 +210,7 @@ void LLManipRotate::render()
}
gGL.popMatrix();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
}
gGL.translatef( center.mV[VX], center.mV[VY], center.mV[VZ] );
@@ -234,10 +228,7 @@ void LLManipRotate::render()
gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.bind();
- }
+ gDebugProgram.bind();
if (mManipPart == LL_ROT_Z)
{
@@ -355,11 +346,7 @@ void LLManipRotate::render()
}
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
-
+ gUIProgram.bind();
}
gGL.popMatrix();
gGL.popMatrix();
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 8736d3b51f..0b2a1ef389 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1565,11 +1565,6 @@ void LLManipTranslate::renderSnapGuides()
LLGLEnable stipple(GL_LINE_STIPPLE);
gGL.flush();
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glLineStipple(1, 0x3333);
- }
-
switch (mManipPart)
{
case LL_YZ_PLANE:
@@ -1633,7 +1628,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
- if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction)
+ if (!gSavedSettings.getBOOL("GridCrossSections"))
{
return;
}
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 8080e43383..61418ba547 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1972,7 +1972,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
LLMeshSkinInfo info(skin);
info.mMeshID = mesh_id;
- // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL;
+ // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL;
{
LLMutexLock lock(mMutex);
mSkinInfoQ.push_back(info);
@@ -4070,29 +4070,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 441264d42f..1989350303 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"
@@ -584,7 +585,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);
@@ -612,7 +613,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 5a8c1b474a..5d81d2c9b3 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -559,7 +559,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))
{
@@ -1380,6 +1380,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
S32 buf_positions_copied = 0;
S32 buf_indices_copied = 0;
indices_idx_shift = 0;
+ S32 valid_faces = 0;
// Crude method to copy indices back into face
for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
@@ -1478,6 +1479,8 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size);
+
+ valid_faces++;
}
indices_idx_shift += face.mNumVertices;
@@ -1490,7 +1493,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
ll_aligned_free_16(buffer_indices);
ll_aligned_free_32(combined_indices);
- if (new_indices < 3)
+ if (new_indices < 3 || valid_faces == 0)
{
// Model should have at least one visible triangle
@@ -1691,12 +1694,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
end = which_lod;
}
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- shader->unbind();
- }
-
for (S32 lod = start; lod >= end; --lod)
{
if (which_lod == -1)
@@ -1740,7 +1737,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// but combine all submodels with origin model as well
if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE)
{
- // Run meshoptimizer for each model/object, up to 8 faces in one model
+ // Run meshoptimizer for each model/object, up to 8 faces in one model.
// Ideally this should run not per model,
// but combine all submodels with origin model as well
@@ -1762,10 +1759,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
{
genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true);
}
+
+ LL_INFOS() << "Model " << target_model->getName()
+ << " lod " << which_lod
+ << " simplified using per face method." << LL_ENDL;
}
if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)
{
+ // Switches between 'combine' method and 'per model sloppy' based on combine's result.
F32 allowed_ratio_drift = 2.f;
F32 res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
@@ -1776,25 +1778,44 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
{
genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
}
- LL_INFOS() << "Model " << target_model->getName()
- << " lod " << which_lod
- << " per model method overflow, defaulting to per face." << LL_ENDL;
}
else if (res_ratio * allowed_ratio_drift < indices_decimator)
{
// Try sloppy variant if normal one failed to simplify model enough.
res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
- LL_INFOS() << "Model " << target_model->getName()
- << " lod " << which_lod
- << " sloppily simplified using per model method." << LL_ENDL;
+
+ // Sloppy has a tendecy to error into lower side, so a request for 100
+ // triangles turns into ~70, so check for significant difference from target decimation
+ F32 sloppy_ratio_drift = 1.4f;
+ if (lod_mode == LIMIT_TRIANGLES
+ && (res_ratio > indices_decimator * sloppy_ratio_drift || res_ratio < 0))
+ {
+ // Apply a correction to compensate.
+
+ // (indices_decimator / res_ratio) by itself is likely to overshoot to a differend
+ // side due to overal lack of precision, and we don't need an ideal result, which
+ // likely does not exist, just a better one, so a partial correction is enough.
+ F32 sloppy_decimator = indices_decimator * (indices_decimator / res_ratio + 1) / 2;
+ res_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ }
if (res_ratio < 0)
{
// Sloppy variant failed to generate triangles.
// Can happen with models that are too simple as is.
- // Fallback to normal method.
+ // Fallback to normal method or use lower decimator.
genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+
+ LL_INFOS() << "Model " << target_model->getName()
+ << " lod " << which_lod
+ << " simplified using per model method." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << "Model " << target_model->getName()
+ << " lod " << which_lod
+ << " sloppily simplified using per model method." << LL_ENDL;
}
}
else
@@ -1846,12 +1867,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
}
mResourceCost = calcResourceCost();
-
- LLVertexBuffer::unbind();
- if (shader)
- {
- shader->bind();
- }
}
void LLModelPreview::updateStatusMessages()
@@ -2652,6 +2667,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
*(index_strider++) = vf.mIndices[i];
}
+ vb->flush();
+
mVertexBuffer[lod][mdl].push_back(vb);
vertex_count += num_vertices;
@@ -2877,8 +2894,6 @@ BOOL LLModelPreview::render()
LLMutexLock lock(this);
mNeedsUpdate = FALSE;
- bool use_shaders = LLGLSLShader::sNoFixedFunction;
-
bool edges = mViewOption["show_edges"];
bool joint_overrides = mViewOption["show_joint_overrides"];
bool joint_positions = mViewOption["show_joint_positions"];
@@ -2896,10 +2911,8 @@ BOOL LLModelPreview::render()
LLGLDisable fog(GL_FOG);
{
- if (use_shaders)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
+
//clear background to grey
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -2918,10 +2931,7 @@ BOOL LLModelPreview::render()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- if (use_shaders)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
}
LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
@@ -3074,10 +3084,7 @@ BOOL LLModelPreview::render()
refresh();
}
- if (use_shaders)
- {
- gObjectPreviewProgram.bind();
- }
+ gObjectPreviewProgram.bind();
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -3137,6 +3144,11 @@ BOOL LLModelPreview::render()
genBuffers(mPreviewLOD, skin_weight);
}
+ if (physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+
if (!skin_weight)
{
for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
@@ -3198,6 +3210,7 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
}
+ buffer->flush();
}
gGL.popMatrix();
}
@@ -3278,7 +3291,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)
{
@@ -3291,11 +3304,6 @@ BOOL LLModelPreview::render()
if (render_mesh)
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
if (pass > 0){
for (U32 i = 0; i < num_models; ++i)
@@ -3315,6 +3323,8 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
+
+ buffer->flush();
}
}
}
@@ -3359,11 +3369,6 @@ BOOL LLModelPreview::render()
if (physics.mHull.empty())
{
- if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
- {
- genBuffers(LLModel::LOD_PHYSICS, false);
- }
-
U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size();
for (U32 v = 0; v < num_models; ++v)
{
@@ -3390,6 +3395,8 @@ BOOL LLModelPreview::render()
buffer->draw(LLRender::POINTS, 3, i);
}
}
+
+ buffer->flush();
}
}
}
@@ -3450,7 +3457,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;
@@ -3492,11 +3499,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)
{
@@ -3579,10 +3585,7 @@ BOOL LLModelPreview::render()
}
}
- if (use_shaders)
- {
- gObjectPreviewProgram.unbind();
- }
+ gObjectPreviewProgram.unbind();
gGL.popMatrix();
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 9361acfc49..48d6d362eb 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -225,8 +225,12 @@ private:
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
- // functions for meshoptimizer, return reached simplification ratio
+ // Merges faces into single mesh, simplifies using mesh optimizer,
+ // then splits back into faces.
+ // Returns reached simplification ratio. -1 in case of a failure.
F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ // Simplifies specified face using mesh optimizer.
+ // Returns reached simplification ratio. -1 in case of a failure.
F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, bool sloppy);
protected:
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 112da55682..937f36b6fc 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);
@@ -258,7 +259,7 @@ void LLNetMap::draw()
gGL.end();
// Draw water
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f);
+ gGL.flush();
{
if (regionp->getLand().getWaterTexture())
{
@@ -275,7 +276,7 @@ void LLNetMap::draw()
gGL.end();
}
}
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
// Redraw object layer periodically
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..2e44dc1459 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -271,7 +271,7 @@ void LLSceneMonitor::capture()
static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime");
static bool force_capture = true;
- bool enabled = LLGLSLShader::sNoFixedFunction && (monitor_enabled || mDebugViewerVisible);
+ bool enabled = monitor_enabled || mDebugViewerVisible;
if(mEnabled != enabled)
{
if(mEnabled)
@@ -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();
@@ -729,13 +719,6 @@ void LLSceneMonitorView::onTeleportFinished()
void LLSceneMonitorView::onVisibilityChange(BOOL visible)
{
- if (!LLGLSLShader::sNoFixedFunction && visible)
- {
- visible = false;
- // keep Scene monitor and its view in sycn
- setVisible(false);
- LL_WARNS("SceneMonitor") << "Incompatible graphical settings, Scene Monitor can't be turned on" << LL_ENDL;
- }
LLSceneMonitor::getInstance()->setDebugViewerVisible(visible);
}
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..b3d3e9e0da 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -209,8 +209,6 @@ void LLSelectMgr::cleanupGlobals()
LLSelectMgr::getInstance()->clearSelections();
}
-// Build time optimization, generate this function once here
-template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
//-----------------------------------------------------------------------------
// LLSelectMgr()
//-----------------------------------------------------------------------------
@@ -5896,8 +5894,6 @@ void LLSelectMgr::updateSilhouettes()
LLViewerObject* objectp = *iter;
objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
}
-
- //gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects)
@@ -6622,7 +6618,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
glFogfv(GL_FOG_COLOR, fogCol.mV);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
gGL.begin(LLRender::LINES);
{
gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
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 58cbe0e20a..6415da4e4a 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 a1baf02fe7..05ec0e9275 100644
--- a/indra/newview/llsettingsvo.h
+++ b/indra/newview/llsettingsvo.h
@@ -101,8 +101,6 @@ public:
bool isAdvanced() const { return m_isAdvanced; }
- virtual void updateShader(LLGLSLShader* shader) { applySpecial(shader, true); }
-
protected:
LLSettingsVOSky();
@@ -135,8 +133,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..1869370ac7 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -51,13 +51,9 @@
#include "llphysicsshapebuilderutil.h"
#include "llvoavatar.h"
#include "llvolumemgr.h"
-#include "lltextureatlas.h"
#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;
@@ -131,129 +127,6 @@ LLSpatialGroup::~LLSpatialGroup()
sNodeCount--;
clearDrawMap();
- clearAtlasList() ;
-}
-
-BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp)
-{
- S8 type = atlasp->getComponents() - 1 ;
- for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter)
- {
- if(atlasp == *iter)
- {
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level)
-{
- if(!hasAtlas(atlasp))
- {
- mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ;
- atlasp->addSpatialGroup(this) ;
- }
-
- --recursive_level;
- if(recursive_level)//levels propagating up.
- {
- LLSpatialGroup* parent = getParent() ;
- if(parent)
- {
- parent->addAtlas(atlasp, recursive_level) ;
- }
- }
-}
-
-void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level)
-{
- mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ;
- if(remove_group)
- {
- atlasp->removeSpatialGroup(this) ;
- }
-
- --recursive_level;
- if(recursive_level)//levels propagating up.
- {
- LLSpatialGroup* parent = getParent() ;
- if(parent)
- {
- parent->removeAtlas(atlasp, recursive_level) ;
- }
- }
-}
-
-void LLSpatialGroup::clearAtlasList()
-{
- std::list<LLTextureAtlas*>::iterator iter ;
- for(S8 i = 0 ; i < 4 ; i++)
- {
- if(mAtlasList[i].size() > 0)
- {
- for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter)
- {
- ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ;
- }
- mAtlasList[i].clear() ;
- }
- }
-}
-
-LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level)
-{
- S8 type = ncomponents - 1 ;
- if(mAtlasList[type].size() > 0)
- {
- for(std::list<LLTextureAtlas*>::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter)
- {
- if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved))
- {
- return *iter ;
- }
- }
- }
-
- --recursive_level;
- if(recursive_level)
- {
- LLSpatialGroup* parent = getParent() ;
- if(parent)
- {
- return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ;
- }
- }
- return NULL ;
-}
-
-void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp)
-{
- mCurUpdatingSlotp = slotp;
-
- //if(!hasAtlas(mCurUpdatingSlotp->getAtlas()))
- //{
- // addAtlas(mCurUpdatingSlotp->getAtlas()) ;
- //}
-}
-
-LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level)
-{
- if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep)
- {
- return mCurUpdatingSlotp ;
- }
-
- //--recursive_level ;
- //if(recursive_level)
- //{
- // LLSpatialGroup* parent = getParent() ;
- // if(parent)
- // {
- // return parent->getCurUpdatingSlot(imagep, recursive_level) ;
- // }
- //}
- return NULL ;
}
void LLSpatialGroup::clearDrawMap()
@@ -345,6 +218,7 @@ void LLSpatialGroup::validateDrawMap()
BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
{
+ LL_PROFILE_ZONE_SCOPED;
drawablep->updateSpatialExtents();
OctreeNode* parent = mOctreeNode->getOctParent();
@@ -409,11 +283,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 +296,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 +304,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 +324,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
group->mVertexBuffer = NULL;
group->mBufferMap.clear();
}
- stop_glerror();
}
else
{
@@ -471,13 +336,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 +366,9 @@ LLSpatialGroup* LLSpatialGroup::getParent()
}
BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
- {
+{
+ LL_PROFILE_ZONE_SCOPED
+
if(!drawablep)
{
return FALSE;
@@ -591,6 +456,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 +505,8 @@ public:
void LLSpatialGroup::clearState(U32 state, S32 mode)
{
+ LL_PROFILE_ZONE_SCOPED
+
llassert(state <= LLSpatialGroup::STATE_MASK);
if (mode > STATE_MODE_SINGLE)
@@ -673,11 +542,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
mDistance(0.f),
mDepth(0.f),
mLastUpdateDistance(-1.f),
- mLastUpdateTime(gFrameTimeSeconds),
- mAtlasList(4),
- mCurUpdatingTime(0),
- mCurUpdatingSlotp(NULL),
- mCurUpdatingTexture (NULL)
+ mLastUpdateTime(gFrameTimeSeconds)
{
ll_assert_aligned(this,16);
@@ -724,6 +589,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 +682,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 +776,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());
@@ -983,6 +854,7 @@ LLSpatialPartition::~LLSpatialPartition()
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
{
+ LL_PROFILE_ZONE_SCOPED;
drawablep->updateSpatialExtents();
//keep drawable from being garbage collected
@@ -1008,6 +880,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!curp->removeObject(drawablep))
{
OCT_ERRS << "Failed to remove drawable from octree!" << LL_ENDL;
@@ -1024,6 +897,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate)
{
+ LL_PROFILE_ZONE_SCOPED;
// sanity check submitted by open source user bushing Spatula
// who was seeing crashing here. (See VWR-424 reported by Bunny Mayne)
if (!drawablep)
@@ -1477,12 +1351,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 +1378,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 +1399,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;
}
@@ -1728,10 +1597,14 @@ void renderOctree(LLSpatialGroup* group)
gGL.flush();
glLineWidth(1.f);
gGL.flush();
+
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
+ if(!drawable || drawable->getNumFaces() == 0)
{
continue;
}
@@ -1742,6 +1615,27 @@ void renderOctree(LLSpatialGroup* group)
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
}
+ LLFace* face = drawable->getFace(0);
+ bool rigged = face->isState(LLFace::RIGGED);
+ gDebugProgram.bind(rigged);
+
+ gGL.diffuseColor4f(1, 0, 0, 1);
+
+ if (rigged)
+ {
+ gGL.pushMatrix();
+ gGL.loadMatrix(gGLModelView);
+ if (lastAvatar != face->mAvatar ||
+ lastMeshId != face->mSkinInfo->mHash)
+ {
+ if (!LLRenderPass::uploadMatrixPalette(face->mAvatar, face->mSkinInfo))
+ {
+ continue;
+ }
+ lastAvatar = face->mAvatar;
+ lastMeshId = face->mSkinInfo->mHash;
+ }
+ }
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* face = drawable->getFace(j);
@@ -1760,19 +1654,25 @@ void renderOctree(LLSpatialGroup* group)
continue;
}
- face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX | (rigged ? LLVertexBuffer::MAP_WEIGHT4 : 0));
//drawBox((face->mExtents[0] + face->mExtents[1])*0.5f,
// (face->mExtents[1]-face->mExtents[0])*0.5f);
face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
}
}
+ if (rigged)
+ {
+ gGL.popMatrix();
+ }
+
if (!group->getSpatialPartition()->isBridge())
{
gGL.popMatrix();
}
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gDebugProgram.bind(); // make sure non-rigged variant is bound
gGL.diffuseColor4f(1,1,1,1);
}
}
@@ -2374,7 +2274,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 +2299,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 +2358,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 +2388,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
@@ -2613,9 +2519,9 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.diffuseColor4fv(line_color.mV);
LLVertexBuffer::unbind();
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
-
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
+ llassert(LLGLSLShader::sCurBoundShader != 0);
+
+ 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);
@@ -2695,16 +2601,22 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
if (phys_volume->mHullPoints && phys_volume->mHullIndices)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
+ llassert(LLGLSLShader::sCurBoundShader != 0);
LLVertexBuffer::unbind();
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
{
@@ -2896,8 +2808,27 @@ void renderBatchSize(LLDrawInfo* params)
{
LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.f, 1.f);
- gGL.diffuseColor4ubv((GLubyte*) &(params->mDebugColor));
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
+ LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr;
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ bool bind = false;
+ if (params->mAvatar)
+ {
+ gGL.pushMatrix();
+ gGL.loadMatrix(gGLModelView);
+ bind = true;
+ old_shader->mRiggedVariant->bind();
+ LLRenderPass::uploadMatrixPalette(*params);
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ gGL.diffuseColor4ubv((GLubyte*)&(params->mDebugColor));
+ pushVerts(params, mask);
+
+ if (bind)
+ {
+ gGL.popMatrix();
+ old_shader->bind();
+ }
}
void renderShadowFrusta(LLDrawInfo* params)
@@ -3222,6 +3153,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);
}
@@ -3774,10 +3706,7 @@ void LLSpatialPartition::renderDebug()
return;
}
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.bind();
- }
+ gDebugProgram.bind();
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
@@ -3826,10 +3755,7 @@ void LLSpatialPartition::renderDebug()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.unbind();
- }
+ gDebugProgram.unbind();
}
void LLSpatialGroup::drawObjectBox(LLColor4 col)
@@ -4023,8 +3949,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),
@@ -4054,7 +3979,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
- mDebugColor = (rand() << 16) + rand();
+ mDebugColor = (rand() << 16) + rand();
+ ((U8*)&mDebugColor)[3] = 200;
}
LLDrawInfo::~LLDrawInfo()
@@ -4080,6 +4006,11 @@ void LLDrawInfo::validate()
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
}
+U64 LLDrawInfo::getSkinHash()
+{
+ return mSkinInfo ? mSkinInfo->mHash : 0;
+}
+
LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
{
return new LLVertexBuffer(type_mask, usage);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 919f386d29..666c025347 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)
@@ -49,20 +50,18 @@ class LLViewerOctreePartition;
class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
-class LLTextureAtlas;
-class LLTextureAtlasSlot;
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;
}
@@ -81,12 +80,19 @@ public:
void validate();
+ // return mSkinHash->mHash, or 0 if mSkinHash is null
+ U64 getSkinHash();
+
LLVector4a mExtents[2];
LLPointer<LLVertexBuffer> mVertexBuffer;
LLPointer<LLViewerTexture> mTexture;
std::vector<LLPointer<LLViewerTexture> > mTextureList;
+ // virtual size of mTexture and mTextureList textures
+ // used to update the decode priority of textures in this DrawInfo
+ std::vector<F32> mTextureListVSize;
+
S32 mDebugColor;
const LLMatrix4* mTextureMatrix;
const LLMatrix4* mModelMatrix;
@@ -119,6 +125,8 @@ public:
F32 mAlphaMaskCutoff;
U8 mDiffuseAlphaMode;
bool mSelected;
+ LLVOAvatar* mAvatar = nullptr;
+ LLMeshSkinInfo* mSkinInfo = nullptr;
struct CompareTexture
@@ -216,10 +224,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
{
@@ -298,49 +306,15 @@ public:
virtual void handleDestruction(const TreeNode* node);
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
-//-------------------
-//for atlas use
-//-------------------
- //atlas
- void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;}
- U32 getCurUpdatingTime() const { return mCurUpdatingTime ;}
-
- void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ;
- LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level = 3) ;
-
- void setCurUpdatingTexture(LLViewerTexture* tex){ mCurUpdatingTexture = tex ;}
- LLViewerTexture* getCurUpdatingTexture() const { return mCurUpdatingTexture ;}
-
- BOOL hasAtlas(LLTextureAtlas* atlasp) ;
- LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ;
- void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ;
- void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ;
- void clearAtlasList() ;
-
public:
-
LL_ALIGN_16(LLVector4a mViewAngle);
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
-
-private:
- U32 mCurUpdatingTime ;
- //do not make the below two to use LLPointer
- //because mCurUpdatingTime invalidates them automatically.
- LLTextureAtlasSlot* mCurUpdatingSlotp ;
- LLViewerTexture* mCurUpdatingTexture ;
-
- std::vector< std::list<LLTextureAtlas*> > mAtlasList ;
-//-------------------
-//end for atlas use
-//-------------------
protected:
virtual ~LLSpatialGroup();
- static S32 sLODSeed;
-
public:
bridge_list_t mBridgeList;
buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
@@ -465,8 +439,11 @@ public:
virtual void cleanupReferences();
virtual LLSpatialPartition* asPartition() { return this; }
+ //transform agent space camera into this Spatial Bridge's coordinate frame
virtual LLCamera transformCamera(LLCamera& camera);
-
+
+ //transform agent space bounding box into this Spatial Bridge's coordinate frame
+ void transformExtents(const LLVector4a* src, LLVector4a* dst);
LLDrawable* mDrawable;
};
@@ -646,7 +623,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
- U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
+ U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL rigged = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
private:
@@ -654,13 +631,13 @@ private:
void freeFaces();
static int32_t sInstanceCount;
- static LLFace** sFullbrightFaces;
- static LLFace** sBumpFaces;
- static LLFace** sSimpleFaces;
- static LLFace** sNormFaces;
- static LLFace** sSpecFaces;
- static LLFace** sNormSpecFaces;
- static LLFace** sAlphaFaces;
+ static LLFace** sFullbrightFaces[2];
+ static LLFace** sBumpFaces[2];
+ static LLFace** sSimpleFaces[2];
+ static LLFace** sNormFaces[2];
+ static LLFace** sSpecFaces[2];
+ static LLFace** sNormSpecFaces[2];
+ static LLFace** sAlphaFaces[2];
};
//spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 54f3e6305c..da8d5152b4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -35,6 +35,7 @@
#else
# include <sys/stat.h> // mkdir()
#endif
+#include <memory> // std::unique_ptr
#include "llviewermedia_streamingaudio.h"
#include "llaudioengine.h"
@@ -178,7 +179,6 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llfasttimerview.h"
-#include "lltelemetry.h"
#include "llfloatermap.h"
#include "llweb.h"
#include "llvoiceclient.h"
@@ -205,6 +205,9 @@
#include "llstacktrace.h"
+#include "threadpool.h"
+
+
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
@@ -252,9 +255,9 @@ static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
-boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
-boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
-boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);
+std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
+std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
+std::unique_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);
//
// local function declaration
@@ -529,8 +532,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");
@@ -1484,6 +1485,21 @@ bool idle_startup()
gAgentCamera.resetCamera();
display_startup();
+ // start up the ThreadPool we'll use for textures et al.
+ {
+ LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") };
+ LLSD sizeSpec{ poolSizes["General"] };
+ LLSD::Integer poolSize{ sizeSpec.isInteger()? sizeSpec.asInteger() : 3 };
+ LL_DEBUGS("ThreadPool") << "Instantiating General pool with "
+ << poolSize << " threads" << LL_ENDL;
+ // We don't want anyone, especially the main thread, to have to block
+ // due to this ThreadPool being full.
+ auto pool = new LL::ThreadPool("General", poolSize, 1024*1024);
+ pool->start();
+ // Once we start shutting down, destroy this ThreadPool.
+ LLAppViewer::instance()->onCleanup([pool](){ delete pool; });
+ }
+
// Initialize global class data needed for surfaces (i.e. textures)
LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
// Initialize all of the viewer object classes for the first time (doing things like texture fetches.
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 116aeb36a7..fe8e215f76 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -27,7 +27,7 @@
#ifndef LL_LLSTARTUP_H
#define LL_LLSTARTUP_H
-#include <boost/scoped_ptr.hpp>
+#include <memory> // unique_ptr
class LLViewerTexture ;
class LLEventPump;
@@ -130,9 +130,9 @@ private:
static std::string startupStateToString(EStartupState state);
static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLStartupListener> sListener;
- static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases;
+ static std::unique_ptr<LLEventPump> sStateWatcher;
+ static std::unique_ptr<LLStartupListener> sListener;
+ static std::unique_ptr<LLViewerStats::PhaseMap> sPhases;
};
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/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
deleted file mode 100644
index 1c8e4f796e..0000000000
--- a/indra/newview/lltextureatlas.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-/**
- * @file lltextureatlas.cpp
- * @brief LLTextureAtlas class implementation.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#include "llviewerprecompiledheaders.h"
-#include "linden_common.h"
-#include "llerror.h"
-#include "llimage.h"
-#include "llmath.h"
-#include "llgl.h"
-#include "llrender.h"
-#include "lltextureatlas.h"
-
-//-------------------
-S16 LLTextureAtlas::sMaxSubTextureSize = 64 ;
-S16 LLTextureAtlas::sSlotSize = 32 ;
-
-#ifndef DEBUG_ATLAS
-#define DEBUG_ATLAS 0
-#endif
-
-#ifndef DEBUG_USAGE_BITS
-#define DEBUG_USAGE_BITS 0
-#endif
-//**************************************************************************************************************
-LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) :
- LLViewerTexture(atlas_dim * sSlotSize, atlas_dim * sSlotSize, ncomponents, TRUE),
- mAtlasDim(atlas_dim),
- mNumSlotsReserved(0),
- mMaxSlotsInAtlas(atlas_dim * atlas_dim)
-{
- generateEmptyUsageBits() ;
-
- //generate an empty texture
- generateGLTexture() ;
- LLPointer<LLImageRaw> image_raw = new LLImageRaw(mFullWidth, mFullHeight, mComponents);
- createGLTexture(0, image_raw, 0);
- image_raw = NULL;
-}
-
-LLTextureAtlas::~LLTextureAtlas()
-{
- if(mSpatialGroupList.size() > 0)
- {
- LL_ERRS() << "Not clean up the spatial groups!" << LL_ENDL ;
- }
- releaseUsageBits() ;
-}
-
-//virtual
-S8 LLTextureAtlas::getType() const
-{
- return 0; //LLViewerTexture::ATLAS_TEXTURE ;
-}
-
-void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset)
-{
- xoffset = (F32)col / mAtlasDim ;
- yoffset = (F32)row / mAtlasDim ;
-}
-
-void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale)
-{
- xscale = (F32)w / (mAtlasDim * sSlotSize) ;
- yscale = (F32)h / (mAtlasDim * sSlotSize) ;
-}
-
-//insert a texture piece into the atlas
-LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row)
-{
- if(!getTexName())
- {
- return 0 ;
- }
-
- S32 w = raw_image->getWidth() ;
- S32 h = raw_image->getHeight() ;
- if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize)
- {
- //size overflow
- return 0 ;
- }
-
- BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName());
- if (!res)
- {
- LL_ERRS() << "bindTexture failed" << LL_ENDL;
- }
-
- GLint xoffset = sSlotSize * slot_col ;
- GLint yoffset = sSlotSize * slot_row ;
-
- if(!source_gl_tex->preAddToAtlas(discard_level, raw_image))
- {
- return 0 ;
- }
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,
- mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData());
-
- source_gl_tex->postAddToAtlas() ;
- return getTexName();
-}
-
-//release a sub-texture slot from the atlas
-void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width)
-{
- unmarkUsageBits(slot_width, slot_col, slot_row) ;
- mNumSlotsReserved -= slot_width * slot_width ;
-}
-
-BOOL LLTextureAtlas::isEmpty() const
-{
- return !mNumSlotsReserved ;
-}
-
-BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const
-{
- return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ;
-}
-F32 LLTextureAtlas::getFullness() const
-{
- return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ;
-}
-
-void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp)
-{
- if(groupp && !hasSpatialGroup(groupp))
- {
- mSpatialGroupList.push_back(groupp);
- }
-}
-
-void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp)
-{
- if(groupp)
- {
- mSpatialGroupList.remove(groupp);
- }
-}
-
-void LLTextureAtlas::clearSpatialGroup()
-{
- mSpatialGroupList.clear();
-}
-void LLTextureAtlas::removeLastSpatialGroup()
-{
- mSpatialGroupList.pop_back() ;
-}
-
-LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup()
-{
- if(mSpatialGroupList.size() > 0)
- {
- return mSpatialGroupList.back() ;
- }
- return NULL ;
-}
-
-BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp)
-{
- for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter)
- {
- if(*iter == groupp)
- {
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-//--------------------------------------------------------------------------------------
-//private
-void LLTextureAtlas::generateEmptyUsageBits()
-{
- S32 col_len = (mAtlasDim + 7) >> 3 ;
- mUsageBits = new U8*[mAtlasDim] ;
- *mUsageBits = new U8[mAtlasDim * col_len] ;
-
- mUsageBits[0] = *mUsageBits ;
- for(S32 i = 1 ; i < mAtlasDim ; i++)
- {
- mUsageBits[i] = mUsageBits[i-1] + col_len ;
-
- for(S32 j = 0 ; j < col_len ; j++)
- {
- //init by 0 for all bits.
- mUsageBits[i][j] = 0 ;
- }
- }
-
- //do not forget mUsageBits[0]!
- for(S32 j = 0 ; j < col_len ; j++)
- {
- //init by 0 for all bits.
- mUsageBits[0][j] = 0 ;
- }
-
- mTestBits = NULL ;
-#if DEBUG_USAGE_BITS
- //------------
- //test
- mTestBits = new U8*[mAtlasDim] ;
- *mTestBits = new U8[mAtlasDim * mAtlasDim] ;
- mTestBits[0] = *mTestBits ;
- for(S32 i = 1 ; i < mAtlasDim ; i++)
- {
- mTestBits[i] = mTestBits[i-1] + mAtlasDim ;
-
- for(S32 j = 0 ; j < mAtlasDim ; j++)
- {
- //init by 0 for all bits.
- mTestBits[i][j] = 0 ;
- }
- }
-
- for(S32 j = 0 ; j < mAtlasDim ; j++)
- {
- //init by 0 for all bits.
- mTestBits[0][j] = 0 ;
- }
-#endif
-}
-
-void LLTextureAtlas::releaseUsageBits()
-{
- if(mUsageBits)
- {
- delete[] *mUsageBits ;
- delete[] mUsageBits ;
- }
- mUsageBits = NULL ;
-
- //test
- if( mTestBits)
- {
- delete[] *mTestBits;
- delete[] mTestBits;
- }
- mTestBits = NULL ;
-}
-
-void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row)
-{
- S16 x = col >> 3 ;
-
- for(S8 i = 0 ; i < bits_len ; i++)
- {
- mUsageBits[row + i][x] |= mask ;
- }
-
-#if DEBUG_USAGE_BITS
- //test
- for(S8 i = row ; i < row + bits_len ; i++)
- {
- for(S8 j = col ; j < col + bits_len ; j++)
- {
- mTestBits[i][j] = 1 ;
- }
- }
-#endif
-}
-
-void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row)
-{
- S16 x = col >> 3 ;
- U8 mask = 1 ;
- for(S8 i = 1 ; i < bits_len ; i++)
- {
- mask |= (1 << i) ;
- }
- mask <<= (col & 7) ;
- mask = ~mask ;
-
- for(S8 i = 0 ; i < bits_len ; i++)
- {
- mUsageBits[row + i][x] &= mask ;
- }
-
-#if DEBUG_USAGE_BITS
- //test
- for(S8 i = row ; i < row + bits_len ; i++)
- {
- for(S8 j = col ; j < col + bits_len ; j++)
- {
- mTestBits[i][j] = 0 ;
- }
- }
-#endif
-}
-
-//return true if any of bits in the range marked.
-BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row)
-{
- BOOL ret = FALSE ;
- S16 x = col >> 3 ;
-
- for(S8 i = 0 ; i < bits_len ; i++)
- {
- if(mUsageBits[row + i][x] & mask)
- {
- ret = TRUE ;
- break ;
- //return TRUE ;
- }
- }
-
-#if DEBUG_USAGE_BITS
- //test
- BOOL ret2 = FALSE ;
- for(S8 i = row ; i < row + bits_len ; i++)
- {
- for(S8 j = col ; j < col + bits_len ; j++)
- {
- if(mTestBits[i][j])
- {
- ret2 = TRUE ;
- }
- }
- }
-
- if(ret != ret2)
- {
- LL_ERRS() << "bits map corrupted." << LL_ENDL ;
- }
-#endif
- return ret ;//FALSE ;
-}
-
-//----------------------------------------------------------------------
-//
-//index order: Z order, i.e.:
-// |-----|-----|-----|-----|
-// | 10 | 11 | 14 | 15 |
-// |-----|-----|-----|-----|
-// | 8 | 9 | 12 | 13 |
-// |-----|-----|-----|-----|
-// | 2 | 3 | 6 | 7 |
-// |-----|-----|-----|-----|
-// | 0 | 1 | 4 | 5 |
-// |-----|-----|-----|-----|
-void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row)
-{
- col = 0 ;
- row = 0 ;
-
- S16 index_copy = index ;
- for(S16 i = 0 ; index_copy && i < 16 ; i += 2)
- {
- col |= ((index & (1 << i)) >> i) << (i >> 1) ;
- row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ;
- index_copy >>= 2 ;
- }
-}
-void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index)
-{
- index = 0 ;
- S16 col_copy = col ;
- S16 row_copy = row ;
- for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++)
- {
- index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ;
- col_copy >>= 1 ;
- row_copy >>= 1 ;
- }
-}
-//----------------------------------------------------------------------
-//return TRUE if succeeds.
-BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row)
-{
- S16 index_step = bits_len * bits_len ;
-
- U8 mask = 1 ;
- for(S8 i = 1 ; i < bits_len ; i++)
- {
- mask |= (1 << i) ;
- }
-
- U8 cur_mask ;
- for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step)
- {
- getPositionFromIndex(index, col, row) ;
-
- cur_mask = mask << (col & 7) ;
- if(!areUsageBitsMarked(bits_len, cur_mask, col, row))
- {
- markUsageBits(bits_len, cur_mask, col, row) ;
- mNumSlotsReserved += bits_len * bits_len ;
-
- return TRUE ;
- }
- }
-
- return FALSE ;
-}
diff --git a/indra/newview/lltextureatlas.h b/indra/newview/lltextureatlas.h
deleted file mode 100644
index 6b36eb7fe4..0000000000
--- a/indra/newview/lltextureatlas.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @file lltextureatlas.h
- * @brief LLTextureAtlas base class.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#ifndef LL_TEXTUREATLAS_H
-#define LL_TEXTUREATLAS_H
-
-#include "llviewertexture.h"
-class LLSpatialGroup ;
-
-class LLTextureAtlas : public LLViewerTexture
-{
-protected:
- /*virtual*/ ~LLTextureAtlas() ;
-
-public:
- LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ;
-
- /*virtual*/ S8 getType() const;
-
- LLGLuint insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ;
- void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width);
-
- BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ;
- void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ;
- void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ;
-
- BOOL isEmpty() const ;
- BOOL isFull(S8 to_be_reserved = 1) const ;
- F32 getFullness() const ;
-
- void addSpatialGroup(LLSpatialGroup* groupp) ;
- void removeSpatialGroup(LLSpatialGroup* groupp) ;
- LLSpatialGroup* getLastSpatialGroup() ;
- void removeLastSpatialGroup() ;
- BOOL hasSpatialGroup(LLSpatialGroup* groupp) ;
- void clearSpatialGroup() ;
- std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;}
-private:
- void generateEmptyUsageBits() ;
- void releaseUsageBits() ;
-
- void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ;
- void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ;
-
- void getPositionFromIndex(S16 index, S16& col, S16& row) ;
- void getIndexFromPosition(S16 col, S16 row, S16& index) ;
- BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ;
-
-private:
- S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas.
- S16 mNumSlotsReserved ;
- S16 mMaxSlotsInAtlas ;
- U8 **mUsageBits ;
- std::list<LLSpatialGroup*> mSpatialGroupList ;
-
-public:
- //debug use only
- U8 **mTestBits ;
-
-public:
- static S16 sMaxSubTextureSize ;
- static S16 sSlotSize ;
-};
-
-#endif
-
diff --git a/indra/newview/lltextureatlasmanager.cpp b/indra/newview/lltextureatlasmanager.cpp
deleted file mode 100644
index ca9d6da4db..0000000000
--- a/indra/newview/lltextureatlasmanager.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- * @file lltextureatlasmanager.cpp
- * @brief LLTextureAtlasManager class implementation.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#include "llviewerprecompiledheaders.h"
-#include "linden_common.h"
-#include "llerror.h"
-#include "llmath.h"
-#include "lltextureatlas.h"
-#include "lltextureatlasmanager.h"
-#include "llspatialpartition.h"
-
-const S8 MAX_NUM_EMPTY_ATLAS = 2 ;
-const F32 MIN_ATLAS_FULLNESS = 0.6f ;
-
-//*********************************************************************************************
-//implementation of class LLTextureAtlasInfo
-//*********************************************************************************************
-LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) :
- mAtlasp(atlasp),
- mGroupp(groupp),
- mCol(col),
- mRow(row),
- mReservedSlotWidth(slot_width),
- mValid(FALSE),
- mUpdatedTime(0),
- mTexCoordOffset(xoffset, yoffset),
- mTexCoordScale(1.f, 1.f)
-{
- llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ;
-}
-
-LLTextureAtlasSlot::~LLTextureAtlasSlot()
-{
- if(mAtlasp)
- {
- mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ;
- if(mAtlasp->isEmpty())
- {
- LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ;
- }
- mAtlasp = NULL ;
- }
-}
-
-//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp)
-//{
-// mAtlasp = atlasp ;
-//}
-//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row)
-//{
-// mCol = col ;
-// mRow = row ;
-//}
-//void LLTextureAtlasSlot::setSlotWidth(S8 width)
-//{
-// //slot is a square with each edge length a power-of-two number
-// mReservedSlotWidth = width ;
-//}
-//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset)
-//{
-// mTexCoordOffset.mV[0] = xoffset ;
-// mTexCoordOffset.mV[1] = yoffset ;
-//}
-
-void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp)
-{
- mGroupp = groupp ;
-}
-void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale)
-{
- mTexCoordScale.mV[0] = xscale ;
- mTexCoordScale.mV[1] = yscale ;
-}
-//*********************************************************************************************
-//END of implementation of class LLTextureAtlasInfo
-//*********************************************************************************************
-
-//*********************************************************************************************
-//implementation of class LLTextureAtlasManager
-//*********************************************************************************************
-LLTextureAtlasManager::LLTextureAtlasManager() :
- mAtlasMap(4),
- mEmptyAtlasMap(4)
-{
-}
-
-LLTextureAtlasManager::~LLTextureAtlasManager()
-{
- for(S32 i = 0 ; i < 4 ; i++)
- {
- for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j)
- {
- *j = NULL ;
- }
- for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j)
- {
- *j = NULL ;
- }
-
- mAtlasMap[i].clear() ;
- mEmptyAtlasMap[i].clear() ;
- }
- mAtlasMap.clear() ;
- mEmptyAtlasMap.clear() ;
-}
-
-//return TRUE if qualified
-BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target)
-{
- if(ncomponents < 1 || ncomponents > 4)
- {
- return FALSE ;
- }
- //only support GL_TEXTURE_2D
- if(GL_TEXTURE_2D != target)
- {
- return FALSE ;
- }
- //real image size overflows
- if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize)
- {
- return FALSE ;
- }
-
- //if non-power-of-two number
- if((w & (w - 1)) || (h & (h - 1)))
- {
- return FALSE ;
- }
-
- return TRUE ;
-}
-
-void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp)
-{
- LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ;
- while(groupp)
- {
- groupp->removeAtlas(atlasp, FALSE) ;
- atlasp->removeLastSpatialGroup() ;
-
- groupp = atlasp->getLastSpatialGroup() ;
- }
-
- S8 type = atlasp->getComponents() - 1 ;
- //insert to the empty list
- if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS)
- {
- mEmptyAtlasMap[type].push_back(atlasp) ;
- }
-
- //delete the atlasp
- mAtlasMap[type].remove(atlasp) ;
-}
-
-//
-//this function reserves an appropriate slot from atlas pool for an image.
-//return non-NULL if succeeds.
-//Note:
-//1, this function does not check if the image this slot assigned for qualifies for atlas or not,
-// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function.
-//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway.
-//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching.
-//
-LLPointer<LLTextureAtlasSlot> LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents,
- LLSpatialGroup* groupp, LLViewerTexture* imagep)
-{
- if(!groupp)
- {
- //do not insert to atlas if does not have a group.
- return NULL ;
- }
-
- //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8.
- if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize)
- {
- sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ;
- }
- S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ;
- if(bits_len < 1)
- {
- bits_len = 1 ;
- }
-
- S16 col = -1, row = -1;
- S8 total_bits = bits_len * bits_len ;
-
- //insert to the atlas reserved by the same spatial group
- LLPointer<LLTextureAtlas> atlasp = groupp->getAtlas(ncomponents, total_bits) ;
- if(atlasp.notNull())
- {
- if(!atlasp->getNextAvailableSlot(bits_len, col, row))
- {
- //failed
- atlasp = NULL ;
- }
- }
-
- //search an atlas to fit for 'size'
- if(!atlasp)
- {
- S8 atlas_index = ncomponents - 1 ;
- ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ;
- for(; iter != mAtlasMap[atlas_index].end(); ++iter)
- {
- LLTextureAtlas* cur = (LLTextureAtlas*)*iter ;
- if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary.
- {
- if(cur->getNextAvailableSlot(bits_len, col, row))
- {
- atlasp = cur ;
- groupp->addAtlas(atlasp) ;
- break ;
- }
- }
- }
- }
-
- //create a new atlas if necessary
- if(!atlasp)
- {
- if(mEmptyAtlasMap[ncomponents - 1].size() > 0)
- {
- //there is an empty one
- atlasp = mEmptyAtlasMap[ncomponents - 1].back() ;
- mEmptyAtlasMap[ncomponents - 1].pop_back() ;
- }
- else
- {
- atlasp = new LLTextureAtlas(ncomponents, 16) ;
- }
- mAtlasMap[ncomponents - 1].push_back(atlasp) ;
- atlasp->getNextAvailableSlot(bits_len, col, row) ;
- groupp->addAtlas(atlasp) ;
- }
-
- F32 xoffset, yoffset ;
- atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ;
- LLPointer<LLTextureAtlasSlot> slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ;
-
- return slot_infop ;
-}
-
-//*********************************************************************************************
-//END of implementation of class LLTextureAtlasManager
-//*********************************************************************************************
diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h
deleted file mode 100644
index 1b8df708c6..0000000000
--- a/indra/newview/lltextureatlasmanager.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file lltextureatlasmanager.h
- * @brief LLTextureAtlasManager base class.
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#ifndef LL_TEXTUREATLASMANAGER_H
-#define LL_TEXTUREATLASMANAGER_H
-
-#include "llmemory.h"
-
-class LLSpatialGroup ;
-class LLViewerTexture ;
-
-//just use it as a structure.
-class LLTextureAtlasSlot : public LLRefCount
-{
-public:
- LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ;
-
-protected:
- virtual ~LLTextureAtlasSlot();
-
-public:
-
- //
- //do not allow to change those values
- //
- //void setAtlas(LLTextureAtlas* atlasp) ;
- //void setSlotPos(S16 col, S16 row) ;
- //void setSlotWidth(S8 width) ;
- //void setTexCoordOffset(F32 xoffser, F32 yoffset) ;
- //
-
- void setSpatialGroup(LLSpatialGroup* groupp) ;
- void setTexCoordScale(F32 xscale, F32 yscale) ;
- void setValid() {mValid = TRUE ;}
-
- LLTextureAtlas* getAtlas()const {return mAtlasp;}
- LLSpatialGroup* getSpatialGroup() const {return mGroupp ;}
- S16 getSlotCol()const {return mCol;}
- S16 getSlotRow()const {return mRow;}
- S8 getSlotWidth()const{return mReservedSlotWidth;}
- BOOL isValid()const { return mValid;}
- const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;}
- const LLVector2* getTexCoordScale() const {return &mTexCoordScale;}
-
- void setUpdatedTime(U32 t) {mUpdatedTime = t;}
- U32 getUpdatedTime()const {return mUpdatedTime;}
-
-private:
- LLTextureAtlas* mAtlasp;
- S16 mCol ;//col of the slot
- S16 mRow ;//row of the slot
- S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number
- LLSpatialGroup* mGroupp ;
- BOOL mValid ;
-
- LLVector2 mTexCoordOffset ;
- LLVector2 mTexCoordScale ;
-
- U32 mUpdatedTime ;
-} ;
-
-class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager>
-{
- LLSINGLETON(LLTextureAtlasManager);
- ~LLTextureAtlasManager();
- typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ;
-
-public:
-
- LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents,
- LLSpatialGroup* groupp, LLViewerTexture* imagep) ;
- void releaseAtlas(LLTextureAtlas* atlasp);
-
- BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ;
-
-private:
- std::vector<ll_texture_atlas_list_t> mAtlasMap ;
- std::vector<ll_texture_atlas_list_t> mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately.
-};
-
-#endif
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/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index f01b374db1..6216899dc6 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -529,8 +529,8 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask)
const F32 RADIANS_PER_PIXEL_X = 0.01f;
const F32 RADIANS_PER_PIXEL_Y = 0.01f;
- S32 dx = x - (gViewerWindow->getWorldViewWidthScaled() / 2);
- S32 dy = y - (gViewerWindow->getWorldViewHeightScaled() / 2);
+ S32 dx = gViewerWindow->getCurrentMouseDX();
+ S32 dy = gViewerWindow->getCurrentMouseDY();
if (dx != 0 || dy != 0)
{
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 06a2caf75b..b2e8348ffd 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -195,10 +195,7 @@ BOOL LLVisualParamHint::render()
gGL.pushMatrix();
gGL.loadIdentity();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
LLGLSUIDefault gls_ui;
//LLGLState::verify(TRUE);
@@ -247,11 +244,11 @@ BOOL LLVisualParamHint::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
- gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS);
+ gGL.flush();
gGL.setSceneBlendType(LLRender::BT_REPLACE);
avatarPoolp->renderAvatars(gAgentAvatarp); // renders only one avatar
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
gAgentAvatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
mWearablePtr->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 27a87ee1a0..5d8e80cc41 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -81,9 +81,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 bc425123e1..e53f988c6e 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();
+ 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)
@@ -162,17 +166,6 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
return true;
}
-static bool handleAvatarVPChanged(const LLSD& newvalue)
-{
- LLRenderTarget::sUseFBO = newvalue.asBoolean()
- && gSavedSettings.getBOOL("RenderObjectBump")
- && gSavedSettings.getBOOL("RenderTransparentWater")
- && gSavedSettings.getBOOL("RenderDeferred");
-
- handleSetShaderChanged(LLSD());
- return true;
-}
-
static bool handleRenderPerfTestChanged(const LLSD& newvalue)
{
bool status = !newvalue.asBoolean();
@@ -212,10 +205,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
{
- LLRenderTarget::sUseFBO = newvalue.asBoolean()
- && gSavedSettings.getBOOL("RenderObjectBump")
- && gSavedSettings.getBOOL("RenderAvatarVP")
- && gSavedSettings.getBOOL("RenderDeferred");
if (gPipeline.isInit())
{
gPipeline.updateRenderTransparentWater();
@@ -269,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);
@@ -391,7 +388,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
@@ -468,10 +465,7 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue)
//
static bool handleRenderBumpChanged(const LLSD& newval)
{
- LLRenderTarget::sUseFBO = newval.asBoolean()
- && gSavedSettings.getBOOL("RenderTransparentWater")
- && gSavedSettings.getBOOL("RenderAvatarVP")
- && gSavedSettings.getBOOL("RenderDeferred");
+ LLRenderTarget::sUseFBO = newval.asBoolean() && gSavedSettings.getBOOL("RenderDeferred");
if (gPipeline.isInit())
{
gPipeline.updateRenderBump();
@@ -665,7 +659,6 @@ void settings_setup_listeners()
gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleAvatarVPChanged, _2));
gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2));
gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
@@ -696,6 +689,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..c84a8c70fa 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;
}
@@ -165,8 +166,6 @@ void display_startup()
if (gViewerWindow)
gViewerWindow->setup2DRender();
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
gGL.color4f(1,1,1,1);
if (gViewerWindow)
gViewerWindow->draw();
@@ -208,9 +207,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 +220,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 +230,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 +312,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)
@@ -572,8 +576,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
//
LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
- LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
- LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);
+ if (LLViewerCamera::instanceExists())
+ {
+ LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
+ LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);
+ }
//////////////////////////
//
@@ -630,6 +637,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
@@ -675,21 +683,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
- S32 water_clip = 0;
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
- (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||
- gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
- {
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- water_clip = -1;
- }
- else
- {
- water_clip = 1;
- }
- }
-
LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
//Increment drawable frame counter
@@ -707,21 +700,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
static LLCullResult result;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
- gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
+ gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
stop_glerror();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
-
+
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
{
+ LL_PROFILE_ZONE_NAMED("display - 2")
if (gResizeScreenTexture)
{
gResizeScreenTexture = FALSE;
@@ -733,7 +725,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
if (!for_snapshot)
{
@@ -747,7 +738,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
@@ -766,17 +756,16 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
}
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
LLGLState::checkStates();
- LLGLState::checkClientArrays();
//if (!for_snapshot)
{
+ LL_PROFILE_ZONE_NAMED("display - 3")
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
gPipeline.generateHighlight(*LLViewerCamera::getInstance());
@@ -784,7 +773,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
LLGLState::checkStates();
- LLGLState::checkClientArrays();
//////////////////////////////////////
//
@@ -800,13 +788,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,10 +809,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLImageGL::deleteDeadTextures();
stop_glerror();
}*/
- }
+ }
LLGLState::checkStates();
- LLGLState::checkClientArrays();
///////////////////////////////////
//
@@ -840,6 +823,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();
@@ -859,7 +843,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLSceneMonitor::getInstance()->fetchQueryResult();
LLGLState::checkStates();
- LLGLState::checkClientArrays();
LLPipeline::sUseOcclusion = occlusion;
@@ -918,7 +901,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
LLGLState::checkStates();
- LLGLState::checkClientArrays();
stop_glerror();
@@ -948,9 +930,10 @@ 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)
+ if (gSavedSettings.getBOOL("RenderDepthPrePass"))
{
gGL.setColorMask(false, false);
@@ -1259,7 +1242,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 +1257,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 +1264,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();
- {
- gGL.color4f(1,1,1,1);
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ LLGLSDefault gls_default;
+ LLGLSUIDefault gls_ui;
{
- if (!gDisconnected)
+ gPipeline.disableLights();
+ }
+
+ {
+ 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");
@@ -1435,10 +1423,7 @@ void render_ui_3d()
stop_glerror();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
// Coordinate axes
if (gSavedSettings.getBOOL("ShowAxes"))
@@ -1478,7 +1463,6 @@ void render_ui_2d()
}
stop_glerror();
- //gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
// render outline for HUD
if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f)
@@ -1568,10 +1552,7 @@ void render_ui_2d()
void render_disconnected_background()
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gGL.color4f(1,1,1,1);
if (!gDisconnectedImagep && gDisconnected)
@@ -1643,11 +1624,7 @@ void render_disconnected_background()
}
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
-
+ gUIProgram.unbind();
}
void display_cleanup()
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 62d73063aa..dd03d6cfdd 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -193,6 +193,10 @@ LLFloaterOpenHandler gFloaterOpenHandler;
void LLViewerFloaterReg::registerFloaters()
{
+ if (gNonInteractive)
+ {
+ return;
+ }
// *NOTE: Please keep these alphabetized for easier merges
LLFloaterAboutUtil::registerFloater();
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 8a597ed7e6..fd314ed3dc 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -121,8 +121,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
object->mDrawable->mXform.setRotation(current_rot);
gPipeline.markMoved(object->mDrawable);
gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
- object->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
-
+
if(mIsHUDAttachment)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
@@ -142,7 +141,6 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->setState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
gPipeline.markMoved(childp->mDrawable);
@@ -256,7 +254,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
object->mDrawable->mXform.setRotation(cur_rotation);
gPipeline.markMoved(object->mDrawable, TRUE);
gPipeline.markTextured(object->mDrawable); // face may need to change draw pool to/from POOL_HUD
- object->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
if (mIsHUDAttachment)
{
@@ -278,7 +275,6 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
LLViewerObject* childp = *iter;
if (childp && childp->mDrawable.notNull())
{
- childp->mDrawable->clearState(LLDrawable::USE_BACKLIGHT);
gPipeline.markTextured(childp->mDrawable); // face may need to change draw pool to/from POOL_HUD
if (mIsHUDAttachment)
{
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 63ad708e59..f3b0e82b3a 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -225,7 +225,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
if (!mValid || !mMesh || !mFace || !mVisible ||
!mFace->getVertexBuffer() ||
mMesh->getNumFaces() == 0 ||
- (LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShaderPtr == NULL))
+ LLGLSLShader::sCurBoundShaderPtr == NULL)
{
return 0;
}
@@ -246,7 +246,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
stop_glerror();
- LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getShaderLevel() > 0 || LLGLSLShader::sNoFixedFunction) ? 0.f : mShiny);
+ LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), 0.f);
//----------------------------------------------------------------
// setup current texture
@@ -265,7 +265,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
else
{
gGL.diffuseColor4f(0.7f, 0.6f, 0.3f, 1.f);
- gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
}
}
else if( !is_dummy && layerset )
@@ -328,11 +327,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
triangle_count += count;
- if (mTestImageName)
- {
- gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
-
return triangle_count;
}
@@ -362,7 +356,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 +376,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 54c2099ac9..0a0a3f905a 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 01a4bd587d..47f0a43884 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8370,6 +8370,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 14442c9705..22e5907b14 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2219,11 +2219,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;
@@ -2423,6 +2421,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;
@@ -3263,10 +3265,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
@@ -3447,7 +3448,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);
@@ -3697,11 +3697,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 31e80eb865..a2d3f2c0cf 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),
@@ -2501,9 +2515,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..b5bf4f0354 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -32,6 +32,7 @@
#include "llappviewer.h"
#include "llglslshader.h"
#include "llviewershadermgr.h"
+#include "lldrawpoolwater.h"
//-----------------------------------------------------------------------------------
//static variables definitions
@@ -231,8 +232,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 +458,7 @@ LLViewerOctreeGroup::~LLViewerOctreeGroup()
}
LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)
-: LLTrace::MemTrackable<LLViewerOctreeGroup, 16>("LLViewerOctreeGroup"),
- mOctreeNode(node),
+: mOctreeNode(node),
mAnyVisible(0),
mState(CLEAN)
{
@@ -517,6 +516,7 @@ bool LLViewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry)
//virtual
void LLViewerOctreeGroup::unbound()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isDirty())
{
return;
@@ -545,6 +545,7 @@ void LLViewerOctreeGroup::unbound()
//virtual
void LLViewerOctreeGroup::rebound()
{
+ LL_PROFILE_ZONE_SCOPED;
if (!isDirty())
{
return;
@@ -932,47 +933,53 @@ void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
}
}
-void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode)
-{
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialSetOcclusionStateDiff setter(state);
- setter.traverse(mOctreeNode);
- }
- else if (mode == STATE_MODE_BRANCH)
- {
- LLSpatialSetOcclusionState setter(state);
- setter.traverse(mOctreeNode);
- }
- else
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mOcclusionState[i] |= state;
-
- if ((state & DISCARD_QUERY) && mOcclusionQuery[i])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
- }
- }
- }
- else
- {
- if (state & OCCLUDED)
- {
- add(sNumObjectsOccluded, 1);
- }
- mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
- if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
- }
+void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */ )
+{
+ switch (mode)
+ {
+ case STATE_MODE_SINGLE:
+ if (state & OCCLUDED)
+ {
+ add(sNumObjectsOccluded, 1);
+ }
+ mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
+ if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
+ }
+ break;
+
+ case STATE_MODE_DIFF:
+ {
+ LLSpatialSetOcclusionStateDiff setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_BRANCH:
+ {
+ LLSpatialSetOcclusionState setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_ALL_CAMERAS:
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mOcclusionState[i] |= state;
+
+ if ((state & DISCARD_QUERY) && mOcclusionQuery[i])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
}
class LLSpatialClearOcclusionState : public OctreeTraveler
@@ -1007,43 +1014,47 @@ public:
}
};
-void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode)
-{
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialClearOcclusionStateDiff clearer(state);
- clearer.traverse(mOctreeNode);
- }
- else if (mode == STATE_MODE_BRANCH)
- {
- LLSpatialClearOcclusionState clearer(state);
- clearer.traverse(mOctreeNode);
- }
- else
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mOcclusionState[i] &= ~state;
- }
- }
- }
- else
- {
- if (state & OCCLUDED)
- {
- add(sNumObjectsUnoccluded, 1);
- }
- mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
- }
+void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */)
+{
+ switch (mode)
+ {
+ case STATE_MODE_SINGLE:
+ if (state & OCCLUDED)
+ {
+ add(sNumObjectsUnoccluded, 1);
+ }
+ mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
+ break;
+
+ case STATE_MODE_DIFF:
+ {
+ LLSpatialClearOcclusionStateDiff clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_BRANCH:
+ {
+ LLSpatialClearOcclusionState clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_ALL_CAMERAS:
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mOcclusionState[i] &= ~state;
+ }
+ break;
+
+ default:
+ break;
+ }
}
-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;
@@ -1092,100 +1103,82 @@ U32 LLOcclusionCullingGroup::getLastOcclusionIssuedTime()
void LLOcclusionCullingGroup::checkOcclusion()
{
- if (LLPipeline::sUseOcclusion > 1)
- {
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_READBACK);
- LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent();
- if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
- { //if the parent has been marked as occluded, the child is implicitly occluded
- clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
- }
- else if (isOcclusionState(QUERY_PENDING))
- { //otherwise, if a query is pending, read it back
-
- GLuint available = 0;
- if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- 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
- {
- available = 1;
- }
-
- if (available)
- { //result is available, read it back, otherwise wait until next frame
- GLuint res = 1;
- if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
+ if (LLPipeline::sUseOcclusion < 2) return; // 0 - NoOcclusion, 1 = ReadOnly, 2 = ModifyOcclusionState TODO: DJH 11-2021 ENUM this
+
+ 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
+ clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
+ return;
+ }
+
+ if (mOcclusionQuery[LLViewerCamera::sCurCameraID] && isOcclusionState(QUERY_PENDING))
+ {
+ if (isOcclusionState(DISCARD_QUERY))
+ { // delete the query to avoid holding onto hundreds of pending queries
+ releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
+ // mark non-occluded
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
+ }
+ else
+ {
+ GLuint available;
+ {
+ LL_PROFILE_ZONE_NAMED("co - query available");
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ }
+
+ if (available)
+ {
+ GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
+ {
+ LL_PROFILE_ZONE_NAMED("co - query result");
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result);
+ }
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
- sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
- }
- else if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
- { //delete the query to avoid holding onto hundreds of pending queries
- releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
-
- if (isOcclusionState(DISCARD_QUERY))
- {
- res = 2;
- }
- if (res > 0)
- {
- assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- else
- {
- assert_states_valid(this);
-
- setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
-
- assert_states_valid(this);
- }
-
- clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
- }
- }
- else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
- { //check occlusion has been issued for occluded node that has not had a query issued
- assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- }
+#if 0 // (12/2021) occasional false-negative occlusion tests produce water reflection errors, SL-16461
+ // If/when water occlusion queries become 100% reliable, re-enable this optimization
+
+ if (LLPipeline::RENDER_TYPE_WATER == mSpatialPartition->mDrawableType)
+ {
+ // Note any unoccluded water, for deciding on reflection/distortion passes
+ // (If occlusion is disabled, these are set within LLDrawPoolWater::render)
+ if (query_result > 0)
+ {
+ LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
+ LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
+ }
+ }
+#endif
+ if (query_result > 0)
+ {
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ }
+ else
+ {
+ setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ }
+ clearOcclusionState(QUERY_PENDING);
+ }
+ }
+ }
+ else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
+ { //check occlusion has been issued for occluded node that has not had a query issued
+ assert_states_valid(this);
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ assert_states_valid(this);
+ }
}
-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
@@ -1198,7 +1191,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
}
F32 OCCLUSION_FUDGE_Z = SG_OCCLUSION_FUDGE; //<-- #Solution #2
- if (LLDrawPool::POOL_WATER == mSpatialPartition->mDrawableType)
+ if (LLPipeline::RENDER_TYPE_VOIDWATER == mSpatialPartition->mDrawableType)
{
OCCLUSION_FUDGE_Z = 1.;
}
@@ -1206,7 +1199,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 +1210,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();
}
@@ -1229,8 +1221,8 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
- (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
- mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
+ (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
+ mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
@@ -1246,15 +1238,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);
@@ -1264,9 +1253,9 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
bounds[1][1]+SG_OCCLUSION_FUDGE,
bounds[1][2]+OCCLUSION_FUDGE_Z);
- if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
+ if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER)
{
- LL_RECORD_BLOCK_TIME(FTM_OCCLUSION_DRAW_WATER);
+ LL_PROFILE_ZONE_NAMED("doOcclusion - draw water");
LLGLSquashToFarClip squash;
if (camera->getOrigin().isExactlyZero())
@@ -1281,7 +1270,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 +1281,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..c97b1d914b 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -77,6 +77,7 @@ LLGLSLShader gTransformTangentProgram;
//utility shaders
LLGLSLShader gOcclusionProgram;
+LLGLSLShader gSkinnedOcclusionProgram;
LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
@@ -87,6 +88,7 @@ LLGLSLShader gTwoTextureCompareProgram;
LLGLSLShader gOneTextureFilterProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
+LLGLSLShader gSkinnedDebugProgram;
LLGLSLShader gClipProgram;
LLGLSLShader gDownsampleDepthProgram;
LLGLSLShader gDownsampleDepthRectProgram;
@@ -96,56 +98,49 @@ LLGLSLShader gBenchmarkProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
+LLGLSLShader gSkinnedObjectSimpleProgram;
LLGLSLShader gObjectSimpleImpostorProgram;
+LLGLSLShader gSkinnedObjectSimpleImpostorProgram;
LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gObjectSimpleWaterProgram;
+LLGLSLShader gSkinnedObjectSimpleWaterProgram;
LLGLSLShader gObjectSimpleAlphaMaskProgram;
+LLGLSLShader gSkinnedObjectSimpleAlphaMaskProgram;
LLGLSLShader gObjectSimpleWaterAlphaMaskProgram;
+LLGLSLShader gSkinnedObjectSimpleWaterAlphaMaskProgram;
LLGLSLShader gObjectFullbrightProgram;
+LLGLSLShader gSkinnedObjectFullbrightProgram;
LLGLSLShader gObjectFullbrightWaterProgram;
+LLGLSLShader gSkinnedObjectFullbrightWaterProgram;
LLGLSLShader gObjectEmissiveProgram;
+LLGLSLShader gSkinnedObjectEmissiveProgram;
LLGLSLShader gObjectEmissiveWaterProgram;
+LLGLSLShader gSkinnedObjectEmissiveWaterProgram;
LLGLSLShader gObjectFullbrightAlphaMaskProgram;
+LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram;
+LLGLSLShader gSkinnedObjectFullbrightWaterAlphaMaskProgram;
LLGLSLShader gObjectFullbrightShinyProgram;
+LLGLSLShader gSkinnedObjectFullbrightShinyProgram;
LLGLSLShader gObjectFullbrightShinyWaterProgram;
+LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram;
LLGLSLShader gObjectShinyProgram;
+LLGLSLShader gSkinnedObjectShinyProgram;
LLGLSLShader gObjectShinyWaterProgram;
+LLGLSLShader gSkinnedObjectShinyWaterProgram;
LLGLSLShader gObjectBumpProgram;
+LLGLSLShader gSkinnedObjectBumpProgram;
LLGLSLShader gTreeProgram;
LLGLSLShader gTreeWaterProgram;
LLGLSLShader gObjectFullbrightNoColorProgram;
LLGLSLShader gObjectFullbrightNoColorWaterProgram;
-LLGLSLShader gObjectSimpleNonIndexedProgram;
LLGLSLShader gObjectSimpleNonIndexedTexGenProgram;
LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram;
-LLGLSLShader gObjectSimpleNonIndexedWaterProgram;
LLGLSLShader gObjectAlphaMaskNonIndexedProgram;
LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram;
LLGLSLShader gObjectAlphaMaskNoColorProgram;
LLGLSLShader gObjectAlphaMaskNoColorWaterProgram;
-LLGLSLShader gObjectFullbrightNonIndexedProgram;
-LLGLSLShader gObjectFullbrightNonIndexedWaterProgram;
-LLGLSLShader gObjectEmissiveNonIndexedProgram;
-LLGLSLShader gObjectEmissiveNonIndexedWaterProgram;
-LLGLSLShader gObjectFullbrightShinyNonIndexedProgram;
-LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram;
-LLGLSLShader gObjectShinyNonIndexedProgram;
-LLGLSLShader gObjectShinyNonIndexedWaterProgram;
-
-//object hardware skinning shaders
-LLGLSLShader gSkinnedObjectSimpleProgram;
-LLGLSLShader gSkinnedObjectFullbrightProgram;
-LLGLSLShader gSkinnedObjectEmissiveProgram;
-LLGLSLShader gSkinnedObjectFullbrightShinyProgram;
-LLGLSLShader gSkinnedObjectShinySimpleProgram;
-
-LLGLSLShader gSkinnedObjectSimpleWaterProgram;
-LLGLSLShader gSkinnedObjectFullbrightWaterProgram;
-LLGLSLShader gSkinnedObjectEmissiveWaterProgram;
-LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram;
-LLGLSLShader gSkinnedObjectShinySimpleWaterProgram;
//environment shaders
LLGLSLShader gTerrainProgram;
@@ -156,6 +151,7 @@ LLGLSLShader gUnderWaterProgram;
//interface shaders
LLGLSLShader gHighlightProgram;
+LLGLSLShader gSkinnedHighlightProgram;
LLGLSLShader gHighlightNormalProgram;
LLGLSLShader gHighlightSpecularProgram;
@@ -191,17 +187,18 @@ LLGLSLShader gDeferredWaterProgram;
LLGLSLShader gDeferredUnderWaterProgram;
LLGLSLShader gDeferredDiffuseProgram;
LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseProgram;
LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
LLGLSLShader gDeferredSkinnedDiffuseProgram;
LLGLSLShader gDeferredSkinnedBumpProgram;
-LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredBumpProgram;
LLGLSLShader gDeferredTerrainProgram;
LLGLSLShader gDeferredTerrainWaterProgram;
LLGLSLShader gDeferredTreeProgram;
LLGLSLShader gDeferredTreeShadowProgram;
+LLGLSLShader gDeferredSkinnedTreeShadowProgram;
LLGLSLShader gDeferredAvatarProgram;
LLGLSLShader gDeferredAvatarAlphaProgram;
LLGLSLShader gDeferredLightProgram;
@@ -213,9 +210,12 @@ LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
LLGLSLShader gDeferredSoftenWaterProgram;
LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredSkinnedShadowProgram;
LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram;
LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAvatarAlphaShadowProgram;
LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
@@ -223,14 +223,20 @@ LLGLSLShader gDeferredAttachmentShadowProgram;
LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredAlphaImpostorProgram;
+LLGLSLShader gDeferredSkinnedAlphaImpostorProgram;
LLGLSLShader gDeferredAlphaWaterProgram;
+LLGLSLShader gDeferredSkinnedAlphaWaterProgram;
LLGLSLShader gDeferredAvatarEyesProgram;
LLGLSLShader gDeferredFullbrightProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredFullbrightWaterProgram;
+LLGLSLShader gDeferredSkinnedFullbrightWaterProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
+LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredEmissiveProgram;
+LLGLSLShader gDeferredSkinnedEmissiveProgram;
LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
LLGLSLShader gDeferredDoFCombineProgram;
@@ -243,14 +249,31 @@ LLGLSLShader gDeferredWLSunProgram;
LLGLSLShader gDeferredWLMoonProgram;
LLGLSLShader gDeferredStarProgram;
LLGLSLShader gDeferredFullbrightShinyProgram;
-LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
+LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
+LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+//helper for making a rigged variant of a given shader
+bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
+{
+ riggedShader.mName = llformat("Skinned %s", shader.mName.c_str());
+ riggedShader.mFeatures = shader.mFeatures;
+ riggedShader.mFeatures.hasObjectSkinning = true;
+ riggedShader.mDefines = shader.mDefines; // NOTE: Must come before addPermutation
+ riggedShader.addPermutation("HAS_SKIN", "1");
+ riggedShader.mShaderFiles = shader.mShaderFiles;
+ riggedShader.mShaderLevel = shader.mShaderLevel;
+ riggedShader.mShaderGroup = shader.mShaderGroup;
+
+ shader.mRiggedVariant = &riggedShader;
+ return riggedShader.createShader(NULL, NULL);
+}
+
LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
@@ -263,75 +286,77 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gWLMoonProgram);
mShaderList.push_back(&gAvatarProgram);
mShaderList.push_back(&gObjectShinyProgram);
- mShaderList.push_back(&gObjectShinyNonIndexedProgram);
+ mShaderList.push_back(&gSkinnedObjectShinyProgram);
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gObjectSimpleProgram);
+ mShaderList.push_back(&gSkinnedObjectSimpleProgram);
mShaderList.push_back(&gObjectSimpleImpostorProgram);
+ mShaderList.push_back(&gSkinnedObjectSimpleImpostorProgram);
mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectFullbrightNoColorProgram);
mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram);
mShaderList.push_back(&gObjectSimpleAlphaMaskProgram);
+ mShaderList.push_back(&gSkinnedObjectSimpleAlphaMaskProgram);
mShaderList.push_back(&gObjectBumpProgram);
+ mShaderList.push_back(&gSkinnedObjectBumpProgram);
mShaderList.push_back(&gObjectEmissiveProgram);
+ mShaderList.push_back(&gSkinnedObjectEmissiveProgram);
mShaderList.push_back(&gObjectEmissiveWaterProgram);
+ mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram);
mShaderList.push_back(&gObjectFullbrightProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightProgram);
mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
mShaderList.push_back(&gObjectFullbrightShinyProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram);
mShaderList.push_back(&gObjectFullbrightShinyWaterProgram);
- mShaderList.push_back(&gObjectSimpleNonIndexedProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram);
mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram);
mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram);
- mShaderList.push_back(&gObjectSimpleNonIndexedWaterProgram);
mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram);
mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram);
mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);
mShaderList.push_back(&gTreeProgram);
mShaderList.push_back(&gTreeWaterProgram);
- mShaderList.push_back(&gObjectFullbrightNonIndexedProgram);
- mShaderList.push_back(&gObjectFullbrightNonIndexedWaterProgram);
- mShaderList.push_back(&gObjectEmissiveNonIndexedProgram);
- mShaderList.push_back(&gObjectEmissiveNonIndexedWaterProgram);
- mShaderList.push_back(&gObjectFullbrightShinyNonIndexedProgram);
- mShaderList.push_back(&gObjectFullbrightShinyNonIndexedWaterProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightProgram);
- mShaderList.push_back(&gSkinnedObjectEmissiveProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram);
- mShaderList.push_back(&gSkinnedObjectShinySimpleProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram);
- mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram);
- mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram);
mShaderList.push_back(&gTerrainProgram);
mShaderList.push_back(&gTerrainWaterProgram);
mShaderList.push_back(&gObjectSimpleWaterProgram);
+ mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram);
mShaderList.push_back(&gObjectFullbrightWaterProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram);
mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram);
+ mShaderList.push_back(&gSkinnedObjectSimpleWaterAlphaMaskProgram);
mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram);
+ mShaderList.push_back(&gSkinnedObjectFullbrightWaterAlphaMaskProgram);
mShaderList.push_back(&gAvatarWaterProgram);
mShaderList.push_back(&gObjectShinyWaterProgram);
- mShaderList.push_back(&gObjectShinyNonIndexedWaterProgram);
+ mShaderList.push_back(&gSkinnedObjectShinyWaterProgram);
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
mShaderList.push_back(&gDeferredSoftenWaterProgram);
mShaderList.push_back(&gDeferredAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredAlphaImpostorProgram);
+ mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
mShaderList.push_back(&gDeferredAlphaWaterProgram);
- mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
mShaderList.push_back(&gDeferredFullbrightWaterProgram);
- mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
mShaderList.push_back(&gDeferredFullbrightShinyProgram);
- mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
+ mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
mShaderList.push_back(&gDeferredUnderWaterProgram);
@@ -384,7 +409,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
S32 LLViewerShaderMgr::getShaderLevel(S32 type)
{
- return LLPipeline::sDisableShaders ? 0 : mShaderLevel[type];
+ return mShaderLevel[type];
}
//============================================================================
@@ -400,15 +425,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 +449,7 @@ void LLViewerShaderMgr::setShaders()
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
+ LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater;
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
LLPipeline::updateRenderDeferred();
@@ -458,7 +474,6 @@ void LLViewerShaderMgr::setShaders()
}
mMaxAvatarShaderLevel = 0;
- LLGLSLShader::sNoFixedFunction = false;
LLVertexBuffer::unbind();
llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
@@ -467,10 +482,7 @@ void LLViewerShaderMgr::setShaders()
bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred") && gSavedSettings.getBOOL("RenderAvatarVP");
-
- //using shaders, disable fixed function
- LLGLSLShader::sNoFixedFunction = true;
+ bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred");
S32 light_class = 3;
S32 interface_class = 2;
@@ -543,192 +555,168 @@ void LLViewerShaderMgr::setShaders()
}
else
{
- LL_WARNS() << "Failed to load basic shaders." << LL_ENDL;
+ LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL;
llassert(loaded);
+ reentrance = false; // For hygiene only, re-try probably helps nothing
+ return;
}
+ gPipeline.mShadersLoaded = true;
+
+ // Load all shaders to set max levels
+ loaded = loadShadersEnvironment();
+
if (loaded)
{
- gPipeline.mVertexShadersEnabled = TRUE;
- gPipeline.mVertexShadersLoaded = 1;
-
- // Load all shaders to set max levels
- loaded = loadShadersEnvironment();
+ LL_INFOS() << "Loaded environment shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load environment shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ if (loaded)
+ {
+ loaded = loadShadersWater();
if (loaded)
{
- LL_INFOS() << "Loaded environment shaders." << LL_ENDL;
+ LL_INFOS() << "Loaded water shaders." << LL_ENDL;
}
else
{
- LL_WARNS() << "Failed to load environment shaders." << LL_ENDL;
+ LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
llassert(loaded);
}
+ }
+ if (loaded)
+ {
+ loaded = loadShadersWindLight();
if (loaded)
{
- loaded = loadShadersWater();
- if (loaded)
- {
- LL_INFOS() << "Loaded water shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
- llassert(loaded);
- }
+ LL_INFOS() << "Loaded windlight shaders." << LL_ENDL;
}
-
- if (loaded)
+ else
{
- loaded = loadShadersWindLight();
- if (loaded)
- {
- LL_INFOS() << "Loaded windlight shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL;
- llassert(loaded);
- }
+ LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL;
+ llassert(loaded);
}
+ }
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
if (loaded)
{
- loaded = loadShadersEffects();
- if (loaded)
- {
- LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
- llassert(loaded);
- }
+ LL_INFOS() << "Loaded effects shaders." << LL_ENDL;
}
-
- if (loaded)
+ else
{
- loaded = loadShadersInterface();
- if (loaded)
- {
- LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
- llassert(loaded);
- }
+ LL_WARNS() << "Failed to load effects shaders." << LL_ENDL;
+ llassert(loaded);
}
+ }
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
if (loaded)
-
{
- loaded = loadTransformShaders();
- if (loaded)
- {
- LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
- llassert(loaded);
- }
+ LL_INFOS() << "Loaded interface shaders." << LL_ENDL;
}
+ else
+ {
+ LL_WARNS() << "Failed to load interface shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ loaded = loadTransformShaders();
if (loaded)
{
- // Load max avatar shaders to set the max level
- mShaderLevel[SHADER_AVATAR] = 3;
- mMaxAvatarShaderLevel = 3;
+ LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
+ llassert(loaded);
+ }
+ }
+
+ if (loaded)
+ {
+ // Load max avatar shaders to set the max level
+ mShaderLevel[SHADER_AVATAR] = 3;
+ mMaxAvatarShaderLevel = 3;
- if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ if (loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
+ BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
- // cloth is a class3 shader
- S32 avatar_class = avatar_cloth ? 3 : 1;
+ // cloth is a class3 shader
+ S32 avatar_class = avatar_cloth ? 3 : 1;
- // Set the actual level
- mShaderLevel[SHADER_AVATAR] = avatar_class;
+ // Set the actual level
+ mShaderLevel[SHADER_AVATAR] = avatar_class;
- loaded = loadShadersAvatar();
- llassert(loaded);
+ loaded = loadShadersAvatar();
+ llassert(loaded);
- if (mShaderLevel[SHADER_AVATAR] != avatar_class)
+ if (mShaderLevel[SHADER_AVATAR] != avatar_class)
+ {
+ if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)
{
- if (mShaderLevel[SHADER_AVATAR] == 0)
- {
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
- }
- if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)
- {
- avatar_cloth = true;
- }
- else
- {
- avatar_cloth = false;
- }
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
+ avatar_cloth = true;
}
- }
- else
- { //hardware skinning not possible, neither is deferred rendering
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_DEFERRED] = 0;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP"))
+ else
{
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ avatar_cloth = false;
}
-
- loadShadersAvatar(); // unloads
-
- loaded = loadShadersObject();
- llassert(loaded);
+ gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
}
}
+ else
+ { //hardware skinning not possible, neither is deferred rendering
+ mShaderLevel[SHADER_AVATAR] = 0;
+ mShaderLevel[SHADER_DEFERRED] = 0;
- if (!loaded)
- { //some shader absolutely could not load, try to fall back to a simpler setting
- if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
- { //disable windlight and try again
- gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
- LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
- }
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
- llassert(loaded);
+ loadShadersAvatar(); // unloads
+
+ loaded = loadShadersObject();
+ llassert(loaded);
+ }
+ }
- if (loaded && !loadShadersDeferred())
- { //everything else succeeded but deferred failed, disable deferred and try again
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL;
+ if (!loaded)
+ { //some shader absolutely could not load, try to fall back to a simpler setting
+ if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
+ { //disable windlight and try again
+ gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
+ LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL;
reentrance = false;
setShaders();
return;
}
+ }
+
+ llassert(loaded);
+
+ if (loaded && !loadShadersDeferred())
+ { //everything else succeeded but deferred failed, disable deferred and try again
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL;
+ reentrance = false;
+ setShaders();
+ return;
}
- else
- {
- LLGLSLShader::sNoFixedFunction = false;
- gPipeline.mVertexShadersEnabled = FALSE;
- gPipeline.mVertexShadersLoaded = 0;
- mShaderLevel[SHADER_LIGHTING] = 0;
- mShaderLevel[SHADER_INTERFACE] = 0;
- mShaderLevel[SHADER_ENVIRONMENT] = 0;
- mShaderLevel[SHADER_WATER] = 0;
- mShaderLevel[SHADER_OBJECT] = 0;
- mShaderLevel[SHADER_EFFECT] = 0;
- mShaderLevel[SHADER_WINDLIGHT] = 0;
- mShaderLevel[SHADER_AVATAR] = 0;
- }
-
+
if (gViewerWindow)
{
gViewerWindow->setCursor(UI_CURSOR_ARROW);
@@ -741,8 +729,10 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
gOcclusionProgram.unload();
+ gSkinnedOcclusionProgram.unload();
gOcclusionCubeProgram.unload();
gDebugProgram.unload();
+ gSkinnedDebugProgram.unload();
gClipProgram.unload();
gDownsampleDepthProgram.unload();
gDownsampleDepthRectProgram.unload();
@@ -764,58 +754,50 @@ void LLViewerShaderMgr::unloadShaders()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
+ gSkinnedObjectSimpleProgram.unload();
gObjectSimpleImpostorProgram.unload();
+ gSkinnedObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
+ gSkinnedObjectSimpleAlphaMaskProgram.unload();
gObjectBumpProgram.unload();
+ gSkinnedObjectBumpProgram.unload();
gObjectSimpleWaterProgram.unload();
+ gSkinnedObjectSimpleWaterProgram.unload();
gObjectSimpleWaterAlphaMaskProgram.unload();
+ gSkinnedObjectSimpleWaterAlphaMaskProgram.unload();
gObjectFullbrightProgram.unload();
+ gSkinnedObjectFullbrightProgram.unload();
gObjectFullbrightWaterProgram.unload();
+ gSkinnedObjectFullbrightWaterProgram.unload();
gObjectEmissiveProgram.unload();
+ gSkinnedObjectEmissiveProgram.unload();
gObjectEmissiveWaterProgram.unload();
+ gSkinnedObjectEmissiveWaterProgram.unload();
gObjectFullbrightAlphaMaskProgram.unload();
+ gSkinnedObjectFullbrightAlphaMaskProgram.unload();
gObjectFullbrightWaterAlphaMaskProgram.unload();
+ gSkinnedObjectFullbrightWaterAlphaMaskProgram.unload();
gObjectShinyProgram.unload();
+ gSkinnedObjectShinyProgram.unload();
gObjectFullbrightShinyProgram.unload();
+ gSkinnedObjectFullbrightShinyProgram.unload();
gObjectFullbrightShinyWaterProgram.unload();
+ gSkinnedObjectFullbrightShinyWaterProgram.unload();
gObjectShinyWaterProgram.unload();
+ gSkinnedObjectShinyWaterProgram.unload();
- gObjectSimpleNonIndexedProgram.unload();
gObjectSimpleNonIndexedTexGenProgram.unload();
gObjectSimpleNonIndexedTexGenWaterProgram.unload();
- gObjectSimpleNonIndexedWaterProgram.unload();
gObjectAlphaMaskNonIndexedProgram.unload();
gObjectAlphaMaskNonIndexedWaterProgram.unload();
gObjectAlphaMaskNoColorProgram.unload();
gObjectAlphaMaskNoColorWaterProgram.unload();
- gObjectFullbrightNonIndexedProgram.unload();
- gObjectFullbrightNonIndexedWaterProgram.unload();
- gObjectEmissiveNonIndexedProgram.unload();
- gObjectEmissiveNonIndexedWaterProgram.unload();
gTreeProgram.unload();
gTreeWaterProgram.unload();
- gObjectShinyNonIndexedProgram.unload();
- gObjectFullbrightShinyNonIndexedProgram.unload();
- gObjectFullbrightShinyNonIndexedWaterProgram.unload();
- gObjectShinyNonIndexedWaterProgram.unload();
-
- gSkinnedObjectSimpleProgram.unload();
- gSkinnedObjectFullbrightProgram.unload();
- gSkinnedObjectEmissiveProgram.unload();
- gSkinnedObjectFullbrightShinyProgram.unload();
- gSkinnedObjectShinySimpleProgram.unload();
-
- gSkinnedObjectSimpleWaterProgram.unload();
- gSkinnedObjectFullbrightWaterProgram.unload();
- gSkinnedObjectEmissiveWaterProgram.unload();
- gSkinnedObjectFullbrightShinyWaterProgram.unload();
- gSkinnedObjectShinySimpleWaterProgram.unload();
-
-
gWaterProgram.unload();
gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
@@ -828,6 +810,7 @@ void LLViewerShaderMgr::unloadShaders()
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
gHighlightProgram.unload();
+ gSkinnedHighlightProgram.unload();
gHighlightNormalProgram.unload();
gHighlightSpecularProgram.unload();
@@ -841,13 +824,13 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredDiffuseProgram.unload();
gDeferredDiffuseAlphaMaskProgram.unload();
+ gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
gDeferredNonIndexedDiffuseProgram.unload();
gDeferredSkinnedDiffuseProgram.unload();
gDeferredSkinnedBumpProgram.unload();
- gDeferredSkinnedAlphaProgram.unload();
-
+
gTransformPositionProgram.unload();
gTransformTexCoordProgram.unload();
gTransformNormalProgram.unload();
@@ -864,7 +847,7 @@ void LLViewerShaderMgr::unloadShaders()
mShaderLevel[SHADER_WINDLIGHT] = 0;
mShaderLevel[SHADER_TRANSFORM] = 0;
- gPipeline.mVertexShadersLoaded = 0;
+ gPipeline.mShadersLoaded = false;
}
BOOL LLViewerShaderMgr::loadBasicShaders()
@@ -924,7 +907,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
- boost::unordered_map<std::string, std::string> attribs;
+ std::unordered_map<std::string, std::string> attribs;
attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount());
@@ -1236,14 +1219,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredTreeProgram.unload();
gDeferredTreeShadowProgram.unload();
+ gDeferredSkinnedTreeShadowProgram.unload();
gDeferredDiffuseProgram.unload();
gDeferredDiffuseAlphaMaskProgram.unload();
+ gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
gDeferredNonIndexedDiffuseProgram.unload();
gDeferredSkinnedDiffuseProgram.unload();
gDeferredSkinnedBumpProgram.unload();
- gDeferredSkinnedAlphaProgram.unload();
gDeferredBumpProgram.unload();
gDeferredImpostorProgram.unload();
gDeferredTerrainProgram.unload();
@@ -1260,9 +1244,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.unload();
gDeferredSoftenWaterProgram.unload();
gDeferredShadowProgram.unload();
+ gDeferredSkinnedShadowProgram.unload();
gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowAlphaMaskProgram.unload();
gDeferredShadowFullbrightAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
gDeferredAvatarAlphaShadowProgram.unload();
gDeferredAvatarAlphaMaskShadowProgram.unload();
@@ -1272,12 +1259,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
+ gDeferredSkinnedAlphaProgram.unload();
gDeferredAlphaWaterProgram.unload();
+ gDeferredSkinnedAlphaWaterProgram.unload();
gDeferredFullbrightProgram.unload();
gDeferredFullbrightAlphaMaskProgram.unload();
gDeferredFullbrightWaterProgram.unload();
+ gDeferredSkinnedFullbrightWaterProgram.unload();
gDeferredFullbrightAlphaMaskWaterProgram.unload();
+ gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload();
gDeferredEmissiveProgram.unload();
+ gDeferredSkinnedEmissiveProgram.unload();
gDeferredAvatarEyesProgram.unload();
gDeferredPostProgram.unload();
gDeferredCoFProgram.unload();
@@ -1292,8 +1284,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLMoonProgram.unload();
gDeferredStarProgram.unload();
gDeferredFullbrightShinyProgram.unload();
- gDeferredSkinnedFullbrightShinyProgram.unload();
+ gDeferredSkinnedFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightProgram.unload();
+ gDeferredSkinnedFullbrightAlphaMaskProgram.unload();
gDeferredHighlightProgram.unload();
gDeferredHighlightNormalProgram.unload();
@@ -1350,7 +1343,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredDiffuseProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
+ success = success && gDeferredDiffuseProgram.createShader(NULL, NULL);
}
if (success)
@@ -1362,7 +1356,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
+ success = success && gDeferredDiffuseAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
@@ -1404,94 +1399,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader";
- gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedDiffuseProgram.mFeatures.encodesNormal = true;
- gDeferredSkinnedDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredSkinnedDiffuseProgram.mShaderFiles.clear();
- gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader";
- gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedBumpProgram.mFeatures.encodesNormal = true;
- gDeferredSkinnedBumpProgram.mShaderFiles.clear();
- gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
- gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
- gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
- gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasSrgb = true;
- gDeferredSkinnedAlphaProgram.mFeatures.encodesNormal = true;
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasTransport = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasShadows = true;
-
- gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
-
- gDeferredSkinnedAlphaProgram.clearPermutations();
- gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
- gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
- gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
-
- if (use_sun_shadow)
- {
- gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", "1");
- }
-
- if (ambient_kill)
- {
- gDeferredSkinnedAlphaProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredSkinnedAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredSkinnedAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
- success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
- llassert(success);
-
- // Hack to include uniforms for lighting without linking in lighting file
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true;
- }
-
- if (success)
- {
gDeferredBumpProgram.mName = "Deferred Bump Shader";
gDeferredBumpProgram.mFeatures.encodesNormal = true;
gDeferredBumpProgram.mShaderFiles.clear();
gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredBumpProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
+ success = success && gDeferredBumpProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1579,6 +1494,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
}
+ else
+ {
+ gDeferredMaterialProgram[i].mRiggedVariant = &gDeferredMaterialProgram[i + 0x10];
+ }
success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
llassert(success);
@@ -1624,6 +1543,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN", "1");
}
+ else
+ {
+ gDeferredMaterialWaterProgram[i].mRiggedVariant = &(gDeferredMaterialWaterProgram[i + 0x10]);
+ }
gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
if (ambient_kill)
@@ -1700,10 +1623,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
llassert(success);
}
+ if (success)
+ {
+ gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader";
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear();
+ gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true;
+ gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true;
+ gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredImpostorProgram.mName = "Deferred Impostor Shader";
@@ -1892,172 +1830,235 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAlphaProgram.mName = "Deferred Alpha Shader";
-
- gDeferredAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAlphaProgram.mFeatures.hasLighting = false;
- gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
- gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- gDeferredAlphaProgram.mFeatures.hasSrgb = true;
- gDeferredAlphaProgram.mFeatures.encodesNormal = true;
- gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
- gDeferredAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAlphaProgram.mFeatures.hasTransport = true;
- gDeferredAlphaProgram.mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
+ for (int i = 0; i < 2 && success; ++i)
{
- gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
-
- gDeferredAlphaProgram.mShaderFiles.clear();
- gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
-
- gDeferredAlphaProgram.clearPermutations();
- gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
- gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
- if (use_sun_shadow)
- {
- gDeferredAlphaProgram.addPermutation("HAS_SHADOW", "1");
- }
+ LLGLSLShader* shader = nullptr;
+ bool rigged = i == 1;
+ if (!rigged)
+ {
+ shader = &gDeferredAlphaProgram;
+ shader->mName = "Deferred Alpha Shader";
+ shader->mRiggedVariant = &gDeferredSkinnedAlphaProgram;
+ }
+ else
+ {
+ shader = &gDeferredSkinnedAlphaProgram;
+ shader->mName = "Skinned Deferred Alpha Shader";
+ shader->mFeatures.hasObjectSkinning = true;
+ }
- if (ambient_kill)
- {
- gDeferredAlphaProgram.addPermutation("AMBIENT_KILL", "1");
- }
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasTransport = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
- if (sunlight_kill)
- {
- gDeferredAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (local_light_kill)
- {
- gDeferredAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
+ shader->clearPermutations();
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+ shader->addPermutation("USE_INDEXED_TEX", "1");
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SHADOW", "1");
+ }
- gDeferredAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (ambient_kill)
+ {
+ shader->addPermutation("AMBIENT_KILL", "1");
+ }
- success = gDeferredAlphaProgram.createShader(NULL, NULL);
- llassert(success);
+ if (sunlight_kill)
+ {
+ shader->addPermutation("SUNLIGHT_KILL", "1");
+ }
+
+ if (local_light_kill)
+ {
+ shader->addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
+
+ if (rigged)
+ {
+ shader->addPermutation("HAS_SKIN", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- // Hack
- gDeferredAlphaProgram.mFeatures.calculatesLighting = true;
- gDeferredAlphaProgram.mFeatures.hasLighting = true;
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
+
+ // Hack
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+ }
}
if (success)
{
- gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Impostor Shader";
+ LLGLSLShader* shaders[] = {
+ &gDeferredAlphaImpostorProgram,
+ &gDeferredSkinnedAlphaImpostorProgram
+ };
-// Begin Hack
- gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
- gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
+ for (int i = 0; i < 2 && success; ++i)
+ {
+ bool rigged = i == 1;
+ LLGLSLShader* shader = shaders[i];
- gDeferredAlphaImpostorProgram.mFeatures.hasSrgb = true;
- gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
- gDeferredAlphaImpostorProgram.mFeatures.encodesNormal = true;
- gDeferredAlphaImpostorProgram.mFeatures.hasShadows = use_sun_shadow;
+ shader->mName = rigged ? "Skinned Deferred Alpha Impostor Shader" : "Deferred Alpha Impostor Shader";
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ // Begin Hack
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
- gDeferredAlphaImpostorProgram.mShaderFiles.clear();
- gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
- gDeferredAlphaImpostorProgram.clearPermutations();
- gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
- gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
- gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
- if (use_sun_shadow)
- {
- gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", "1");
- }
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAlphaImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ shader->clearPermutations();
+ shader->addPermutation("USE_INDEXED_TEX", "1");
+ shader->addPermutation("FOR_IMPOSTOR", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+ if (rigged)
+ {
+ shader->mFeatures.hasObjectSkinning = true;
+ shader->addPermutation("HAS_SKIN", "1");
+ }
- success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
- llassert(success);
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SHADOW", "1");
+ }
+
+ shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (!rigged)
+ {
+ shader->mRiggedVariant = shaders[1];
+ }
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
-// End Hack
- gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
- gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
+ // End Hack
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+ }
}
- if (success)
- {
- gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
- gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false;
- gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
- gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
- gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
- gDeferredAlphaWaterProgram.mFeatures.hasWaterFog = true;
- gDeferredAlphaWaterProgram.mFeatures.hasSrgb = true;
- gDeferredAlphaWaterProgram.mFeatures.encodesNormal = true;
- gDeferredAlphaWaterProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAlphaWaterProgram.mFeatures.hasAtmospherics = true;
- gDeferredAlphaWaterProgram.mFeatures.hasGamma = true;
- gDeferredAlphaWaterProgram.mFeatures.hasTransport = true;
- gDeferredAlphaWaterProgram.mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
- gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gDeferredAlphaWaterProgram.mShaderFiles.clear();
- gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
-
- gDeferredAlphaWaterProgram.clearPermutations();
- gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
- gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
- gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
- if (use_sun_shadow)
- {
- gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", "1");
- }
+ if (success)
+ {
+ LLGLSLShader* shader[] = {
+ &gDeferredAlphaWaterProgram,
+ &gDeferredSkinnedAlphaWaterProgram
+ };
+
+ gDeferredAlphaWaterProgram.mRiggedVariant = &gDeferredSkinnedAlphaWaterProgram;
+
+ gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
+ gDeferredSkinnedAlphaWaterProgram.mName = "Deferred Skinned Alpha Underwater Shader";
- if (ambient_kill)
+ for (int i = 0; i < 2 && success; ++i)
{
- gDeferredAlphaWaterProgram.addPermutation("AMBIENT_KILL", "1");
- }
+ shader[i]->mFeatures.calculatesLighting = false;
+ shader[i]->mFeatures.hasLighting = false;
+ shader[i]->mFeatures.isAlphaLighting = true;
+ shader[i]->mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ shader[i]->mFeatures.hasWaterFog = true;
+ shader[i]->mFeatures.hasSrgb = true;
+ shader[i]->mFeatures.encodesNormal = true;
+ shader[i]->mFeatures.calculatesAtmospherics = true;
+ shader[i]->mFeatures.hasAtmospherics = true;
+ shader[i]->mFeatures.hasGamma = true;
+ shader[i]->mFeatures.hasTransport = true;
+ shader[i]->mFeatures.hasShadows = use_sun_shadow;
+
+ if (mShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+ shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
+ shader[i]->mShaderFiles.clear();
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ shader[i]->clearPermutations();
+ shader[i]->addPermutation("USE_INDEXED_TEX", "1");
+ shader[i]->addPermutation("WATER_FOG", "1");
+ shader[i]->addPermutation("USE_VERTEX_COLOR", "1");
+ if (use_sun_shadow)
+ {
+ shader[i]->addPermutation("HAS_SHADOW", "1");
+ }
- if (sunlight_kill)
- {
- gDeferredAlphaWaterProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
+ if (ambient_kill)
+ {
+ shader[i]->addPermutation("AMBIENT_KILL", "1");
+ }
- if (local_light_kill)
- {
- gDeferredAlphaWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
- gDeferredAlphaWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (sunlight_kill)
+ {
+ shader[i]->addPermutation("SUNLIGHT_KILL", "1");
+ }
- success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
- llassert(success);
+ if (local_light_kill)
+ {
+ shader[i]->addPermutation("LOCAL_LIGHT_KILL", "1");
+ }
- // Hack
- gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true;
- gDeferredAlphaWaterProgram.mFeatures.hasLighting = true;
+ if (i == 1)
+ { // rigged variant
+ shader[i]->mFeatures.hasObjectSkinning = true;
+ shader[i]->addPermutation("HAS_SKIN", "1");
+ }
+ else
+ {
+ shader[i]->mRiggedVariant = shader[1];
+ }
+ shader[i]->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = shader[i]->createShader(NULL, NULL);
+ llassert(success);
+
+ // Hack
+ shader[i]->mFeatures.calculatesLighting = true;
+ shader[i]->mFeatures.hasLighting = true;
+ }
}
if (success)
@@ -2091,6 +2092,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2108,7 +2110,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
+ success = success && gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2127,10 +2130,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
- success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredFullbrightWaterProgram, gDeferredSkinnedFullbrightWaterProgram);
+ success = success && gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
llassert(success);
}
-
+
if (success)
{
gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
@@ -2147,7 +2151,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
- success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
+ success = success && gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2164,43 +2169,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedFullbrightProgram.mName = "Skinned Fullbright Shader";
- gDeferredSkinnedFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.hasAtmospherics = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.hasGamma = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.hasTransport = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.disableTextureIndex = true;
- gDeferredSkinnedFullbrightProgram.mFeatures.hasSrgb = true;
- gDeferredSkinnedFullbrightProgram.mShaderFiles.clear();
- gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gDeferredSkinnedFullbrightProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredSkinnedFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasGamma = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasTransport = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
- gDeferredSkinnedFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredSkinnedFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gDeferredSkinnedFullbrightShinyProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
+ success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2215,7 +2185,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredEmissiveProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
+ success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2358,10 +2329,29 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");
}
+ gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
success = gDeferredShadowProgram.createShader(NULL, NULL);
llassert(success);
}
+ if (success)
+ {
+ gDeferredSkinnedShadowProgram.mName = "Deferred Skinned Shadow Shader";
+ gDeferredSkinnedShadowProgram.mFeatures.isDeferred = true;
+ gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
+ gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedShadowProgram.mShaderFiles.clear();
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
@@ -2395,11 +2385,32 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
+ {
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mName = "Deferred Skinned Shadow Fullbright Alpha Mask Shader";
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations();
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
+ gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
{
gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
@@ -2412,10 +2423,28 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
}
gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram;
success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
}
+ if (success)
+ {
+ gDeferredSkinnedShadowAlphaMaskProgram.mName = "Deferred Skinned Shadow Alpha Mask Shader";
+ gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ if (gGLManager.mHasDepthClamp)
+ {
+ gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
+ }
+ gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredAvatarShadowProgram.mName = "Deferred Avatar Shadow Shader";
@@ -2791,79 +2820,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
BOOL LLViewerShaderMgr::loadShadersObject()
{
BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_OBJECT] == 0)
- {
- gObjectShinyProgram.unload();
- gObjectFullbrightShinyProgram.unload();
- gObjectFullbrightShinyWaterProgram.unload();
- gObjectShinyWaterProgram.unload();
- gObjectFullbrightNoColorProgram.unload();
- gObjectFullbrightNoColorWaterProgram.unload();
- gObjectSimpleProgram.unload();
- gObjectSimpleImpostorProgram.unload();
- gObjectPreviewProgram.unload();
- gImpostorProgram.unload();
- gObjectSimpleAlphaMaskProgram.unload();
- gObjectBumpProgram.unload();
- gObjectSimpleWaterProgram.unload();
- gObjectSimpleWaterAlphaMaskProgram.unload();
- gObjectEmissiveProgram.unload();
- gObjectEmissiveWaterProgram.unload();
- gObjectFullbrightProgram.unload();
- gObjectFullbrightAlphaMaskProgram.unload();
- gObjectFullbrightWaterProgram.unload();
- gObjectFullbrightWaterAlphaMaskProgram.unload();
- gObjectShinyNonIndexedProgram.unload();
- gObjectFullbrightShinyNonIndexedProgram.unload();
- gObjectFullbrightShinyNonIndexedWaterProgram.unload();
- gObjectShinyNonIndexedWaterProgram.unload();
- gObjectSimpleNonIndexedTexGenProgram.unload();
- gObjectSimpleNonIndexedTexGenWaterProgram.unload();
- gObjectSimpleNonIndexedWaterProgram.unload();
- gObjectAlphaMaskNonIndexedProgram.unload();
- gObjectAlphaMaskNonIndexedWaterProgram.unload();
- gObjectAlphaMaskNoColorProgram.unload();
- gObjectAlphaMaskNoColorWaterProgram.unload();
- gObjectFullbrightNonIndexedProgram.unload();
- gObjectFullbrightNonIndexedWaterProgram.unload();
- gObjectEmissiveNonIndexedProgram.unload();
- gObjectEmissiveNonIndexedWaterProgram.unload();
- gSkinnedObjectSimpleProgram.unload();
- gSkinnedObjectFullbrightProgram.unload();
- gSkinnedObjectEmissiveProgram.unload();
- gSkinnedObjectFullbrightShinyProgram.unload();
- gSkinnedObjectShinySimpleProgram.unload();
- gSkinnedObjectSimpleWaterProgram.unload();
- gSkinnedObjectFullbrightWaterProgram.unload();
- gSkinnedObjectEmissiveWaterProgram.unload();
- gSkinnedObjectFullbrightShinyWaterProgram.unload();
- gSkinnedObjectShinySimpleWaterProgram.unload();
- gTreeProgram.unload();
- gTreeWaterProgram.unload();
-
- return TRUE;
- }
if (success)
{
- gObjectSimpleNonIndexedProgram.mName = "Non indexed Shader";
- gObjectSimpleNonIndexedProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectSimpleNonIndexedProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleNonIndexedProgram.mFeatures.hasLighting = true;
- gObjectSimpleNonIndexedProgram.mFeatures.hasAlphaMask = true; // Fix for MAINT-8836
- gObjectSimpleNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectSimpleNonIndexedProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectSimpleNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";
gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;
gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true;
@@ -2878,24 +2837,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
}
-
- if (success)
- {
- gObjectSimpleNonIndexedWaterProgram.mName = "Non indexed Water Shader";
- gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectSimpleNonIndexedWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleNonIndexedWaterProgram.mFeatures.hasLighting = true;
- gObjectSimpleNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectSimpleNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectSimpleNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectSimpleNonIndexedWaterProgram.createShader(NULL, NULL);
- }
-
if (success)
{
gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader";
@@ -3020,70 +2961,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectFullbrightNonIndexedProgram.mName = "Non Indexed Fullbright Shader";
- gObjectFullbrightNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectFullbrightNonIndexedProgram.mFeatures.hasTransport = true;
- gObjectFullbrightNonIndexedProgram.mFeatures.isFullbright = true;
- gObjectFullbrightNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightNonIndexedProgram.mShaderFiles.clear();
- gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightNonIndexedWaterProgram.mName = "Non Indexed Fullbright Water Shader";
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightNonIndexedWaterProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightNonIndexedWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectEmissiveNonIndexedProgram.mName = "Non Indexed Emissive Shader";
- gObjectEmissiveNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectEmissiveNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectEmissiveNonIndexedProgram.mFeatures.hasTransport = true;
- gObjectEmissiveNonIndexedProgram.mFeatures.isFullbright = true;
- gObjectEmissiveNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectEmissiveNonIndexedProgram.mFeatures.hasSrgb = true;
- gObjectEmissiveNonIndexedProgram.mShaderFiles.clear();
- gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectEmissiveNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectEmissiveNonIndexedWaterProgram.mName = "Non Indexed Emissive Water Shader";
- gObjectEmissiveNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectEmissiveNonIndexedWaterProgram.mFeatures.isFullbright = true;
- gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectEmissiveNonIndexedWaterProgram.mFeatures.hasTransport = true;
- gObjectEmissiveNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectEmissiveNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectEmissiveNonIndexedWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader";
gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true;
gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true;
@@ -3116,73 +2993,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectShinyNonIndexedProgram.mName = "Non Indexed Shiny Shader";
- gObjectShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectShinyNonIndexedProgram.mFeatures.calculatesLighting = true;
- gObjectShinyNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectShinyNonIndexedProgram.mFeatures.hasAtmospherics = true;
- gObjectShinyNonIndexedProgram.mFeatures.isShiny = true;
- gObjectShinyNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectShinyNonIndexedProgram.mShaderFiles.clear();
- gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectShinyNonIndexedWaterProgram.mName = "Non Indexed Shiny Water Shader";
- gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectShinyNonIndexedWaterProgram.mFeatures.calculatesLighting = true;
- gObjectShinyNonIndexedWaterProgram.mFeatures.isShiny = true;
- gObjectShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectShinyNonIndexedWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectShinyNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightShinyNonIndexedProgram.mName = "Non Indexed Fullbright Shiny Shader";
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.clear();
- gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightShinyNonIndexedWaterProgram.mName = "Non Indexed Fullbright Shiny Water Shader";
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gImpostorProgram.mName = "Impostor Shader";
gImpostorProgram.mFeatures.disableTextureIndex = true;
gImpostorProgram.mFeatures.hasSrgb = true;
@@ -3224,7 +3034,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectSimpleProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
+ success = success && gObjectSimpleProgram.createShader(NULL, NULL);
}
if (success)
@@ -3244,8 +3055,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
-
- success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram);
+ success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL);
}
if (success)
@@ -3262,30 +3073,30 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram);
success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
}
if (success)
{
gObjectBumpProgram.mName = "Bump Shader";
- /*gObjectBumpProgram.mFeatures.calculatesLighting = true;
- gObjectBumpProgram.mFeatures.calculatesAtmospherics = true;
- gObjectBumpProgram.mFeatures.hasGamma = true;
- gObjectBumpProgram.mFeatures.hasAtmospherics = true;
- gObjectBumpProgram.mFeatures.hasLighting = true;
- gObjectBumpProgram.mFeatures.mIndexedTextureChannels = 0;*/
gObjectBumpProgram.mFeatures.encodesNormal = true;
gObjectBumpProgram.mShaderFiles.clear();
gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));
gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectBumpProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
+ success = success && gObjectBumpProgram.createShader(NULL, NULL);
if (success)
{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
- gObjectBumpProgram.bind();
- gObjectBumpProgram.uniform1i(sTexture0, 0);
- gObjectBumpProgram.uniform1i(sTexture1, 1);
- gObjectBumpProgram.unbind();
+ LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
+ for (int i = 0; i < 2; ++i)
+ {
+ shader[i]->bind();
+ shader[i]->uniform1i(sTexture0, 0);
+ shader[i]->uniform1i(sTexture1, 1);
+ shader[i]->unbind();
+ }
}
}
@@ -3304,7 +3115,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram);
+ success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
@@ -3322,7 +3134,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram);
+ success = success && gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
@@ -3338,7 +3151,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
+ success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
}
if (success)
@@ -3346,7 +3160,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
+ gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;
gObjectFullbrightWaterProgram.mShaderFiles.clear();
@@ -3354,7 +3168,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram);
+ success = success && gObjectFullbrightWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -3370,7 +3185,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectEmissiveProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram);
+ success = success && gObjectEmissiveProgram.createShader(NULL, NULL);
}
if (success)
@@ -3386,7 +3202,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectEmissiveWaterProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram);
+ success = success && gObjectEmissiveWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -3403,12 +3220,13 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram);
+ success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
{
- gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Shader";
+ gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Alpha Mask Shader";
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true;
gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;
@@ -3420,7 +3238,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram);
+ success = success && gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
@@ -3436,7 +3255,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectShinyProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram);
+ success = success && gObjectShinyProgram.createShader(NULL, NULL);
}
if (success)
@@ -3453,7 +3273,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectShinyWaterProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram);
+ success = success && gObjectShinyWaterProgram.createShader(NULL, NULL);
}
if (success)
@@ -3469,7 +3290,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram);
+ success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL);
}
if (success)
@@ -3487,196 +3309,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
- }
-
- if (mShaderLevel[SHADER_AVATAR] > 0)
- { //load hardware skinned attachment shaders
- if (success)
- {
- gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader";
- gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true;
- gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true;
- gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true;
- gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true;
- gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectSimpleProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectSimpleProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectSimpleProgram.mShaderFiles.clear();
- gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader";
- gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true;
- gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true;
- gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true;
- gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectFullbrightProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectFullbrightProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectFullbrightProgram.mFeatures.hasSrgb = true;
- gSkinnedObjectFullbrightProgram.mShaderFiles.clear();
- gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectEmissiveProgram.mName = "Skinned Emissive Shader";
- gSkinnedObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectEmissiveProgram.mFeatures.hasGamma = true;
- gSkinnedObjectEmissiveProgram.mFeatures.hasTransport = true;
- gSkinnedObjectEmissiveProgram.mFeatures.isFullbright = true;
- gSkinnedObjectEmissiveProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectEmissiveProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectEmissiveProgram.mFeatures.hasSrgb = true;
- gSkinnedObjectEmissiveProgram.mShaderFiles.clear();
- gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectEmissiveProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectEmissiveWaterProgram.mName = "Skinned Emissive Water Shader";
- gSkinnedObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.hasGamma = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.isFullbright = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true;
- gSkinnedObjectEmissiveWaterProgram.mShaderFiles.clear();
- gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectEmissiveWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader";
- gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectFullbrightShinyProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear();
- gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader";
- gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true;
- gSkinnedObjectShinySimpleProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectShinySimpleProgram.mShaderFiles.clear();
- gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectShinySimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader";
- gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
- gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();
- gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader";
- gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
- gSkinnedObjectFullbrightWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear();
- gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader";
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader";
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAlphaMask = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true;
- gSkinnedObjectShinySimpleWaterProgram.mFeatures.disableTextureIndex = true;
- gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear();
- gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);
- }
+ success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
+ success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
}
if( !success )
@@ -3789,12 +3423,6 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
BOOL success = TRUE;
- if (mShaderLevel[SHADER_INTERFACE] == 0)
- {
- gHighlightProgram.unload();
- return TRUE;
- }
-
if (success)
{
gHighlightProgram.mName = "Highlight Shader";
@@ -3802,7 +3430,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
+ success = success && gHighlightProgram.createShader(NULL, NULL);
}
if (success)
@@ -4004,9 +3633,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));
gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
success = gOcclusionProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
+ gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
+ gSkinnedOcclusionProgram.mShaderFiles.clear();
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
+ }
+
if (success)
{
gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
@@ -4023,8 +3664,10 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gDebugProgram.mShaderFiles.clear();
gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDebugProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
+ success = success && gDebugProgram.createShader(NULL, NULL);
}
if (success)
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 081221f15b..297cfb6e68 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -184,10 +184,8 @@ extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gObjectSimpleAlphaMaskProgram;
extern LLGLSLShader gObjectSimpleWaterProgram;
extern LLGLSLShader gObjectSimpleWaterAlphaMaskProgram;
-extern LLGLSLShader gObjectSimpleNonIndexedProgram;
extern LLGLSLShader gObjectSimpleNonIndexedTexGenProgram;
extern LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram;
-extern LLGLSLShader gObjectSimpleNonIndexedWaterProgram;
extern LLGLSLShader gObjectAlphaMaskNonIndexedProgram;
extern LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram;
extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
@@ -200,8 +198,6 @@ extern LLGLSLShader gObjectEmissiveProgram;
extern LLGLSLShader gObjectEmissiveWaterProgram;
extern LLGLSLShader gObjectFullbrightAlphaMaskProgram;
extern LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram;
-extern LLGLSLShader gObjectFullbrightNonIndexedProgram;
-extern LLGLSLShader gObjectFullbrightNonIndexedWaterProgram;
extern LLGLSLShader gObjectEmissiveNonIndexedProgram;
extern LLGLSLShader gObjectEmissiveNonIndexedWaterProgram;
extern LLGLSLShader gObjectBumpProgram;
@@ -213,25 +209,9 @@ extern LLGLSLShader gObjectFullbrightLODProgram;
extern LLGLSLShader gObjectFullbrightShinyProgram;
extern LLGLSLShader gObjectFullbrightShinyWaterProgram;
-extern LLGLSLShader gObjectFullbrightShinyNonIndexedProgram;
-extern LLGLSLShader gObjectFullbrightShinyNonIndexedWaterProgram;
extern LLGLSLShader gObjectShinyProgram;
extern LLGLSLShader gObjectShinyWaterProgram;
-extern LLGLSLShader gObjectShinyNonIndexedProgram;
-extern LLGLSLShader gObjectShinyNonIndexedWaterProgram;
-
-extern LLGLSLShader gSkinnedObjectSimpleProgram;
-extern LLGLSLShader gSkinnedObjectFullbrightProgram;
-extern LLGLSLShader gSkinnedObjectEmissiveProgram;
-extern LLGLSLShader gSkinnedObjectFullbrightShinyProgram;
-extern LLGLSLShader gSkinnedObjectShinySimpleProgram;
-
-extern LLGLSLShader gSkinnedObjectSimpleWaterProgram;
-extern LLGLSLShader gSkinnedObjectFullbrightWaterProgram;
-extern LLGLSLShader gSkinnedObjectEmissiveWaterProgram;
-extern LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram;
-extern LLGLSLShader gSkinnedObjectShinySimpleWaterProgram;
//environment shaders
extern LLGLSLShader gTerrainProgram;
@@ -281,9 +261,6 @@ extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseProgram;
-extern LLGLSLShader gDeferredSkinnedDiffuseProgram;
-extern LLGLSLShader gDeferredSkinnedBumpProgram;
-extern LLGLSLShader gDeferredSkinnedAlphaProgram;
extern LLGLSLShader gDeferredBumpProgram;
extern LLGLSLShader gDeferredTerrainProgram;
extern LLGLSLShader gDeferredTerrainWaterProgram;
@@ -330,8 +307,6 @@ extern LLGLSLShader gDeferredWLSunProgram;
extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
-extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
-extern LLGLSLShader gDeferredSkinnedFullbrightProgram;
extern LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 6471e89233..5ce97c086d 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -181,8 +181,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");
@@ -259,8 +260,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));
@@ -534,7 +538,7 @@ void send_viewer_stats(bool include_preferences)
{
shader_level = 2;
}
- else if (gPipeline.canUseVertexShaders())
+ else if (gPipeline.shadersLoaded())
{
shader_level = 1;
}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 72ce336664..1133326d4f 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -217,8 +217,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 075588d577..dcdc259b26 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -182,6 +182,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();
@@ -206,6 +207,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);
}
@@ -477,11 +479,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.
@@ -498,6 +499,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);
@@ -511,6 +513,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);
@@ -523,48 +526,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;
@@ -680,6 +677,9 @@ void LLViewerTexture::init(bool firstinit)
mVolumeList[LLRender::LIGHT_TEX].clear();
mVolumeList[LLRender::SCULPT_TEX].clear();
+
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
+ mImageQueue = LL::WorkQueue::getInstance("LLImageGL");
}
//virtual
@@ -701,6 +701,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++)
@@ -712,6 +713,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++)
@@ -724,6 +726,7 @@ void LLViewerTexture::notifyAboutMissingAsset()
// virtual
void LLViewerTexture::dump()
{
+ LL_PROFILE_ZONE_SCOPED;
LLGLTexture::dump();
LL_INFOS() << "LLViewerTexture"
@@ -759,6 +762,7 @@ bool LLViewerTexture::isActiveFetching()
bool LLViewerTexture::bindDebugImage(const S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -777,6 +781,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage)
bool LLViewerTexture::bindDefaultImage(S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED;
if (stage < 0) return false;
bool res = true;
@@ -819,6 +824,7 @@ void LLViewerTexture::forceImmediateUpdate()
void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
+ LL_PROFILE_ZONE_SCOPED;
if(needs_gltexture)
{
mNeedsGLTexture = TRUE;
@@ -829,14 +835,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()
@@ -861,6 +867,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())
@@ -876,6 +883,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)
@@ -916,6 +924,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);
@@ -929,6 +938,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);
@@ -952,6 +962,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;
@@ -975,6 +986,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;
@@ -1177,6 +1189,7 @@ FTType LLViewerFetchedTexture::getFTType() const
void LLViewerFetchedTexture::cleanup()
{
+ LL_PROFILE_ZONE_SCOPED;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
@@ -1202,6 +1215,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.
@@ -1347,6 +1361,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 ;
@@ -1363,6 +1378,7 @@ void LLViewerFetchedTexture::destroyTexture()
void LLViewerFetchedTexture::addToCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED;
bool force_update = false;
if (getComponents() != mRawImage->getComponents())
{
@@ -1404,6 +1420,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
else
{
+ LL_PROFILE_ZONE_SCOPED;
#if 1
//
//if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
@@ -1448,99 +1465,104 @@ 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 LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->checkActiveThread();
+#endif
- // store original size only for locally-sourced images
- if (mUrl.compare(0, 7, "file://") == 0)
- {
- mOrigWidth = mRawImage->getWidth();
- mOrigHeight = mRawImage->getHeight();
+ 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;
+
+ // 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);
+ }
- bool size_okay = true;
+ mFullWidth = mRawImage->getWidth();
+ mFullHeight = mRawImage->getHeight();
+ setTexelsPerImage();
+ }
+ else
+ {
+ mOrigWidth = mFullWidth;
+ mOrigHeight = mFullHeight;
+ }
- S32 discard_level = mRawDiscardLevel;
- if (mRawDiscardLevel < 0)
- {
- LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
- discard_level = 0;
- }
+ bool size_okay = true;
- U32 raw_width = mRawImage->getWidth() << discard_level;
- U32 raw_height = mRawImage->getHeight() << discard_level;
+ S32 discard_level = mRawDiscardLevel;
+ if (mRawDiscardLevel < 0)
+ {
+ LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
+ discard_level = 0;
+ }
- 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;
- }
+ 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 (mGLTexturep->getHasExplicitFormat())
{
@@ -1562,19 +1584,85 @@ 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;
+ }
+#if LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->checkActiveThread();
+#endif
- return res;
+ notifyAboutCreatingTexture();
+
+ setActive();
+
+ if (!needsToSaveRawImage())
+ {
+ mNeedsAux = FALSE;
+ destroyRawImage();
+ }
+
+ mNeedsCreateTexture = FALSE;
+}
+
+void LLViewerFetchedTexture::scheduleCreateTexture()
+{
+ if (!mNeedsCreateTexture)
+ {
+ ref();
+ mNeedsCreateTexture = TRUE;
+ if (preCreateTexture())
+ {
+ mNeedsCreateTexture = TRUE;
+ auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ if (mainq)
+ {
+ mainq->postTo(
+ mImageQueue,
+ // work to be done on LLImageGL worker thread
+ [this]()
+ {
+#if LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->mActiveThread = LLThread::currentID();
+#endif
+ //actually create the texture on a background thread
+ createTexture();
+ },
+ // callback to be run on main thread
+ [this]()
+ {
+#if LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->mActiveThread = LLThread::currentID();
+#endif
+ //finalize on main thread
+ postCreateTexture();
+ unref();
+ });
+ }
+ else
+ {
+ gTextureList.mCreateTextureList.insert(this);
+ unref();
+ }
+ }
+ }
}
// Call with 0,0 to turn this feature off.
@@ -1866,6 +1954,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
void LLViewerFetchedTexture::updateVirtualSize()
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mMaxVirtualSizeResetCounter)
{
addTextureStats(0.f, FALSE);//reset
@@ -1957,6 +2046,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);
@@ -2059,7 +2149,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
- mIsRawImageValid = TRUE;
+ mIsRawImageValid = TRUE;
addToCreateTexture();
}
@@ -2537,6 +2627,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
@@ -2887,7 +2978,9 @@ void LLViewerFetchedTexture::destroyRawImage()
//virtual
void LLViewerFetchedTexture::switchToCachedImage()
{
- if(mCachedRawImage.notNull())
+ LL_PROFILE_ZONE_SCOPED;
+ if(mCachedRawImage.notNull() &&
+ !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it
{
mRawImage = mCachedRawImage;
@@ -2898,12 +2991,12 @@ void LLViewerFetchedTexture::switchToCachedImage()
mComponents = mRawImage->getComponents();
mGLTexturep->setComponents(mComponents);
gTextureList.dirtyImage(this);
- }
+ }
mIsRawImageValid = TRUE;
mRawDiscardLevel = mCachedRawDiscardLevel;
- gTextureList.mCreateTextureList.insert(this);
- mNeedsCreateTexture = TRUE;
+
+ scheduleCreateTexture();
}
}
@@ -3177,6 +3270,7 @@ bool LLViewerLODTexture::isUpdateFrozen()
//virtual
void LLViewerLODTexture::processTextureStats()
{
+ LL_PROFILE_ZONE_SCOPED;
updateVirtualSize();
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
@@ -3340,6 +3434,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 07997e02a5..03b5b7497f 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -35,6 +35,7 @@
#include "llrender.h"
#include "llmetricperformancetester.h"
#include "httpcommon.h"
+#include "workqueue.h"
#include <map>
#include <list>
@@ -114,7 +115,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) ;
@@ -213,6 +214,9 @@ protected:
//do not use LLPointer here.
LLViewerMediaTexture* mParcelMedia ;
+ LL::WorkQueue::weak_t mMainQueue;
+ LL::WorkQueue::weak_t mImageQueue;
+
static F32 sTexelPixelRatio;
public:
static const U32 sCurrentFileVersion;
@@ -321,9 +325,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 38fccba169..db59976be2 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -66,7 +66,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)
{
@@ -112,6 +111,7 @@ void LLViewerTextureList::init()
void LLViewerTextureList::doPreloadImages()
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL;
llassert_always(mInitialized) ;
@@ -203,6 +203,7 @@ static std::string get_texture_list_name()
void LLViewerTextureList::doPrefetchImages()
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLAppViewer::instance()->getPurgeCache())
{
// cache was purged, no point
@@ -256,6 +257,7 @@ LLViewerTextureList::~LLViewerTextureList()
void LLViewerTextureList::shutdown()
{
+ LL_PROFILE_ZONE_SCOPED;
// clear out preloads
mImagePreloads.clear();
@@ -331,6 +333,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)
{
@@ -375,6 +378,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -402,6 +406,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
LLGLenum primary_format,
const LLUUID& force_id)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -490,6 +495,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!mInitialized)
{
return NULL ;
@@ -552,6 +558,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 ;
@@ -607,6 +614,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)
@@ -618,6 +626,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;
@@ -631,6 +640,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);
@@ -650,6 +660,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
@@ -698,6 +709,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListType tex_type)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!new_image)
{
return;
@@ -721,6 +733,7 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image, ETexListTy
void LLViewerTextureList::deleteImage(LLViewerFetchedTexture *image)
{
+ LL_PROFILE_ZONE_SCOPED;
if( image)
{
if (image->hasCallbacks())
@@ -745,18 +758,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)
{
@@ -782,66 +787,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;
@@ -859,6 +847,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
@@ -974,6 +963,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!tex->setDebugFetching(debug_level))
{
return;
@@ -1022,6 +1012,7 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled) return 0.0f;
//
@@ -1038,6 +1029,7 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
enditer = iter;
LLViewerFetchedTexture *imagep = *curiter;
imagep->createTexture();
+ imagep->postCreateTexture();
if (create_timer.getElapsedTimeF32() > max_time)
{
break;
@@ -1049,6 +1041,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())
{
@@ -1079,6 +1072,7 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!imagep)
{
return ;
@@ -1098,6 +1092,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
@@ -1173,6 +1168,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();
@@ -1187,6 +1183,7 @@ void LLViewerTextureList::updateImagesUpdateStats()
void LLViewerTextureList::decodeAllImages(F32 max_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer timer;
//loading from fast cache
@@ -1256,6 +1253,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())
@@ -1309,6 +1307,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();
@@ -1342,6 +1341,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 ;
@@ -1351,6 +1351,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)
{
@@ -1358,7 +1359,7 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl
// - it's going to be swapping constantly regardless
S32Megabytes max_vram(gGLManager.mVRAM);
- if(gGLManager.mIsATI)
+ if(gGLManager.mIsAMD)
{
//shrink the availabe vram for ATI cards because some of them do not handel texture swapping well.
max_vram = max_vram * 0.75f;
@@ -1404,6 +1405,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");
@@ -1466,8 +1468,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.
@@ -1538,7 +1540,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.
@@ -1611,7 +1613,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);
@@ -1644,6 +1646,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();
@@ -1662,6 +1665,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())
@@ -1679,6 +1683,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;
@@ -1691,6 +1696,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;
@@ -1702,6 +1708,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);
@@ -1739,6 +1746,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())
@@ -1753,6 +1761,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;
@@ -1854,6 +1863,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 92e8f8026d..8d749c41cc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -608,12 +608,6 @@ public:
{
LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
- if (gPipeline.getUseVertexShaders() == 0)
- {
- addText(xpos, ypos, "Shaders Disabled");
- ypos += y_inc;
- }
-
if (gGLManager.mHasATIMemInfo)
{
S32 meminfo[4];
@@ -1518,8 +1512,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)
@@ -1766,6 +1767,7 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
{
+ //TODO: just call this every frame from gatherInput instead of using a convoluted 30fps timer callback
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{
LLViewerJoystick::getInstance()->updateStatus();
@@ -1906,7 +1908,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 +1975,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 +2023,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, false, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
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");
@@ -2059,20 +2060,6 @@ void LLViewerWindow::initGLDefaults()
{
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- if (!LLGLSLShader::sNoFixedFunction)
- { //initialize fixed function state
- glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
-
- glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,LLColor4::black.mV);
- glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,LLColor4::white.mV);
-
- // lights for objects
- glShadeModel( GL_SMOOTH );
-
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
-
glPixelStorei(GL_PACK_ALIGNMENT,1);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
@@ -2112,6 +2099,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 +2187,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 +2205,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 +2302,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 +2563,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);
@@ -2672,10 +2675,7 @@ void LLViewerWindow::drawDebugText()
gGL.color4f(1,1,1,1);
gGL.pushMatrix();
gGL.pushUIMatrix();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
{
// scale view by UI global scale factor and aspect ratio correction factor
gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
@@ -2685,10 +2685,7 @@ void LLViewerWindow::drawDebugText()
gGL.popMatrix();
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
}
void LLViewerWindow::draw()
@@ -2734,10 +2731,7 @@ void LLViewerWindow::draw()
// Draw all nested UI views.
// No translation needed, this view is glued to 0,0
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gGL.pushMatrix();
LLUI::pushMatrix();
@@ -2813,14 +2807,9 @@ void LLViewerWindow::draw()
LLUI::popMatrix();
gGL.popMatrix();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
-//#if LL_DEBUG
LLView::sIsDrawing = FALSE;
-//#endif
}
// Takes a single keyup event, usually when UI is visible
@@ -3790,8 +3779,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;
@@ -5388,6 +5384,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();
@@ -5606,8 +5603,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()
@@ -5649,7 +5644,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 713cc51bf7..979a560508 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -427,7 +427,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 5d994058c2..c8c85d404d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -111,6 +111,7 @@
#include "llsdserialize.h"
#include "llcallstack.h"
#include "llrendersphere.h"
+#include "llskinningutil.h"
#include <boost/lexical_cast.hpp>
@@ -126,6 +127,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 +332,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 +453,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 +555,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 +671,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 +746,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mCurrentGesticulationLevel = 0;
-
+ mFirstSeenTimer.reset();
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
@@ -1317,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)
@@ -1424,7 +1430,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
continue;
}
LLDrawable* drawable = attached_object->mDrawable;
- if (drawable && !drawable->isState(LLDrawable::RIGGED))
+ if (drawable && !drawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) // <-- don't extend bounding box if any rigged objects are present
{
LLSpatialBridge* bridge = drawable->getSpatialBridge();
if (bridge)
@@ -2490,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()
//------------------------------------------------------------------------
@@ -2526,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())
{
@@ -2562,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();
@@ -2663,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();
}
@@ -2778,10 +2777,17 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}//if ( voiceEnabled )
}
-static LLTrace::BlockTimerStatHandle FTM_ATTACHMENT_UPDATE("Update Attachments");
+static void override_bbox(LLDrawable* drawable, LLVector4a* extents)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ drawable->setSpatialExtents(extents[0], extents[1]);
+ drawable->setPositionGroup(LLVector4a(0, 0, 0));
+ drawable->movePartition();
+}
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;
@@ -2795,7 +2801,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)
@@ -2813,21 +2818,34 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid())
{
- // if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
- {
- gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
- }
- else
- {
- gPipeline.updateMoveDampedAsync(attached_object->mDrawable);
- }
-
- LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
- if (bridge)
- {
- gPipeline.updateMoveNormalAsync(bridge);
- }
+
+ //override rigged attachments' octree spatial extents with this avatar's bounding box
+ LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
+ bool rigged = false;
+ if (bridge)
+ {
+ //transform avatar bounding box into attachment's coordinate frame
+ LLVector4a extents[2];
+ bridge->transformExtents(mDrawable->getSpatialExtents(), extents);
+
+ if (attached_object->mDrawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD))
+ {
+ rigged = true;
+ override_bbox(attached_object->mDrawable, extents);
+ }
+ }
+
+
+ attached_object->mDrawable->makeActive();
+ attached_object->mDrawable->updateXform(TRUE);
+
+ if (!rigged)
+ {
+ if (bridge)
+ {
+ gPipeline.updateMoveNormalAsync(bridge);
+ }
+ }
attached_object->updateText();
}
}
@@ -3135,6 +3153,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
@@ -4883,6 +4903,8 @@ bool LLVOAvatar::shouldAlphaMask()
//-----------------------------------------------------------------------------
U32 LLVOAvatar::renderSkinned()
{
+ LL_PROFILE_ZONE_SCOPED;
+
U32 num_indices = 0;
if (!mIsBuilt)
@@ -5051,11 +5073,6 @@ U32 LLVOAvatar::renderSkinned()
bool should_alpha_mask = shouldAlphaMask();
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
- if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
- }
-
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
@@ -5102,11 +5119,6 @@ U32 LLVOAvatar::renderSkinned()
}
}
- if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- }
-
if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)
{
LLGLState blend(GL_BLEND, !mIsDummy);
@@ -5122,21 +5134,21 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
U32 num_indices = 0;
if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (isUIAvatar() || isTextureVisible(TEX_SKIRT_BAKED)) )
{
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);
+ gGL.flush();
LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
if (skirt_mesh)
{
num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
}
first_pass = FALSE;
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
if (LLPipeline::sImpostorRender)
{
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
+ gGL.flush();
}
if (isTextureVisible(TEX_HEAD_BAKED))
@@ -5159,7 +5171,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
}
if (LLPipeline::sImpostorRender)
{
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
}
}
@@ -5191,11 +5203,6 @@ U32 LLVOAvatar::renderRigid()
bool should_alpha_mask = shouldAlphaMask();
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
- if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
- }
-
if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
{
LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
@@ -5210,11 +5217,6 @@ U32 LLVOAvatar::renderRigid()
}
}
- if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
- {
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- }
-
return num_indices;
}
@@ -5265,7 +5267,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
}
{
LLGLEnable test(GL_ALPHA_TEST);
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
+ gGL.flush();
gGL.color4ubv(color.mV);
gGL.getTexUnit(diffuse_channel)->bind(&mImpostor);
@@ -6157,27 +6159,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;
}
@@ -6512,7 +6516,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;
@@ -7116,6 +7120,7 @@ void LLVOAvatar::updateGL()
{
if (mMeshTexturesDirty)
{
+ LL_PROFILE_ZONE_SCOPED
updateMeshTextures();
mMeshTexturesDirty = FALSE;
}
@@ -7124,10 +7129,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;
@@ -7861,6 +7865,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;
@@ -8125,16 +8131,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
{
@@ -8352,6 +8377,7 @@ void LLVOAvatar::updateMeshVisibility()
// virtual
void LLVOAvatar::updateMeshTextures()
{
+ LL_PROFILE_ZONE_SCOPED
static S32 update_counter = 0;
mBakedTextureDebugText.clear();
@@ -9420,6 +9446,54 @@ LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)
}
+const LLVOAvatar::MatrixPaletteCache& LLVOAvatar::updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skin)
+{
+ U64 hash = skin->mHash;
+ MatrixPaletteCache& entry = mMatrixPaletteCache[hash];
+
+ if (entry.mFrame != gFrameCount)
+ {
+ LL_PROFILE_ZONE_SCOPED;
+
+ entry.mFrame = gFrameCount;
+
+ //build matrix palette
+ U32 count = LLSkinningUtil::getMeshJointCount(skin);
+ entry.mMatrixPalette.resize(count);
+ LLSkinningUtil::initSkinningMatrixPalette(&(entry.mMatrixPalette[0]), count, skin, this);
+
+ 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];
+ }
+ }
+
+ return entry;
+}
+
// static
void LLVOAvatar::getAnimLabels( std::vector<std::string>* labels )
{
@@ -10183,6 +10257,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;
@@ -10240,27 +10315,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)
{
@@ -10422,6 +10489,7 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
void LLVOAvatar::idleUpdateRenderComplexity()
{
+ LL_PROFILE_ZONE_SCOPED;
if (isControlAvatar())
{
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
@@ -10949,6 +11017,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..ab2a2daf49 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -53,6 +53,7 @@
#include "llviewerstats.h"
#include "llvovolume.h"
#include "llavatarrendernotifier.h"
+#include "llmodel.h"
extern const LLUUID ANIM_AGENT_BODY_NOISE;
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
@@ -77,6 +78,7 @@ class LLViewerJointMesh;
const F32 MAX_AVATAR_LOD_FACTOR = 1.0f;
+extern U32 gFrameCount;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatar
@@ -87,6 +89,7 @@ class LLVOAvatar :
public LLViewerObject,
public boost::signals2::trackable
{
+ LL_ALIGN_NEW;
LOG_CLASS(LLVOAvatar);
public:
@@ -99,16 +102,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 +202,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 +378,9 @@ protected:
private:
BOOL mFirstFullyVisible;
+ F32 mFirstUseDelaySeconds;
+ LLFrameTimer mFirstSeenTimer;
+
BOOL mFullyLoaded;
BOOL mPreviousFullyLoaded;
BOOL mFullyLoadedInitialized;
@@ -747,6 +748,34 @@ public:
void updateMeshVisibility();
LLViewerTexture* getBakedTexture(const U8 te);
+ // Matrix palette cache entry
+ class alignas(16) MatrixPaletteCache
+ {
+ public:
+ // Last frame this entry was updated
+ U32 mFrame;
+
+ // List of Matrix4a's for this entry
+ LLMeshSkinInfo::matrix_list_t mMatrixPalette;
+
+ // Float array ready to be sent to GL
+ std::vector<F32> mGLMp;
+
+ MatrixPaletteCache() :
+ mFrame(gFrameCount - 1)
+ {
+ }
+ };
+
+ // Accessor for Matrix Palette Cache
+ // Will do a map lookup for the entry associated with the given MeshSkinInfo
+ // Will update said entry if it hasn't been updated yet this frame
+ const MatrixPaletteCache& updateSkinInfoMatrixPalette(const LLMeshSkinInfo* skinInfo);
+
+ // Map of LLMeshSkinInfo::mHash to MatrixPaletteCache
+ typedef std::unordered_map<U64, MatrixPaletteCache> matrix_palette_cache_t;
+ matrix_palette_cache_t mMatrixPaletteCache;
+
protected:
void releaseMeshData();
virtual void restoreMeshData();
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..b0af565867 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -59,63 +59,7 @@ public:
// virtual
void setupVertexBuffer(U32 data_mask)
{
- if (LLGLSLShader::sNoFixedFunction)
- { //just use default if shaders are in play
- LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3));
- return;
- }
-
- volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
-
- //assume tex coords 2 and 3 are present
- U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3;
-
- if ((data_mask & type_mask) != data_mask)
- {
- LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL;
- }
-
- if (data_mask & MAP_NORMAL)
- {
- glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
- }
- if (data_mask & MAP_TEXCOORD3)
- { //substitute tex coord 1 for tex coord 3
- glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD2)
- { //substitute tex coord 0 for tex coord 2
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TANGENT)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
- }
- if (data_mask & MAP_COLOR)
- {
- glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
- }
-
- if (data_mask & MAP_VERTEX)
- {
- glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
- }
+ LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3));
}
};
@@ -212,19 +156,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 +1014,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..c49ac895ca 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,14 +1667,15 @@ void LLVOVolume::regenFaces()
BOOL LLVOVolume::genBBoxes(BOOL force_global)
{
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED;
+ BOOL res = TRUE;
- LLVector4a min,max;
+ LLVector4a min, max;
- min.clear();
- max.clear();
+ min.clear();
+ max.clear();
- BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
+ BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
if (getRiggedVolume())
{
@@ -1687,74 +1686,112 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
// Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about.
updateRiggedVolume();
}
-
- LLVolume* volume = mRiggedVolume;
- if (!volume)
- {
- volume = getVolume();
- }
+
+ LLVolume* volume = mRiggedVolume;
+ if (!volume)
+ {
+ volume = getVolume();
+ }
bool any_valid_boxes = false;
-
+
if (getRiggedVolume())
{
LL_DEBUGS("RiggedBox") << "rebuilding box, volume face count " << getVolume()->getNumVolumeFaces() << " drawable face count " << mDrawable->getNumFaces() << LL_ENDL;
}
+
// There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces()
- for (S32 i = 0;
- i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs();
- i++)
- {
- LLFace *face = mDrawable->getFace(i);
- if (!face)
- {
- continue;
- }
+ for (S32 i = 0;
+ i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs();
+ i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (!face)
+ {
+ continue;
+ }
BOOL face_res = face->genVolumeBBoxes(*volume, i,
- mRelativeXform,
- (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
+ mRelativeXform,
+ (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
res &= face_res; // note that this result is never used
-
+
// MAINT-8264 - ignore bboxes of ill-formed faces.
if (!face_res)
{
continue;
}
- if (rebuild)
- {
+ if (rebuild)
+ {
if (getRiggedVolume())
{
LL_DEBUGS("RiggedBox") << "rebuilding box, face " << i << " extents " << face->mExtents[0] << ", " << face->mExtents[1] << LL_ENDL;
}
- if (!any_valid_boxes)
- {
- min = face->mExtents[0];
- max = face->mExtents[1];
+ if (!any_valid_boxes)
+ {
+ min = face->mExtents[0];
+ max = face->mExtents[1];
any_valid_boxes = true;
- }
- else
- {
- min.setMin(min, face->mExtents[0]);
- max.setMax(max, face->mExtents[1]);
- }
- }
- }
+ }
+ else
+ {
+ min.setMin(min, face->mExtents[0]);
+ max.setMax(max, face->mExtents[1]);
+ }
+ }
+ }
+
+ bool rigged = false;
+
+ if (!isAnimatedObject())
+ {
+ rigged = isRiggedMesh() && isAttachment();
+ }
+ else
+ {
+ rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying;
+ }
if (any_valid_boxes)
{
if (rebuild)
{
- if (getRiggedVolume())
+ //get the Avatar associated with this object if it's rigged
+ LLVOAvatar* avatar = nullptr;
+ if (isRiggedMesh())
{
- LL_DEBUGS("RiggedBox") << "rebuilding got extents " << min << ", " << max << LL_ENDL;
+ if (!isAnimatedObject())
+ {
+ if (isAttachment())
+ {
+ avatar = getAvatar();
+ }
+ }
+ else
+ {
+ LLControlAvatar* controlAvatar = getControlAvatar();
+ if (controlAvatar && controlAvatar->mPlaying)
+ {
+ avatar = controlAvatar;
+ }
+ }
}
- mDrawable->setSpatialExtents(min,max);
- min.add(max);
- min.mul(0.5f);
- mDrawable->setPositionGroup(min);
- }
+ mDrawable->setSpatialExtents(min, max);
+
+ if (avatar)
+ {
+ // put all rigged drawables in the same octree node for better batching
+ mDrawable->setPositionGroup(LLVector4a(0, 0, 0));
+ }
+ else
+ {
+ min.add(max);
+ min.mul(0.5f);
+ mDrawable->setPositionGroup(min);
+ }
+ }
+
updateRadius();
mDrawable->movePartition();
}
@@ -1762,8 +1799,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
{
LL_DEBUGS("RiggedBox") << "genBBoxes failed to find any valid face boxes" << LL_ENDL;
}
-
- return res;
+
+ return res;
}
void LLVOVolume::preRebuild()
@@ -1879,12 +1916,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 +1931,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 +1958,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 +1982,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 +1995,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
{
BOOL res;
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_FLEX);
res = mVolumeImpl->doUpdateGeometry(drawable);
}
updateFaceFlags();
@@ -2006,7 +2034,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
if (!was_regen_faces) {
- LL_RECORD_BLOCK_TIME(FTM_GEN_TRIANGLES);
regenFaces();
}
@@ -2029,7 +2056,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 +3605,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
{
if (getVolume())
{
- return gMeshRepo.getSkinInfo(getVolume()->getParams().getSculptID(), this);
+ return gMeshRepo.getSkinInfo(getMeshID(), this);
}
else
{
@@ -3741,11 +3767,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();
@@ -4355,6 +4379,7 @@ void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
F32 LLVOVolume::getBinRadius()
{
+ LL_PROFILE_ZONE_SCOPED;
F32 radius;
F32 scale = 1.f;
@@ -4750,6 +4775,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 +4811,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())
{
@@ -4810,7 +4834,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (copy)
{
- copyVolumeFaces(volume);
+ copyVolumeFaces(volume);
}
else
{
@@ -4831,7 +4855,8 @@ 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);
+ const LLMatrix4a bind_shape_matrix = skin->mBindShapeMatrix;
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
@@ -4847,15 +4872,11 @@ 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);
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 +4947,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;
@@ -5029,13 +5049,13 @@ bool can_batch_texture(LLFace* facep)
const static U32 MAX_FACE_COUNT = 4096U;
int32_t LLVolumeGeometryManager::sInstanceCount = 0;
-LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL;
-LLFace** LLVolumeGeometryManager::sBumpFaces = NULL;
-LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL;
-LLFace** LLVolumeGeometryManager::sNormFaces = NULL;
-LLFace** LLVolumeGeometryManager::sSpecFaces = NULL;
-LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL;
-LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL;
+LLFace** LLVolumeGeometryManager::sFullbrightFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sBumpFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };
LLVolumeGeometryManager::LLVolumeGeometryManager()
: LLGeometryManager()
@@ -5063,39 +5083,43 @@ LLVolumeGeometryManager::~LLVolumeGeometryManager()
void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)
{
- sFullbrightFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
- sAlphaFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
+ for (int i = 0; i < 2; ++i)
+ {
+ sFullbrightFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sBumpFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sSimpleFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ }
}
void LLVolumeGeometryManager::freeFaces()
{
- ll_aligned_free<64>(sFullbrightFaces);
- ll_aligned_free<64>(sBumpFaces);
- ll_aligned_free<64>(sSimpleFaces);
- ll_aligned_free<64>(sNormFaces);
- ll_aligned_free<64>(sSpecFaces);
- ll_aligned_free<64>(sNormSpecFaces);
- ll_aligned_free<64>(sAlphaFaces);
-
- sFullbrightFaces = NULL;
- sBumpFaces = NULL;
- sSimpleFaces = NULL;
- sNormFaces = NULL;
- sSpecFaces = NULL;
- sNormSpecFaces = NULL;
- sAlphaFaces = NULL;
+ for (int i = 0; i < 2; ++i)
+ {
+ ll_aligned_free<64>(sFullbrightFaces[i]);
+ ll_aligned_free<64>(sBumpFaces[i]);
+ ll_aligned_free<64>(sSimpleFaces[i]);
+ ll_aligned_free<64>(sNormFaces[i]);
+ ll_aligned_free<64>(sSpecFaces[i]);
+ ll_aligned_free<64>(sNormSpecFaces[i]);
+ ll_aligned_free<64>(sAlphaFaces[i]);
+
+ sFullbrightFaces[i] = NULL;
+ sBumpFaces[i] = NULL;
+ sSimpleFaces[i] = NULL;
+ sNormFaces[i] = NULL;
+ sSpecFaces[i] = NULL;
+ sNormSpecFaces[i] = NULL;
+ sAlphaFaces[i] = 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)
@@ -5111,8 +5135,18 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
return;
}
+ U32 passType = type;
+
+ bool rigged = facep->isState(LLFace::RIGGED);
+
+ if (rigged && type != LLRenderPass::PASS_ALPHA)
+ {
+ // hacky, should probably clean up -- if this face is rigged, put it in "type + 1"
+ // See LLRenderPass PASS_foo enum
+ passType += 1;
+ }
//add face to drawmap
- LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[type];
+ LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[passType];
S32 idx = draw_vec.size()-1;
@@ -5138,7 +5172,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
LLDrawable* drawable = facep->getDrawable();
- if (drawable->isState(LLDrawable::ANIMATED_CHILD))
+ if (rigged)
+ {
+ // rigged meshes ignore their model matrix
+ model_mat = nullptr;
+ }
+ else if (drawable->isState(LLDrawable::ANIMATED_CHILD))
{
model_mat = &drawable->getWorldMatrix();
}
@@ -5179,6 +5218,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
+ F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale?
if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
{
@@ -5192,10 +5232,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{
batchable = true;
draw_vec[idx]->mTextureList[index] = tex;
+ draw_vec[idx]->mTextureListVSize[index] = vsize;
}
else if (draw_vec[idx]->mTextureList[index] == tex)
{ //this face's texture index can be used with this batch
batchable = true;
+ draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]);
}
}
else
@@ -5212,7 +5254,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- draw_vec[idx]->mMaterial == mat &&
+ //draw_vec[idx]->mMaterial == mat &&
draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
draw_vec[idx]->mBump == bump &&
@@ -5220,16 +5262,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat &&
draw_vec[idx]->mShaderMask == shader_mask &&
- draw_vec[idx]->mSelected == selected)
+ draw_vec[idx]->mSelected == selected &&
+ draw_vec[idx]->mAvatar == facep->mAvatar &&
+ draw_vec[idx]->getSkinHash() == facep->getSkinHash())
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size())
{
draw_vec[idx]->mTextureList.resize(index+1);
draw_vec[idx]->mTextureList[index] = tex;
+ draw_vec[idx]->mTextureListVSize.resize(index + 1);
+ draw_vec[idx]->mTextureListVSize[index] = vsize;
}
draw_vec[idx]->validate();
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
@@ -5244,7 +5290,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
facep->getVertexBuffer(), selected, fullbright, bump);
draw_info->mGroup = group;
- draw_info->mVSize = facep->getVirtualSize();
+ draw_info->mVSize = vsize;
draw_vec.push_back(draw_info);
draw_info->mTextureMatrix = tex_mat;
draw_info->mModelMatrix = model_mat;
@@ -5266,6 +5312,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mSpecularMap = NULL;
draw_info->mMaterial = mat;
draw_info->mShaderMask = shader_mask;
+ draw_info->mAvatar = facep->mAvatar;
+ draw_info->mSkinInfo = facep->mSkinInfo;
if (mat)
{
@@ -5317,6 +5365,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{ //initialize texture list for texture batching
draw_info->mTextureList.resize(index+1);
draw_info->mTextureList[index] = tex;
+ draw_info->mTextureListVSize.resize(index + 1);
+ draw_info->mTextureListVSize[index] = vsize;
}
draw_info->validate();
}
@@ -5327,38 +5377,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();
-
- if (avatar)
- {
- LLDrawable* drawable = avatar->mDrawable;
- if (drawable && drawable->getNumFaces() > 0)
- {
- LLFace* face = drawable->getFace(0);
- if (face)
- {
- LLDrawPool* drawpool = face->getPool();
- if (drawpool)
- {
- if (drawpool->getType() == LLDrawPool::POOL_AVATAR
- || drawpool->getType() == LLDrawPool::POOL_CONTROL_AV)
- {
- return (LLDrawPoolAvatar*) drawpool;
- }
- }
- }
- }
- }
-
- return NULL;
-}
-
void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)
{
static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
@@ -5434,8 +5452,29 @@ 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 (face->isState(LLFace::RIGGED))
+ {
+ if (count[1] < MAX_FACE_COUNT)
+ {
+ list[1][count[1]++] = face;
+ }
+ }
+ else
+ {
+ if (count[0] < MAX_FACE_COUNT)
+ {
+ list[0][count[0]++] = face;
+ }
+ }
+}
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+ LL_PROFILE_ZONE_SCOPED;
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5452,8 +5491,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
return;
}
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_VB);
-
group->mBuilt = 1.f;
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
@@ -5481,14 +5518,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
mFaceList.clear();
- U32 fullbright_count = 0;
- U32 bump_count = 0;
- U32 simple_count = 0;
- U32 alpha_count = 0;
- U32 norm_count = 0;
- U32 spec_count = 0;
- U32 normspec_count = 0;
-
+ U32 fullbright_count[2] = { 0 };
+ U32 bump_count[2] = { 0 };
+ U32 simple_count[2] = { 0 };
+ U32 alpha_count[2] = { 0 };
+ U32 norm_count[2] = { 0 };
+ U32 spec_count[2] = { 0 };
+ U32 normspec_count[2] = { 0 };
U32 useage = group->getSpatialPartition()->mBufferUsage;
@@ -5510,7 +5546,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();
@@ -5537,7 +5573,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
std::string vobj_name = llformat("Vol%p", vobj);
- if (vobj->isMesh() &&
+ bool is_mesh = vobj->isMesh();
+ if (is_mesh &&
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
{
continue;
@@ -5550,7 +5587,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
}
- bool is_mesh = vobj->isMesh();
+
F32 est_tris = vobj->getEstTrianglesMax();
vobj->updateControlAvatar();
@@ -5574,15 +5611,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
drawablep->clearState(LLDrawable::HAS_ALPHA);
- if (vobj->isRiggedMesh() &&
- ((vobj->isAnimatedObject() && vobj->getControlAvatar()) ||
- (!vobj->isAnimatedObject() && vobj->getAvatar())))
+ LLVOAvatar* avatar = nullptr;
+ const LLMeshSkinInfo* skinInfo = nullptr;
+ if (is_mesh)
+ {
+ skinInfo = vobj->getSkinInfo();
+ }
+
+ if (skinInfo)
{
- vobj->getAvatar()->addAttachmentOverridesForObject(vobj, NULL, false);
+ if (vobj->isAnimatedObject())
+ {
+ avatar = vobj->getControlAvatar();
+ }
+ else
+ {
+ avatar = vobj->getAvatar();
+ }
+ }
+
+ if (avatar != nullptr)
+ {
+ avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
// Standard rigged mesh attachments:
- bool rigged = !vobj->isAnimatedObject() && vobj->isRiggedMesh() && vobj->isAttachment();
+ bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
// exclude static objects in animated object linksets.
rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
@@ -5606,183 +5660,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//sum up face verts and indices
drawablep->updateFaceSize(i);
-
- if (rigged)
- {
- if (!facep->isState(LLFace::RIGGED))
- { //completely reset vertex buffer
- facep->clearVertexBuffer();
- }
-
- facep->setState(LLFace::RIGGED);
- any_rigged_face = true;
-
- //get drawpool of avatar with rigged face
- LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
-
- if (pool)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
-
- //remove face from old pool if it exists
- LLDrawPool* old_pool = facep->getPool();
- if (old_pool
- && (old_pool->getType() == LLDrawPool::POOL_AVATAR || old_pool->getType() == LLDrawPool::POOL_CONTROL_AV))
- {
- ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
- }
-
- //add face to new pool
- LLViewerTexture* tex = facep->getTexture();
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-
- F32 te_alpha = te->getColor().mV[3];
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
-
- LLMaterial* mat = te->getMaterialParams().get();
- bool fullbright = te->getFullbright();
-
- if (mat && LLPipeline::sRenderDeferred)
- {
- U8 alpha_mode = mat->getDiffuseAlphaMode();
-
- bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
- (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
- te_alpha < 0.999f);
- if (is_alpha)
- { //this face needs alpha blending, override alpha mode
- alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
- }
-
- if (fullbright && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE))
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
- else if (!is_alpha || te_alpha > 0.f) // //only add the face if it will actually be visible
- {
- U32 mask = mat->getShaderMask(alpha_mode);
- pool->addRiggedFace(facep, mask);
- }
-
- if(vobj->isAnimatedObject() && vobj->isRiggedMesh())
- {
- pool->updateRiggedVertexBuffers(vobj->getAvatar());
- }
- }
- else if (mat)
- {
- bool is_alpha = type == LLDrawPool::POOL_ALPHA;
- U8 mode = mat->getDiffuseAlphaMode();
- bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
- mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
-
- if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f)
- {
- pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- else if (is_alpha || (te->getColor().mV[3] < 0.999f))
- {
- if (te->getColor().mV[3] > 0.f)
- {
- pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA);
- }
- }
- else if (gPipeline.canUseVertexShaders()
- && LLPipeline::sRenderBump
- && te->getShiny()
- && can_be_shiny)
- {
- pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY);
- }
- else
- {
- pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- }
- else
- {
- if (type == LLDrawPool::POOL_ALPHA)
- {
- if (te->getColor().mV[3] > 0.f)
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
- }
- }
- }
- else if (te->getShiny())
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
- }
- else
- {
- if (LLPipeline::sRenderDeferred)
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
- }
- }
- }
- else
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- }
-
-
- if (LLPipeline::sRenderDeferred)
- {
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
- {
- if (te->getBumpmap())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
- }
- }
- }
- }
- }
-
- continue;
- }
- else
- {
- if (facep->isState(LLFace::RIGGED))
- { //face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeRiggedFace(facep);
- }
- facep->clearState(LLFace::RIGGED);
- }
- }
+ if (rigged)
+ {
+ if (!facep->isState(LLFace::RIGGED))
+ { //completely reset vertex buffer
+ facep->clearVertexBuffer();
+ }
+ facep->setState(LLFace::RIGGED);
+ facep->mSkinInfo = (LLMeshSkinInfo*) skinInfo; // TODO -- fix ugly de-consting here
+ facep->mAvatar = avatar;
+ any_rigged_face = true;
+ }
+ else
+ {
+ if (facep->isState(LLFace::RIGGED))
+ {
+ //face is not rigged but used to be, remove from rigged face pool
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ if (pool)
+ {
+ pool->removeFace(facep);
+ }
+ facep->clearState(LLFace::RIGGED);
+ }
+ }
if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
{
@@ -5792,7 +5695,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
cur_total += facep->getGeomCount();
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
+ if (facep->hasGeometry() &&
+ (rigged || // <-- HACK FIXME -- getPixelArea might be incorrect for rigged objects
+ facep->getPixelArea() > FORCE_CULL_AREA)) // <-- don't render tiny faces
{
const LLTextureEntry* te = facep->getTextureEntry();
LLViewerTexture* tex = facep->getTexture();
@@ -5851,21 +5756,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 || te->getGlow() > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
+ else if (LLDrawPoolAlpha::sShowDebugAlpha)
+ {
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
}
}
else
@@ -5885,81 +5788,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);
}
}
}
@@ -5975,6 +5848,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!drawablep->isState(LLDrawable::RIGGED))
{
drawablep->setState(LLDrawable::RIGGED);
+ LLDrawable* root = drawablep->getRoot();
+ if (root != drawablep)
+ {
+ root->setState(LLDrawable::RIGGED_CHILD);
+ }
//first time this is drawable is being marked as rigged,
// do another LoD update to use avatar bounding box
@@ -6014,6 +5892,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
+ // add extra vertex data for deferred rendering (not necessarily for batching textures)
if (batch_textures)
{
bump_mask = bump_mask | LLVertexBuffer::MAP_TANGENT;
@@ -6026,13 +5905,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 geometryBytes = 0;
- geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
- geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
- geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
- geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
- geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
- geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
- geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
+ U32 extra_mask = LLVertexBuffer::MAP_TEXTURE_INDEX;
+ geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[0], simple_count[0], FALSE, batch_textures);
+ geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[0], fullbright_count[0], FALSE, batch_textures);
+ geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[0], alpha_count[0], TRUE, batch_textures);
+ geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[0], bump_count[0], FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[0], norm_count[0], FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[0], spec_count[0], FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[0], normspec_count[0], FALSE, FALSE);
+
+ extra_mask |= LLVertexBuffer::MAP_WEIGHT4;
+ geometryBytes += genDrawInfo(group, simple_mask | extra_mask, sSimpleFaces[1], simple_count[1], FALSE, batch_textures, TRUE);
+ geometryBytes += genDrawInfo(group, fullbright_mask | extra_mask, sFullbrightFaces[1], fullbright_count[1], FALSE, batch_textures, TRUE);
+ geometryBytes += genDrawInfo(group, alpha_mask | extra_mask, sAlphaFaces[1], alpha_count[1], TRUE, batch_textures, TRUE);
+ geometryBytes += genDrawInfo(group, bump_mask | extra_mask, sBumpFaces[1], bump_count[1], FALSE, TRUE);
+ geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[1], norm_count[1], FALSE, TRUE);
+ geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[1], spec_count[1], FALSE, TRUE);
+ geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[1], normspec_count[1], FALSE, TRUE);
group->mGeometryBytes = geometryBytes;
@@ -6061,133 +5950,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
@@ -6197,7 +6083,7 @@ struct CompareBatchBreakerModified
const LLTextureEntry* lte = lhs->getTextureEntry();
const LLTextureEntry* rte = rhs->getTextureEntry();
- if (lte->getBumpmap() != rte->getBumpmap())
+ if (lte->getBumpmap() != rte->getBumpmap())
{
return lte->getBumpmap() < rte->getBumpmap();
}
@@ -6220,19 +6106,45 @@ 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");
-
-
+struct CompareBatchBreakerRigged
+{
+ bool operator()(const LLFace* const& lhs, const LLFace* const& rhs)
+ {
+ const LLTextureEntry* lte = lhs->getTextureEntry();
+ const LLTextureEntry* rte = rhs->getTextureEntry();
+ if (lhs->mAvatar != rhs->mAvatar)
+ {
+ return lhs->mAvatar < rhs->mAvatar;
+ }
+ else if (lhs->mSkinInfo->mHash != rhs->mSkinInfo->mHash)
+ {
+ return lhs->mSkinInfo->mHash < rhs->mSkinInfo->mHash;
+ }
+ else if (lhs->getTexture() != rhs->getTexture())
+ {
+ return lhs->getTexture() < rhs->getTexture();
+ }
+ else if (lte->getBumpmap() != rte->getBumpmap())
+ {
+ return lte->getBumpmap() < rte->getBumpmap();
+ }
+ else if (LLPipeline::sRenderDeferred && lte->getMaterialID() != rte->getMaterialID())
+ {
+ return lte->getMaterialID() < rte->getMaterialID();
+ }
+ else // if (LLPipeline::sRenderDeferred && (lte->getMaterialParams() == rte->getMaterialParams()) && (lte->getShiny() != rte->getShiny()))
+ {
+ return lte->getShiny() < rte->getShiny();
+ }
+
+ }
+};
-U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
+U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
- LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+ LL_PROFILE_ZONE_SCOPED;
U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
@@ -6264,12 +6176,18 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
max_vertices = llmin(max_vertices, (U32) 65535);
{
- LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_SORT);
- if (!distance_sort)
- {
- //sort faces by things that break batches
- std::sort(faces, faces+face_count, CompareBatchBreakerModified());
- }
+ LL_PROFILE_ZONE_NAMED("genDrawInfo - sort");
+
+ if (rigged)
+ {
+ //sort faces by things that break batches, including avatar and mesh id
+ std::sort(faces, faces + face_count, CompareBatchBreakerRigged());
+ }
+ else if (!distance_sort)
+ {
+ //sort faces by things that break batches, not including avatar and mesh id
+ std::sort(faces, faces + face_count, CompareBatchBreakerModified());
+ }
else
{
//sort faces by distance
@@ -6286,11 +6204,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LLViewerTexture* last_tex = NULL;
S32 buffer_index = 0;
- if (distance_sort)
- {
- buffer_index = -1;
- }
-
S32 texture_index_channels = 1;
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
@@ -6302,6 +6215,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
}
+
+ if (rigged)
+ { //don't attempt distance sorting on rigged meshes, not likely to succeed and breaks batches
+ distance_sort = FALSE;
+ }
+
+ if (distance_sort)
+ {
+ buffer_index = -1;
+ }
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
@@ -6316,7 +6239,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//pull off next face
LLFace* facep = *face_iter;
LLViewerTexture* tex = facep->getTexture();
- LLMaterialPtr mat = facep->getTextureEntry()->getMaterialParams();
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLMaterialPtr mat = te->getMaterialParams();
+ LLMaterialID matId = te->getMaterialID();
if (distance_sort)
{
@@ -6350,7 +6275,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;
@@ -6439,11 +6364,14 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
while (i != end_faces &&
(LLPipeline::sTextureBindTest ||
(distance_sort ||
- ((*i)->getTexture() == tex &&
- ((*i)->getTextureEntry()->getMaterialParams() == mat)))))
+ ((*i)->getTexture() == tex))))
{
facep = *i;
-
+ const LLTextureEntry* nextTe = facep->getTextureEntry();
+ if (nextTe->getMaterialID() != matId)
+ {
+ break;
+ }
//face has no texture index
facep->mDrawInfo = NULL;
@@ -6473,7 +6401,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))
{
@@ -6533,8 +6461,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 te_idx = facep->getTEOffset();
- llassert(!facep->isState(LLFace::RIGGED));
-
if (!facep->getGeometryVolume(*volume, te_idx,
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
{
@@ -6631,10 +6557,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
}
- else if (no_materials)
- {
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
else if (transparent)
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
@@ -6699,7 +6621,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
- else if (gPipeline.canUseVertexShaders()
+ else if (gPipeline.shadersLoaded()
&& LLPipeline::sRenderBump
&& te->getShiny()
&& can_be_shiny)
@@ -6734,7 +6656,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
}
- else if (gPipeline.canUseVertexShaders()
+ else if (gPipeline.shadersLoaded()
&& LLPipeline::sRenderBump
&& te->getShiny()
&& can_be_shiny)
@@ -6815,7 +6737,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
- if (!gPipeline.canUseVertexShaders() &&
+ if (!gPipeline.shadersLoaded() &&
!is_alpha &&
te->getShiny() &&
LLPipeline::sRenderBump)
@@ -6861,6 +6783,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 73eeec813c..d158044f5d 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -295,6 +295,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..089a7712c0 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)
@@ -145,7 +143,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
static const unsigned int vertices_per_quad = 4;
static const unsigned int indices_per_quad = 6;
- const S32 size = LLPipeline::sRenderTransparentWater && LLGLSLShader::sNoFixedFunction ? 16 : 1;
+ const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1;
const S32 num_quads = size * size;
face->setSize(vertices_per_quad * num_quads,
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..d7f16713d2 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -135,6 +135,7 @@ void LLWorld::destroyClass()
LLDrawable::incrementVisible();
LLSceneMonitor::deleteSingleton();
+ LLWorld::deleteSingleton();
}
@@ -884,6 +885,7 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh
void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!gAgent.getRegion())
{
return;
@@ -1077,6 +1079,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 +1150,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 +1223,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 +1289,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/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index a6df079223..59ac4554d7 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -321,22 +321,19 @@ void LLWorldMapView::draw()
// Clear the background alpha to 0
gGL.flush();
gGL.setColorMask(false, true);
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f);
+ gGL.flush();
gGL.setSceneBlendType(LLRender::BT_REPLACE);
gGL.color4f(0.0f, 0.0f, 0.0f, 0.0f);
gl_rect_2d(0, height, width, 0);
}
gGL.flush();
-
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
gGL.setColorMask(true, true);
// Draw the image tiles
drawMipmap(width, height);
gGL.flush();
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
gGL.setColorMask(true, true);
// Draw per sim overlayed information (names, mature, offline...)
@@ -480,13 +477,13 @@ void LLWorldMapView::draw()
LLGLSUIDefault gls_ui;
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f);
+ gGL.flush();
gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d(0, height, width, 0);
}
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ gGL.flush();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
// Draw item infos if we're not zoomed out too much and there's something to draw
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index cd1b9c7c69..d5f9772b85 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -142,7 +142,6 @@
bool gShiftFrame = false;
//cached settings
-bool LLPipeline::RenderAvatarVP;
bool LLPipeline::WindLightUseAtmosShaders;
bool LLPipeline::RenderDeferred;
F32 LLPipeline::RenderDeferredSunWash;
@@ -238,7 +237,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 +251,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 +265,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 +331,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 +351,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;
@@ -385,8 +376,7 @@ LLPipeline::LLPipeline() :
mNumVisibleFaces(0),
mInitialized(false),
- mVertexShadersEnabled(false),
- mVertexShadersLoaded(0),
+ mShadersLoaded(false),
mTransformFeedbackPrimitives(0),
mRenderDebugFeatureMask(0),
mRenderDebugMask(0),
@@ -487,6 +477,10 @@ void LLPipeline::init()
{
clearAllRenderTypes();
}
+ else if (gNonInteractive)
+ {
+ clearAllRenderTypes();
+ }
else
{
setAllRenderTypes(); // By default, all rendering types start enabled
@@ -541,7 +535,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
connectRefreshCachedSettingsSafe("UseOcclusion");
- connectRefreshCachedSettingsSafe("RenderAvatarVP");
connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
connectRefreshCachedSettingsSafe("RenderDeferred");
connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
@@ -725,8 +718,6 @@ void LLPipeline::destroyGL()
}
}
-static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
-
void LLPipeline::requestResizeScreenTexture()
{
gResizeScreenTexture = TRUE;
@@ -746,8 +737,7 @@ void LLPipeline::resizeShadowTexture()
void LLPipeline::resizeScreenTexture()
{
- LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE);
- if (gPipeline.canUseVertexShaders() && assertInitialized())
+ if (gPipeline.shadersLoaded())
{
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
@@ -758,8 +748,8 @@ void LLPipeline::resizeScreenTexture()
releaseShadowTargets();
allocateScreenBuffer(resX,resY);
gResizeScreenTexture = FALSE;
- }
- }
+ }
+ }
}
void LLPipeline::allocatePhysicsBuffer()
@@ -900,7 +890,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!addDeferredAttachments(mDeferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
- if (gGLManager.mIsATI)
+ if (gGLManager.mIsAMD)
{
screenFormat = GL_RGBA12;
}
@@ -1054,8 +1044,6 @@ void LLPipeline::updateRenderDeferred()
RenderDeferred &&
LLRenderTarget::sUseFBO &&
LLPipeline::sRenderBump &&
- LLPipeline::sRenderTransparentWater &&
- RenderAvatarVP &&
WindLightUseAtmosShaders &&
(bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
}
@@ -1072,12 +1060,10 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
- && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
&& gSavedSettings.getBOOL("UseOcclusion")
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
- RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
@@ -1153,6 +1139,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 +1224,8 @@ void LLPipeline::releaseShadowTargets()
void LLPipeline::createGLBuffers()
{
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
+ stop_glerror();
assertInitialized();
updateRenderDeferred();
@@ -1370,10 +1363,7 @@ void LLPipeline::restoreGL()
{
assertInitialized();
- if (mVertexShadersEnabled)
- {
- LLViewerShaderMgr::instance()->setShaders();
- }
+ LLViewerShaderMgr::instance()->setShaders();
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -1385,31 +1375,19 @@ void LLPipeline::restoreGL()
if (part)
{
part->restoreGL();
- }
+ }
}
}
}
-
-bool LLPipeline::canUseVertexShaders()
+bool LLPipeline::shadersLoaded()
{
- if (sDisableShaders ||
- !gGLManager.mHasVertexShader ||
- !gGLManager.mHasFragmentShader ||
- (assertInitialized() && mVertexShadersLoaded != 1) )
- {
- return false;
- }
- else
- {
- return true;
- }
+ return (assertInitialized() && mShadersLoaded);
}
bool LLPipeline::canUseWindLightShaders() const
{
- return (!LLPipeline::sDisableShaders &&
- gWLSkyProgram.mProgramObject != 0 &&
+ return (gWLSkyProgram.mProgramObject != 0 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
}
@@ -1427,8 +1405,7 @@ bool LLPipeline::canUseAntiAliasing() const
void LLPipeline::unloadShaders()
{
LLViewerShaderMgr::instance()->unloadShaders();
-
- mVertexShadersLoaded = 0;
+ mShadersLoaded = false;
}
void LLPipeline::assertInitializedDoError()
@@ -1514,6 +1491,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 +1703,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 +1714,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 +1723,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 +1733,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 +1765,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 +1798,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 +1822,7 @@ void LLPipeline::createObjects(F32 max_dtime)
void LLPipeline::createObject(LLViewerObject* vobj)
{
+ LL_PROFILE_ZONE_SCOPED;
LLDrawable* drawablep = vobj->mDrawable;
if (!drawablep)
@@ -1897,6 +1860,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
void LLPipeline::resetFrameStats()
{
+ LL_PROFILE_ZONE_SCOPED
assertInitialized();
sCompiles = 0;
@@ -1912,6 +1876,7 @@ void LLPipeline::resetFrameStats()
//external functions for asynchronous updating
void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (FreezeTime)
{
return;
@@ -1942,6 +1907,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
{
+ LL_PROFILE_ZONE_SCOPED;
if (FreezeTime)
{
return;
@@ -1972,6 +1938,7 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
{
+ LL_PROFILE_ZONE_SCOPED;
for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
iter != moved_list.end(); )
{
@@ -2005,14 +1972,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 +1983,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 +2076,7 @@ void LLPipeline::grabReferences(LLCullResult& result)
void LLPipeline::clearReferences()
{
+ LL_PROFILE_ZONE_SCOPED
sCull = NULL;
mGroupSaveQ1.clear();
}
@@ -2372,20 +2324,28 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
-void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep)
+void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
{
static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
- static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction
- && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
+ static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
&& gGLManager.mHasOcclusionQuery;
LL_RECORD_BLOCK_TIME(FTM_CULL);
+ if (planep != nullptr)
+ {
+ camera.setUserClipPlane(*planep);
+ }
+ else
+ {
+ camera.disableUserClipPlane();
+ }
+
grabReferences(result);
sCull->clear();
- bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.canUseVertexShaders();
+ bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded();
if (to_texture)
{
@@ -2419,7 +2379,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bool bound_shader = false;
- if (gPipeline.canUseVertexShaders() && LLGLSLShader::sCurBoundShader == 0)
+ if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0)
{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
// (shadow render uses a special shader that clamps to clip planes)
bound_shader = true;
@@ -2435,11 +2395,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
- if (!sReflectionRender)
- {
- camera.disableUserClipPlane();
- }
-
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -2461,8 +2416,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;
vo_part->cull(camera, do_occlusion_cull);
}
}
@@ -2553,13 +2507,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 +2616,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();
@@ -2690,7 +2638,7 @@ void LLPipeline::doOcclusion(LLCamera& camera)
LLGLDisable cull(GL_CULL_FACE);
- bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0;
+ bool bind_shader = (LLGLSLShader::sCurBoundShader == 0);
if (bind_shader)
{
if (LLPipeline::sShadowRender)
@@ -2753,14 +2701,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 +2715,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 +2826,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 +2848,6 @@ void LLPipeline::rebuildPriorityGroups()
}
-static LLTrace::BlockTimerStatHandle FTM_REBUILD_GROUPS("Rebuild Groups");
-
void LLPipeline::rebuildGroups()
{
if (mGroupQ2.empty())
@@ -2915,7 +2855,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 +3101,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 +3112,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 +3172,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 +3274,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 +3287,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 +3406,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 +3420,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 +3714,36 @@ void renderSoundHighlights(LLDrawable* drawablep)
}
}
+void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)
+{
+ if (tex)
+ {
+ LLImageGL* gl_tex = tex->getGLTexture();
+ if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ {
+ tex->setActive();
+ tex->addTextureStats(vsize);
+ }
+ }
+
+
+}
+void LLPipeline::touchTextures(LLDrawInfo* info)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ for (int i = 0; i < info->mTextureList.size(); ++i)
+ {
+ touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
+ }
+
+ touchTexture(info->mTexture, info->mVSize);
+ touchTexture(info->mSpecularMap, info->mVSize);
+ touchTexture(info->mNormalMap, info->mVSize);
+}
+
void LLPipeline::postSort(LLCamera& camera)
{
- LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT);
+ LL_PROFILE_ZONE_SCOPED;
assertInitialized();
@@ -3842,20 +3793,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 +3939,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())
@@ -4038,10 +3986,7 @@ void render_hud_elements()
gGL.color4f(1,1,1,1);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
@@ -4052,8 +3997,11 @@ void render_hud_elements()
// Draw the tracking overlays
LLTracker::render3D();
- // Show the property lines
- LLWorld::getInstance()->renderPropertyLines();
+ if (LLWorld::instanceExists())
+ {
+ // Show the property lines
+ LLWorld::getInstance()->renderPropertyLines();
+ }
LLViewerParcelMgr::getInstance()->render();
LLViewerParcelMgr::getInstance()->renderParcelCollision();
@@ -4070,10 +4018,7 @@ void render_hud_elements()
LLHUDText::renderAllHUD();
}
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
gGL.flush();
}
@@ -4105,10 +4050,7 @@ void LLPipeline::renderHighlights()
gGL.setColorMask(false, false);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gHighlightProgram.bind();
- }
+ gHighlightProgram.bind();
for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter)
{
@@ -4340,7 +4282,6 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
// Do verification of GL state
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
if (mRenderDebugMask & RENDER_DEBUG_VERIFY)
{
if (!verify())
@@ -4564,92 +4505,98 @@ 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();
- 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 +4696,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 +4762,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)
@@ -4853,10 +4802,7 @@ void LLPipeline::renderPhysicsDisplay()
gGL.setColorMask(true, false);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.bind();
- }
+ gDebugProgram.bind();
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -4877,11 +4823,7 @@ void LLPipeline::renderPhysicsDisplay()
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.unbind();
- }
-
+ gDebugProgram.unbind();
mPhysicsDisplay.flush();
}
@@ -4908,13 +4850,10 @@ void LLPipeline::renderDebug()
if ( pathfindingCharacter->getVisible() || gAgentCamera.cameraMouselook() )
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f(sTint, 1.f);
- gPathfindingProgram.uniform1f(sAmbiance, 1.f);
- gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
- }
+ gPathfindingProgram.bind();
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
//Requried character physics capsule render parameters
LLUUID id;
@@ -4923,21 +4862,14 @@ void LLPipeline::renderDebug()
if ( pathfindingCharacter->isPhysicsCapsuleEnabled( id, pos, rot ) )
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- //remove blending artifacts
- gGL.setColorMask(false, false);
- llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
- gGL.setColorMask(true, false);
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
- gPathfindingProgram.bind();
- }
- else
- {
- llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
- }
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gGL.setColorMask(true, false);
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
+ gPathfindingProgram.bind();
}
}
}
@@ -4953,14 +4885,11 @@ void LLPipeline::renderDebug()
{
F32 ambiance = gSavedSettings.getF32("PathfindingAmbiance");
- if (LLGLSLShader::sNoFixedFunction)
- {
- gPathfindingProgram.bind();
+ gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f(sTint, 1.f);
- gPathfindingProgram.uniform1f(sAmbiance, ambiance);
- gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
- }
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
if ( !pathfindingConsole->isRenderWorld() )
{
@@ -4992,18 +4921,11 @@ void LLPipeline::renderDebug()
}
//render edges
- if (LLGLSLShader::sNoFixedFunction)
- {
- gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
- gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
- llPathingLibInstance->renderNavMeshEdges();
- gPathfindingProgram.bind();
- }
- else
- {
- llPathingLibInstance->renderNavMeshEdges();
- }
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
gGL.flush();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
@@ -5014,53 +4936,31 @@ void LLPipeline::renderDebug()
if ( LLPathfindingPathTool::getInstance()->isRenderPath() )
{
//The path
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
- llPathingLibInstance->renderPath();
- gPathfindingProgram.bind();
- }
- else
- {
- llPathingLibInstance->renderPath();
- }
- //The bookends
- if (LLGLSLShader::sNoFixedFunction)
- {
- //remove blending artifacts
- gGL.setColorMask(false, false);
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+ gUIProgram.bind();
+ gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
+ llPathingLibInstance->renderPath();
+ gPathfindingProgram.bind();
+
+ //The bookends
+ //remove blending artifacts
+ gGL.setColorMask(false, false);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
- gGL.setColorMask(true, false);
- //render the bookends
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
- gPathfindingProgram.bind();
- }
- else
- {
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
- llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
- }
-
+ gGL.setColorMask(true, false);
+ //render the bookends
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
+ llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
+ gPathfindingProgram.bind();
}
if ( pathfindingConsole->isRenderWaterPlane() )
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
- llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
- }
- else
- {
- llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
- }
+ LLGLEnable blend(GL_BLEND);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
+ llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
}
//physics/exclusion shapes
if ( pathfindingConsole->isRenderAnyShapes() )
@@ -5191,18 +5091,11 @@ void LLPipeline::renderDebug()
}
//render edges
- if (LLGLSLShader::sNoFixedFunction)
- {
- gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
- llPathingLibInstance->renderNavMeshEdges();
- gPathfindingProgram.bind();
- }
- else
- {
- llPathingLibInstance->renderNavMeshEdges();
- }
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
+ llPathingLibInstance->renderNavMeshEdges();
+ gPathfindingProgram.bind();
gGL.flush();
glLineWidth(1.0f);
@@ -5211,10 +5104,7 @@ void LLPipeline::renderDebug()
glPolygonOffset(0.f, 0.f);
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gPathfindingProgram.unbind();
- }
+ gPathfindingProgram.unbind();
}
}
}
@@ -5229,10 +5119,7 @@ void LLPipeline::renderDebug()
if (!hud_only && !mDebugBlips.empty())
{ //render debug blips
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true);
@@ -5296,7 +5183,7 @@ void LLPipeline::renderDebug()
}
}
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
{ //render visible selected group occlusion geometry
gDebugProgram.bind();
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
@@ -5318,44 +5205,38 @@ void LLPipeline::renderDebug()
visible_selected_groups.clear();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
{ //draw crosshairs on particle intersection
if (gDebugRaycastParticle)
{
- if (LLGLSLShader::sNoFixedFunction)
- { //this debug display requires shaders
- gDebugProgram.bind();
+ gDebugProgram.bind();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
- LLVector3 size(0.1f, 0.1f, 0.1f);
+ LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
+ LLVector3 size(0.1f, 0.1f, 0.1f);
- LLVector3 p[6];
+ LLVector3 p[6];
- p[0] = center + size.scaledVec(LLVector3(1,0,0));
- p[1] = center + size.scaledVec(LLVector3(-1,0,0));
- p[2] = center + size.scaledVec(LLVector3(0,1,0));
- p[3] = center + size.scaledVec(LLVector3(0,-1,0));
- p[4] = center + size.scaledVec(LLVector3(0,0,1));
- p[5] = center + size.scaledVec(LLVector3(0,0,-1));
+ p[0] = center + size.scaledVec(LLVector3(1,0,0));
+ p[1] = center + size.scaledVec(LLVector3(-1,0,0));
+ p[2] = center + size.scaledVec(LLVector3(0,1,0));
+ p[3] = center + size.scaledVec(LLVector3(0,-1,0));
+ p[4] = center + size.scaledVec(LLVector3(0,0,1));
+ p[5] = center + size.scaledVec(LLVector3(0,0,-1));
- gGL.begin(LLRender::LINES);
- gGL.diffuseColor3f(1.f, 1.f, 0.f);
- for (U32 i = 0; i < 6; i++)
- {
- gGL.vertex3fv(p[i].mV);
- }
- gGL.end();
- gGL.flush();
-
- gDebugProgram.unbind();
+ gGL.begin(LLRender::LINES);
+ gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ for (U32 i = 0; i < 6; i++)
+ {
+ gGL.vertex3fv(p[i].mV);
}
+ gGL.end();
+ gGL.flush();
+
+ gDebugProgram.unbind();
}
}
@@ -5588,17 +5469,12 @@ void LLPipeline::renderDebug()
}
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
}
-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 +5818,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)
@@ -6261,11 +6138,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
- if (!LLGLSLShader::sNoFixedFunction)
- {
- gGL.syncMatrices();
- }
-
// Ambient
LLColor4 ambient = psky->getTotalAmbient();
gGL.setAmbientLightColor(ambient);
@@ -6387,21 +6259,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 +6280,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
@@ -6466,11 +6336,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
// prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20
// Init GL state
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_LIGHTING);
- }
-
for (S32 i = 0; i < 8; ++i)
{
gGL.getLight(i)->disable();
@@ -6489,13 +6354,6 @@ void LLPipeline::enableLights(U32 mask)
if (mLightMask != mask)
{
stop_glerror();
- if (!mLightMask)
- {
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glEnable(GL_LIGHTING);
- }
- }
if (mask)
{
stop_glerror();
@@ -6515,13 +6373,6 @@ void LLPipeline::enableLights(U32 mask)
}
stop_glerror();
}
- else
- {
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glDisable(GL_LIGHTING);
- }
- }
mLightMask = mask;
stop_glerror();
}
@@ -6572,11 +6423,6 @@ void LLPipeline::enableLightsPreview()
{
disableLights();
- if (!LLGLSLShader::sNoFixedFunction)
- {
- glEnable(GL_LIGHTING);
- }
-
LLColor4 ambient = PreviewAmbientColor;
gGL.setAmbientLightColor(ambient);
@@ -7357,8 +7203,6 @@ void LLPipeline::resetVertexBuffers()
mResetVertexBuffers = true;
}
-static LLTrace::BlockTimerStatHandle FTM_RESET_VB("Reset VB");
-
void LLPipeline::doResetVertexBuffers(bool forced)
{
if (!mResetVertexBuffers)
@@ -7380,7 +7224,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
}
}
- LL_RECORD_BLOCK_TIME(FTM_RESET_VB);
+ LL_PROFILE_ZONE_SCOPED;
mResetVertexBuffers = false;
mCubeVB = NULL;
@@ -7450,32 +7294,91 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLVOPartGroup::restoreGL();
}
-void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture)
+void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
{
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
- mSimplePool->pushBatches(type, mask, texture, batch_texture);
+ if (rigged)
+ {
+ mSimplePool->pushRiggedBatches(type + 1, mask, texture, batch_texture);
+ }
+ else
+ {
+ mSimplePool->pushBatches(type, mask, texture, batch_texture);
+ }
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
-void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture)
+void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ U32 type = LLRenderPass::PASS_ALPHA;
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ {
+ LLDrawInfo* pparams = *i;
+ if (pparams)
+ {
+ if (rigged)
+ {
+ if (pparams->mAvatar != nullptr)
+ {
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
+ {
+ mSimplePool->uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
+ }
+ }
+ else if (pparams->mAvatar == nullptr)
+ {
+ mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
+ }
+ }
+ }
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
{
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
- mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ if (rigged)
+ {
+ mAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture);
+ }
+ else
+ {
+ mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ }
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
-void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture)
+void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
{
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
- mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ if (rigged)
+ {
+ mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture);
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ }
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
@@ -7580,11 +7483,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 +7550,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)
{
@@ -8079,18 +7976,7 @@ void LLPipeline::renderFinalize()
LLGLDisable blend(GL_BLEND);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gGlowCombineProgram.bind();
- }
- else
- {
- // tex unit 0
- gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
- // tex unit 1
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR,
- LLTexUnit::TBS_PREV_COLOR);
- }
+ gGlowCombineProgram.bind();
gGL.getTexUnit(0)->bind(&mGlow[1]);
gGL.getTexUnit(1)->bind(&mScreen);
@@ -8100,28 +7986,14 @@ void LLPipeline::renderFinalize()
buff->setBuffer(mask);
buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
- if (LLGLSLShader::sNoFixedFunction)
- {
- gGlowCombineProgram.unbind();
- }
- else
- {
- gGL.getTexUnit(1)->disable();
- gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
-
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
- }
+ gGlowCombineProgram.unbind();
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
{
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSplatTextureRectProgram.bind();
- }
+ gSplatTextureRectProgram.bind();
gGL.setColorMask(true, false);
@@ -8147,10 +8019,7 @@ void LLPipeline::renderFinalize()
gGL.end();
gGL.flush();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gSplatTextureRectProgram.unbind();
- }
+ gSplatTextureRectProgram.unbind();
}
if (LLRenderTarget::sUseFBO)
@@ -8171,11 +8040,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 +8284,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 +8302,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 +8381,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 +8427,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 +8505,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 +8571,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLVertexBuffer::unbind();
{
+ LL_PROFILE_ZONE_NAMED("renderDeferredLighting - local lights");
bindDeferredShader(gDeferredLightProgram);
if (mCubeVB.isNull())
@@ -8786,7 +8642,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 +8677,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 +8687,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 +8722,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 +8742,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 +8773,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,8 +9116,19 @@ 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)
{
+ //disable occlusion culling for reflection/refraction passes (save setting to restore later)
+ S32 occlude = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0;
+
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
{
@@ -9300,26 +9165,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
//plane params
LLPlane plane;
LLVector3 pnorm;
- S32 water_clip = 0;
- if (!camera_is_underwater)
+
+ if (camera_is_underwater)
{
- //camera is above water, clip plane points up
- pnorm.setVec(0,0,1);
- plane.setVec(pnorm, -water_height);
- water_clip = 1;
+ //camera is below water, cull above water
+ pnorm.setVec(0, 0, 1);
}
else
{
- //camera is below water, clip plane points down
- pnorm = LLVector3(0,0,-1);
- plane.setVec(pnorm, water_height);
- water_clip = -1;
+ //camera is above water, cull below water
+ pnorm = LLVector3(0, 0, -1);
}
- S32 occlusion = LLPipeline::sUseOcclusion;
-
- //disable occlusion culling for reflection map for now
- LLPipeline::sUseOcclusion = 0;
+ plane.setVec(LLVector3(0, 0, water_height), pnorm);
if (!camera_is_underwater)
{
@@ -9418,7 +9276,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, mReflectedObjects, -water_clip, &plane);
+ updateCull(camera, mReflectedObjects, &plane);
stateSort(camera, mReflectedObjects);
renderGeom(camera);
}
@@ -9436,8 +9294,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;
@@ -9485,41 +9341,47 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
mWaterDis.clear();
gGL.setColorMask(true, false);
- F32 water_dist = water_height * LLPipeline::sDistortionWaterClipPlaneMargin;
+ F32 water_dist = water_height;
//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;
+
+ if (camera_is_underwater)
+ {
+ //nudge clip plane below water to avoid visible holes in objects intersecting water surface
+ water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin;
+ //camera is below water, clip plane points up
+ pnorm.setVec(0, 0, -1);
+ }
+ else
+ {
+ //nudge clip plane above water to avoid visible holes in objects intersecting water surface
+ water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin;
+ //camera is above water, clip plane points down
+ pnorm = LLVector3(0, 0, 1);
+ }
+
+ plane.setVec(LLVector3(0, 0, water_dist), pnorm);
+
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);
+ updateCull(camera, mRefractedObjects, &plane);
stateSort(camera, mRefractedObjects);
renderGeom(camera);
}
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.bind();
- }
+ gUIProgram.bind();
LLWorld::getInstance()->renderPropertyLines();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gUIProgram.unbind();
- }
+ gUIProgram.unbind();
mWaterDis.flush();
}
@@ -9532,7 +9394,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
- LLPipeline::sUseOcclusion = occlusion;
LLPipeline::sUnderWaterRender = false;
LLPipeline::sReflectionRender = false;
@@ -9554,6 +9415,32 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+
+ // restore occlusion culling
+ LLPipeline::sUseOcclusion = occlude;
+ }
+ 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();
+ }
}
}
@@ -9634,204 +9521,212 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked");
-void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width)
+void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)
{
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
- //clip out geometry on the same side of water as the camera
- S32 occlude = LLPipeline::sUseOcclusion;
- if (!use_occlusion)
- {
- LLPipeline::sUseOcclusion = 0;
- }
- LLPipeline::sShadowRender = true;
-
- static const U32 types[] = {
- LLRenderPass::PASS_SIMPLE,
- LLRenderPass::PASS_FULLBRIGHT,
- LLRenderPass::PASS_SHINY,
- LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY ,
- LLRenderPass::PASS_MATERIAL,
- LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
- LLRenderPass::PASS_SPECMAP,
- LLRenderPass::PASS_SPECMAP_EMISSIVE,
- LLRenderPass::PASS_NORMMAP,
- LLRenderPass::PASS_NORMMAP_EMISSIVE,
- LLRenderPass::PASS_NORMSPEC,
- LLRenderPass::PASS_NORMSPEC_EMISSIVE,
- };
+ //disable occlusion culling for shadow passes (save setting to restore later)
+ S32 occlude = LLPipeline::sUseOcclusion;
+ if (!use_occlusion)
+ {
+ LLPipeline::sUseOcclusion = 0;
+ }
+ LLPipeline::sShadowRender = true;
+
+ static const U32 types[] = {
+ LLRenderPass::PASS_SIMPLE,
+ LLRenderPass::PASS_FULLBRIGHT,
+ LLRenderPass::PASS_SHINY,
+ LLRenderPass::PASS_BUMP,
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ };
+
+ LLGLEnable cull(GL_CULL_FACE);
+
+ //enable depth clamping if available
+ LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+
+ if (use_shader)
+ {
+ gDeferredShadowCubeProgram.bind();
+ }
- LLGLEnable cull(GL_CULL_FACE);
+ LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1];
- //enable depth clamping if available
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+ occlusion_target.bindTarget();
+ updateCull(shadow_cam, result);
+ occlusion_target.flush();
- if (use_shader)
- {
- gDeferredShadowCubeProgram.bind();
- }
+ stateSort(shadow_cam, result);
- LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
- occlusion_target.bindTarget();
- updateCull(shadow_cam, result);
- occlusion_target.flush();
+ //generate shadow map
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadMatrix(proj.m);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadMatrix(view.m);
- stateSort(shadow_cam, result);
-
-
- //generate shadow map
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadMatrix(proj.m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadMatrix(view.m);
+ stop_glerror();
+ gGLLastMatrix = NULL;
- stop_glerror();
- gGLLastMatrix = NULL;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ stop_glerror();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- stop_glerror();
-
LLEnvironment& environment = LLEnvironment::instance();
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
- {
- if (!use_shader)
- { //occlusion program is general purpose depth-only no-textures
- gOcclusionProgram.bind();
- }
- else
- {
- gDeferredShadowProgram.bind();
- gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- }
+ for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged
+ {
+ bool rigged = j == 1;
+ if (!use_shader)
+ { //occlusion program is general purpose depth-only no-textures
+ gOcclusionProgram.bind(rigged);
+ }
+ else
+ {
+ gDeferredShadowProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ }
- gGL.diffuseColor4f(1,1,1,1);
+ gGL.diffuseColor4f(1, 1, 1, 1);
S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
// if not using VSM, disable color writes
if (shadow_detail <= 2)
{
- gGL.setColorMask(false, false);
+ gGL.setColorMask(false, false);
}
-
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
-
- gGL.getTexUnit(0)->disable();
- for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
- {
- renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
- }
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!use_shader)
- {
- gOcclusionProgram.unbind();
- }
- }
-
- if (use_shader)
- {
+
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
+
+ gGL.getTexUnit(0)->disable();
+ for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)
+ {
+ renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged);
+ }
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ if (!use_shader)
+ {
+ gOcclusionProgram.unbind();
+ }
+
+
+ }
+
+ if (use_shader)
+ {
LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
- gDeferredShadowProgram.unbind();
- renderGeomShadow(shadow_cam);
- gDeferredShadowProgram.bind();
+ gDeferredShadowProgram.unbind();
+ renderGeomShadow(shadow_cam);
+ gDeferredShadowProgram.bind();
gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- }
- else
- {
+ }
+ else
+ {
LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
- renderGeomShadow(shadow_cam);
- }
+ renderGeomShadow(shadow_cam);
+ }
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
- gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- gDeferredShadowAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = i == 1;
- U32 mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_TEXTURE_INDEX;
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
- renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- }
+ U32 mask = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TEXTURE_INDEX;
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
- renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
- }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
+ }
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
- gDeferredShadowFullbrightAlphaMaskProgram.bind();
- gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
- }
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
+ renderAlphaObjects(mask, TRUE, TRUE, rigged);
+ }
- mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_TREE);
- gDeferredTreeShadowProgram.bind();
- gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
- renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
- renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
- renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
+ gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged);
+ }
+
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
+ gDeferredTreeShadowProgram.bind(rigged);
+ if (i == 0)
+ {
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
+ renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
+ }
+
+ U32 no_idx_mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, no_idx_mask, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged);
+ }
}
-
- {
- LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
- gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
- renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
- }
}
- //glCullFace(GL_BACK);
+ //glCullFace(GL_BACK);
- gDeferredShadowCubeProgram.bind();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
+ gDeferredShadowCubeProgram.bind();
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
- LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
+ LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1];
- doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
- if (use_shader)
- {
- gDeferredShadowProgram.unbind();
- }
-
- gGL.setColorMask(true, true);
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
- gGLLastMatrix = NULL;
+ if (use_shader)
+ {
+ gDeferredShadowProgram.unbind();
+ }
+
+ gGL.setColorMask(true, true);
- LLPipeline::sUseOcclusion = occlude;
- LLPipeline::sShadowRender = false;
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ gGLLastMatrix = NULL;
+
+ LLPipeline::sUseOcclusion = occlude;
+ 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))
@@ -10043,10 +9938,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
gGL.setColorMask(true, true);
mHighlight.clear();
- if (LLGLSLShader::sNoFixedFunction)
- {
- gHighlightProgram.bind();
- }
+ gHighlightProgram.bind();
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); )
@@ -10088,9 +9980,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)
@@ -10160,6 +10049,29 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_BUMP_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SHINY_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -10886,17 +10798,28 @@ 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");
+void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture)
+{
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ {
+ LLSpatialGroup* group = *i;
+ if (!group->isDead() &&
+ (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
+ gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
+ group->mDrawMap.find(type) != group->mDrawMap.end())
+ {
+ pass->renderRiggedGroup(group, type, mask, texture);
+ }
+ }
+}
+
+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();
static LLCullResult result;
result.clear();
@@ -10924,37 +10847,31 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (visually_muted || too_complex)
{
+ // only show jelly doll geometry
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
END_RENDER_TYPES);
}
else
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_GLOW,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
- LLPipeline::RENDER_TYPE_PASS_GLOW,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SHINY,
- LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
- LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- LLPipeline::RENDER_TYPE_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_INVISIBLE,
- LLPipeline::RENDER_TYPE_SIMPLE,
- END_RENDER_TYPES);
+ //hide world geometry
+ clearRenderTypeMask(
+ RENDER_TYPE_SKY,
+ RENDER_TYPE_WL_SKY,
+ RENDER_TYPE_GROUND,
+ RENDER_TYPE_TERRAIN,
+ RENDER_TYPE_GRASS,
+ RENDER_TYPE_CONTROL_AV, // Animesh
+ RENDER_TYPE_TREE,
+ RENDER_TYPE_VOIDWATER,
+ RENDER_TYPE_WATER,
+ RENDER_TYPE_PASS_GRASS,
+ RENDER_TYPE_HUD,
+ RENDER_TYPE_PARTICLES,
+ RENDER_TYPE_CLOUDS,
+ RENDER_TYPE_HUD_PARTICLES,
+ END_RENDER_TYPES
+ );
}
S32 occlusion = sUseOcclusion;
@@ -10968,7 +10885,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 +10913,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 +10969,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 +10985,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 +11046,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);
}
@@ -11167,11 +11078,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
static const F32 clip_plane = 0.99999f;
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.bind();
- }
-
+ gDebugProgram.bind();
if (visually_muted)
{ // Visually muted avatar
@@ -11185,7 +11092,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.diffuseColor4fv(LLColor4::pink.mV );
}
- {
gGL.begin(LLRender::QUADS);
gGL.vertex3f(-1, -1, clip_plane);
gGL.vertex3f(1, -1, clip_plane);
@@ -11193,12 +11099,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.vertex3f(-1, 1, clip_plane);
gGL.end();
gGL.flush();
- }
- if (LLGLSLShader::sNoFixedFunction)
- {
- gDebugProgram.unbind();
- }
+ gDebugProgram.unbind();
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -11227,7 +11129,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLVertexBuffer::unbind();
LLGLState::checkStates();
LLGLState::checkTextureChannels();
- LLGLState::checkClientArrays();
}
bool LLPipeline::hasRenderBatches(const U32 type) const
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 0eaa6b141d..fdc3738472 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
{
@@ -228,9 +225,7 @@ public:
S32 getLightingDetail() const { return mLightingDetail; }
S32 getMaxLightingDetail() const;
- void setUseVertexShaders(bool use_shaders);
- bool getUseVertexShaders() const { return mVertexShadersEnabled; }
- bool canUseVertexShaders();
+ bool shadersLoaded();
bool canUseWindLightShaders() const;
bool canUseWindLightShadersOnObjects() const;
bool canUseAntiAliasing() const;
@@ -245,7 +240,7 @@ public:
bool visibleObjectsInFrustum(LLCamera& camera);
bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
- void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
+ void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
void createObjects(F32 max_dtime);
void createObject(LLViewerObject* vobj);
void processPartitionQ();
@@ -265,13 +260,20 @@ 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 touchTexture(LLViewerTexture* tex, F32 vsize);
+
void forAllVisibleDrawables(void (*func)(LLDrawable*));
- void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
- void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
- void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false);
+ void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);
+ void renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);
void grabReferences(LLCullResult& result);
void clearReferences();
@@ -458,34 +460,61 @@ public:
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
+ RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS,
RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT,
+ RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT,
RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE,
+ RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED,
RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY,
+ RENDER_TYPE_PASS_INVISI_SHINY_RIGGED = LLRenderPass::PASS_INVISI_SHINY_RIGGED,
RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY,
+ RENDER_TYPE_PASS_FULLBRIGHT_SHINY_RIGGED = LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED,
RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
+ RENDER_TYPE_PASS_SHINY_RIGGED = LLRenderPass::PASS_SHINY_RIGGED,
RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
+ RENDER_TYPE_PASS_BUMP_RIGGED = LLRenderPass::PASS_BUMP_RIGGED,
RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP,
+ RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED,
RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
+ RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED,
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
+ RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED,
RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK,
+ RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK_RIGGED = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
RENDER_TYPE_PASS_MATERIAL = LLRenderPass::PASS_MATERIAL,
+ RENDER_TYPE_PASS_MATERIAL_RIGGED = LLRenderPass::PASS_MATERIAL_RIGGED,
RENDER_TYPE_PASS_MATERIAL_ALPHA = LLRenderPass::PASS_MATERIAL_ALPHA,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_RIGGED,
RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK = LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED,
RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE= LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED = LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED,
RENDER_TYPE_PASS_SPECMAP = LLRenderPass::PASS_SPECMAP,
+ RENDER_TYPE_PASS_SPECMAP_RIGGED = LLRenderPass::PASS_SPECMAP_RIGGED,
RENDER_TYPE_PASS_SPECMAP_BLEND = LLRenderPass::PASS_SPECMAP_BLEND,
+ RENDER_TYPE_PASS_SPECMAP_BLEND_RIGGED = LLRenderPass::PASS_SPECMAP_BLEND_RIGGED,
RENDER_TYPE_PASS_SPECMAP_MASK = LLRenderPass::PASS_SPECMAP_MASK,
+ RENDER_TYPE_PASS_SPECMAP_MASK_RIGGED = LLRenderPass::PASS_SPECMAP_MASK_RIGGED,
RENDER_TYPE_PASS_SPECMAP_EMISSIVE = LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ RENDER_TYPE_PASS_SPECMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED,
RENDER_TYPE_PASS_NORMMAP = LLRenderPass::PASS_NORMMAP,
+ RENDER_TYPE_PASS_NORMMAP_RIGGED = LLRenderPass::PASS_NORMMAP_RIGGED,
RENDER_TYPE_PASS_NORMMAP_BLEND = LLRenderPass::PASS_NORMMAP_BLEND,
+ RENDER_TYPE_PASS_NORMMAP_BLEND_RIGGED = LLRenderPass::PASS_NORMMAP_BLEND_RIGGED,
RENDER_TYPE_PASS_NORMMAP_MASK = LLRenderPass::PASS_NORMMAP_MASK,
+ RENDER_TYPE_PASS_NORMMAP_MASK_RIGGED = LLRenderPass::PASS_NORMMAP_MASK_RIGGED,
RENDER_TYPE_PASS_NORMMAP_EMISSIVE = LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ RENDER_TYPE_PASS_NORMMAP_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED,
RENDER_TYPE_PASS_NORMSPEC = LLRenderPass::PASS_NORMSPEC,
+ RENDER_TYPE_PASS_NORMSPEC_RIGGED = LLRenderPass::PASS_NORMSPEC_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_BLEND = LLRenderPass::PASS_NORMSPEC_BLEND,
+ RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED = LLRenderPass::PASS_NORMSPEC_BLEND_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_MASK = LLRenderPass::PASS_NORMSPEC_MASK,
+ RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -574,7 +603,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 +625,6 @@ public:
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
static S32 sVisibleLightCount;
- static F32 sMinRenderSize;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
@@ -676,8 +703,7 @@ public:
LLVector4 mTransformedMoonDir;
bool mInitialized;
- bool mVertexShadersEnabled;
- S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
+ bool mShadersLoaded;
U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
protected:
@@ -878,7 +904,6 @@ public:
//cached settings
static bool WindLightUseAtmosShaders;
- static bool RenderAvatarVP;
static bool RenderDeferred;
static F32 RenderDeferredSunWash;
static U32 RenderFSAASamples;
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index 7654f0dcd6..b322e67bb7 100644
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -60,7 +60,6 @@ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 20
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org).
GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 42e23b2089..b2708f7141 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -19,7 +19,6 @@ mit Open-Source-Beiträgen von:</text>
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm und Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW).
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..d1e167df64 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"
@@ -661,20 +661,6 @@
</text>
<check_box
- control_name="RenderAvatarVP"
- height="16"
- initial_value="true"
- label="Avatar Hardware skinning"
- layout="topleft"
- left="440"
- name="AvatarVertexProgram"
- top_delta="16"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderAvatarCloth"
height="16"
initial_value="true"
@@ -885,7 +871,7 @@
layout="topleft"
left="13"
name="horiz_border"
- top_pad="5"
+ top_pad="21"
top_delta="5"
width="774"/>
<button
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index f9d44b2c69..b9ca0108b6 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/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 8f143cf072..f59f534908 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -19,7 +19,6 @@ con contribuciones de código abierto de:</text>
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm y Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University y David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index 1e2a14ab3e..df6b61e293 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -19,7 +19,6 @@ avec les contributions Open Source de :</text>
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm et Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University, et David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index 9603238b66..edb334e13e 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -19,7 +19,6 @@ con contributi open source da:</text>
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm e Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index cf5e97bd8d..6a39d057e2 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -19,7 +19,6 @@ DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 20
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index 65c457f822..3c0ca332ac 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -19,7 +19,6 @@ com contribuições de código aberto de:</text>
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University e David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index ee9f82847d..44216e0430 100644
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -19,7 +19,6 @@
expat (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType (C) 1996-2002, 2006 David Turner, Robert Wilhelm и Werner Lemberg.
GL (C) 1999-2004 Brian Paul.
- GLOD (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Университет Джона Гопкинса и David Luebke, Brenden Schubert, Университет Вирджинии.
google-perftools (c) 2005, Google Inc.
Havok.com(TM) (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 (C) 2001, David Taubman, Университет Нового Южного Уэльса (UNSW)
diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index b91575954b..faa504a996 100644
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -19,7 +19,6 @@ açık kaynak kod katkısında bulunanlar şunlardır:</text>
expat Telif Hakkı (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Telif Hakkı (C) 1996-2002, 2006 David Turner, Robert Wilhelm ve Werner Lemberg.
GL Telif Hakkı (C) 1999-2004 Brian Paul.
- GLOD Telif Hakkı (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University ve David Luebke, Brenden Schubert, University of Virginia.
google-perftools Telif Hakkı (c) 2005, Google Inc.
Havok.com(TM) Telif Hakkı (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Telif Hakkı (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml
index 9f6b4421a9..d7d2a52750 100644
--- a/indra/newview/skins/default/xui/zh/floater_about.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about.xml
@@ -19,7 +19,6 @@
expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
GL Copyright (C) 1999-2004 Brian Paul.
- GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
google-perftools Copyright (c) 2005, Google Inc.
Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
diff --git a/indra/newview/slplugin.entitlements b/indra/newview/slplugin.entitlements
index a72c6bc82c..aea8dbfd15 100644
--- a/indra/newview/slplugin.entitlements
+++ b/indra/newview/slplugin.entitlements
@@ -12,5 +12,7 @@
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
+ <key>com.apple.security.device.audio-input</key>
+ <true/>
</dict>
</plist>
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;
}