summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-06-20 16:46:23 -0700
committerRichard Linden <none@none>2013-06-20 16:46:23 -0700
commita2a6bf20d71f923e9a5e43f71213fffbfea5a2a6 (patch)
tree7e2711d256f98872db24e1f9de4449d47e75ed88
parent2655c7a17ae38a073dcf8f05b0127b68edc34c95 (diff)
parente2e6963677657e4f5c417edc8d60e8b2a37ad204 (diff)
merge with release
-rwxr-xr-x.hgignore4
-rwxr-xr-xautobuild.xml24
-rwxr-xr-xindra/cmake/00-Common.cmake1
-rw-r--r--indra/llappearance/llavatarappearance.cpp2
-rw-r--r--indra/llappearance/llavatarjointmesh.cpp1
-rw-r--r--indra/llappearance/llavatarjointmesh.h1
-rw-r--r--indra/llappearance/llpolymorph.cpp5
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp9
-rw-r--r--indra/llappearance/lltexlayer.cpp2
-rw-r--r--indra/llappearance/lltexlayerparams.cpp1
-rw-r--r--indra/llappearance/llwearable.h2
-rwxr-xr-xindra/llaudio/llaudiodecodemgr.cpp1
-rwxr-xr-xindra/llcharacter/llcharacter.cpp1
-rwxr-xr-xindra/llcharacter/lleditingmotion.cpp2
-rwxr-xr-xindra/llcharacter/llheadrotmotion.cpp4
-rwxr-xr-xindra/llcharacter/lljoint.h1
-rwxr-xr-xindra/llcharacter/llkeyframemotion.cpp8
-rwxr-xr-xindra/llcharacter/llkeyframewalkmotion.cpp10
-rwxr-xr-xindra/llcharacter/llmotion.cpp4
-rwxr-xr-xindra/llcharacter/llmotioncontroller.cpp1
-rwxr-xr-xindra/llcharacter/llmotioncontroller.h1
-rwxr-xr-xindra/llcharacter/lltargetingmotion.cpp2
-rwxr-xr-xindra/llcommon/CMakeLists.txt46
-rwxr-xr-xindra/llcommon/doublelinkedlist.h1397
-rwxr-xr-xindra/llcommon/llapr.cpp21
-rwxr-xr-xindra/llcommon/llapr.h47
-rwxr-xr-xindra/llcommon/llassoclist.h296
-rwxr-xr-xindra/llcommon/llcommon.cpp7
-rwxr-xr-xindra/llcommon/llcriticaldamp.cpp77
-rwxr-xr-xindra/llcommon/llcriticaldamp.h32
-rwxr-xr-xindra/llcommon/lldate.cpp14
-rwxr-xr-xindra/llcommon/lldate.h5
-rwxr-xr-xindra/llcommon/lldefs.h3
-rw-r--r--[-rwxr-xr-x]indra/llcommon/lldeleteutils.h0
-rwxr-xr-xindra/llcommon/lldepthstack.h34
-rwxr-xr-xindra/llcommon/lldlinked.h93
-rwxr-xr-xindra/llcommon/lldqueueptr.h352
-rwxr-xr-xindra/llcommon/llenum.h78
-rwxr-xr-xindra/llcommon/llerrorlegacy.h9
-rwxr-xr-xindra/llcommon/llevents.cpp1
-rwxr-xr-xindra/llcommon/llfasttimer.cpp639
-rwxr-xr-xindra/llcommon/llfasttimer.h318
-rwxr-xr-xindra/llcommon/llfile.cpp26
-rwxr-xr-xindra/llcommon/llfindlocale.cpp2
-rwxr-xr-xindra/llcommon/llindexedqueue.h155
-rwxr-xr-xindra/llcommon/llinitparam.cpp36
-rwxr-xr-xindra/llcommon/llinitparam.h432
-rwxr-xr-xindra/llcommon/llinstancetracker.cpp26
-rwxr-xr-xindra/llcommon/llinstancetracker.h67
-rwxr-xr-xindra/llcommon/lllazy.cpp40
-rwxr-xr-xindra/llcommon/lllazy.h399
-rwxr-xr-xindra/llcommon/llleap.cpp2
-rwxr-xr-xindra/llcommon/lllocalidhashmap.h895
-rwxr-xr-xindra/llcommon/llmd5.cpp1
-rwxr-xr-xindra/llcommon/llmemory.cpp1
-rwxr-xr-xindra/llcommon/llmemory.h17
-rwxr-xr-xindra/llcommon/llmetricperformancetester.cpp7
-rwxr-xr-xindra/llcommon/llmortician.h1
-rw-r--r--indra/llcommon/llmutex.cpp179
-rw-r--r--indra/llcommon/llmutex.h101
-rwxr-xr-xindra/llcommon/llpointer.h72
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llpredicate.cpp (renamed from indra/llui/llfunctorregistry.cpp)28
-rw-r--r--indra/llcommon/llpredicate.h210
-rwxr-xr-xindra/llcommon/llprocess.h4
-rwxr-xr-xindra/llcommon/llprocessor.cpp6
-rwxr-xr-xindra/llcommon/llprocessor.h4
-rwxr-xr-xindra/llcommon/llptrskiplist.h724
-rwxr-xr-xindra/llcommon/llptrskipmap.h1239
-rwxr-xr-xindra/llcommon/llqueuedthread.cpp15
-rwxr-xr-xindra/llcommon/llregistry.h12
-rwxr-xr-xindra/llcommon/llsdparam.cpp12
-rwxr-xr-xindra/llcommon/llsdparam.h20
-rwxr-xr-xindra/llcommon/llsingleton.cpp1
-rwxr-xr-xindra/llcommon/llsingleton.h153
-rwxr-xr-xindra/llcommon/llskiplist.h517
-rwxr-xr-xindra/llcommon/llskipmap.h1022
-rwxr-xr-xindra/llcommon/llsortedvector.h152
-rwxr-xr-xindra/llcommon/llstack.h48
-rwxr-xr-xindra/llcommon/llstacktrace.cpp2
-rwxr-xr-xindra/llcommon/llstat.cpp404
-rwxr-xr-xindra/llcommon/llstat.h116
-rwxr-xr-xindra/llcommon/llstatenums.h2
-rwxr-xr-xindra/llcommon/llstl.h1
-rwxr-xr-xindra/llcommon/llstring.cpp5
-rwxr-xr-xindra/llcommon/llstring.h3
-rwxr-xr-xindra/llcommon/llsys.cpp5
-rwxr-xr-xindra/llcommon/llthread.cpp176
-rwxr-xr-xindra/llcommon/llthread.h91
-rw-r--r--indra/llcommon/llthreadlocalstorage.cpp117
-rw-r--r--indra/llcommon/llthreadlocalstorage.h357
-rwxr-xr-xindra/llcommon/lltimer.cpp20
-rwxr-xr-xindra/llcommon/lltimer.h21
-rw-r--r--indra/llcommon/lltrace.cpp116
-rw-r--r--indra/llcommon/lltrace.h1099
-rw-r--r--indra/llcommon/lltracerecording.cpp914
-rw-r--r--indra/llcommon/lltracerecording.h531
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp292
-rw-r--r--indra/llcommon/lltracethreadrecorder.h126
-rwxr-xr-xindra/llcommon/lltypeinfolookup.h117
-rw-r--r--indra/llcommon/llunit.h563
-rwxr-xr-xindra/llcommon/lluuid.cpp4
-rwxr-xr-xindra/llcommon/lluuidhashmap.h583
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llwin32headers.h (renamed from indra/llcommon/reflective.h)34
-rw-r--r--[-rwxr-xr-x]indra/llcommon/llwin32headerslean.h (renamed from indra/llcommon/lldarrayptr.h)24
-rwxr-xr-xindra/llcommon/llworkerthread.h5
-rwxr-xr-xindra/llcommon/metaclass.cpp81
-rwxr-xr-xindra/llcommon/metaclass.h82
-rwxr-xr-xindra/llcommon/metaclasst.h60
-rwxr-xr-xindra/llcommon/metaproperty.h73
-rwxr-xr-xindra/llcommon/metapropertyt.h183
-rwxr-xr-xindra/llcommon/reflectivet.h48
-rw-r--r--indra/llcommon/tests/llunits_test.cpp219
-rwxr-xr-xindra/llcommon/tests/reflection_test.cpp220
-rwxr-xr-xindra/llcorehttp/_refcounted.h4
-rwxr-xr-xindra/llimage/llimage.cpp8
-rwxr-xr-xindra/llimage/llimage.h7
-rwxr-xr-xindra/llimage/tests/llimageworker_test.cpp10
-rwxr-xr-xindra/llinventory/lleconomy.h1
-rwxr-xr-xindra/llinventory/llinventory.cpp1
-rwxr-xr-xindra/llinventory/llpermissions.cpp16
-rwxr-xr-xindra/llinventory/llpermissions.h6
-rwxr-xr-xindra/llkdu/tests/llimagej2ckdu_test.cpp4
-rwxr-xr-xindra/llmath/llcamera.cpp50
-rwxr-xr-xindra/llmath/llcamera.h8
-rwxr-xr-xindra/llmath/llvolume.cpp44
-rwxr-xr-xindra/llmath/v4color.h4
-rwxr-xr-xindra/llmessage/llassetstorage.cpp27
-rwxr-xr-xindra/llmessage/llbuffer.cpp1
-rwxr-xr-xindra/llmessage/lldatapacker.h1
-rwxr-xr-xindra/llmessage/lldispatcher.cpp1
-rwxr-xr-xindra/llmessage/llfiltersd2xmlrpc.cpp1
-rwxr-xr-xindra/llmessage/lliohttpserver.cpp1
-rwxr-xr-xindra/llmessage/lliopipe.h1
-rwxr-xr-xindra/llmessage/lliosocket.cpp1
-rwxr-xr-xindra/llmessage/lliosocket.h1
-rwxr-xr-xindra/llmessage/llioutil.cpp1
-rwxr-xr-xindra/llmessage/llmail.cpp7
-rwxr-xr-xindra/llmessage/llproxy.cpp10
-rwxr-xr-xindra/llmessage/llpumpio.cpp1
-rwxr-xr-xindra/llmessage/llsdrpcclient.cpp1
-rwxr-xr-xindra/llmessage/llsdrpcserver.cpp1
-rwxr-xr-xindra/llmessage/llurlrequest.cpp15
-rwxr-xr-xindra/llmessage/message.h35
-rwxr-xr-xindra/llmessage/net.cpp6
-rwxr-xr-xindra/llplugin/llpluginprocesschild.h1
-rwxr-xr-xindra/llplugin/llpluginprocessparent.h2
-rwxr-xr-xindra/llplugin/tests/llplugincookiestore_test.cpp1
-rwxr-xr-xindra/llprimitive/CMakeLists.txt2
-rwxr-xr-xindra/llprimitive/llvolumexml.cpp78
-rwxr-xr-xindra/llrender/llfontgl.cpp1
-rwxr-xr-xindra/llrender/llfontregistry.cpp24
-rwxr-xr-xindra/llrender/llfontregistry.h5
-rwxr-xr-xindra/llrender/llglheaders.h4
-rw-r--r--indra/llrender/llimagegl.cpp53
-rwxr-xr-xindra/llrender/llimagegl.h7
-rwxr-xr-xindra/llrender/llrender.cpp5
-rw-r--r--indra/llrender/llrender2dutils.cpp79
-rw-r--r--indra/llrender/llrender2dutils.h5
-rwxr-xr-xindra/llrender/lltexture.h2
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp8
-rwxr-xr-xindra/llui/CMakeLists.txt1
-rwxr-xr-xindra/llui/llaccordionctrltab.cpp4
-rwxr-xr-xindra/llui/llaccordionctrltab.h2
-rwxr-xr-xindra/llui/llbutton.cpp4
-rwxr-xr-xindra/llui/llcontainerview.cpp8
-rwxr-xr-xindra/llui/llcontainerview.h4
-rwxr-xr-xindra/llui/llfloater.cpp25
-rwxr-xr-xindra/llui/llfloater.h2
-rwxr-xr-xindra/llui/llfloaterreg.h1
-rw-r--r--[-rwxr-xr-x]indra/llui/llfolderviewitem.cpp16
-rwxr-xr-xindra/llui/lllayoutstack.cpp14
-rwxr-xr-xindra/llui/lllayoutstack.h19
-rwxr-xr-xindra/llui/llmenugl.cpp12
-rwxr-xr-xindra/llui/llmenugl.h4
-rwxr-xr-xindra/llui/llmultifloater.h3
-rwxr-xr-xindra/llui/llnotifications.cpp6
-rwxr-xr-xindra/llui/llnotifications.h3
-rwxr-xr-xindra/llui/llnotificationtemplate.h23
-rwxr-xr-xindra/llui/llpanel.cpp8
-rwxr-xr-xindra/llui/llpanel.h2
-rwxr-xr-xindra/llui/llscrollbar.cpp4
-rwxr-xr-xindra/llui/llscrollbar.h8
-rwxr-xr-xindra/llui/llscrollcontainer.cpp4
-rwxr-xr-xindra/llui/llscrollcontainer.h3
-rwxr-xr-xindra/llui/llslider.h4
-rwxr-xr-xindra/llui/llstatbar.cpp390
-rwxr-xr-xindra/llui/llstatbar.h98
-rwxr-xr-xindra/llui/llstatgraph.cpp88
-rwxr-xr-xindra/llui/llstatgraph.h99
-rwxr-xr-xindra/llui/lltabcontainer.cpp2
-rwxr-xr-xindra/llui/lltextbase.cpp23
-rwxr-xr-xindra/llui/lltextbase.h19
-rwxr-xr-xindra/llui/lltoggleablemenu.cpp2
-rwxr-xr-xindra/llui/lltoggleablemenu.h2
-rwxr-xr-xindra/llui/lltoolbar.cpp10
-rwxr-xr-xindra/llui/lltoolbar.h2
-rwxr-xr-xindra/llui/llui.h6
-rwxr-xr-xindra/llui/lluictrl.cpp21
-rwxr-xr-xindra/llui/lluictrlfactory.h6
-rwxr-xr-xindra/llui/lluistring.cpp2
-rwxr-xr-xindra/llui/llview.cpp18
-rwxr-xr-xindra/llui/llview.h19
-rwxr-xr-xindra/llui/llviewmodel.cpp7
-rwxr-xr-xindra/llui/llviewmodel.h7
-rwxr-xr-xindra/llui/llxuiparser.cpp8
-rwxr-xr-xindra/llui/llxuiparser.h30
-rwxr-xr-xindra/llvfs/llpidlock.cpp2
-rwxr-xr-xindra/llvfs/llvfile.cpp7
-rwxr-xr-xindra/llwindow/lldragdropwin32.h4
-rwxr-xr-xindra/llwindow/llkeyboard.h1
-rwxr-xr-xindra/llwindow/llkeyboardwin32.cpp5
-rwxr-xr-xindra/llwindow/llwindow.h1
-rwxr-xr-xindra/llwindow/llwindowwin32.cpp1
-rwxr-xr-xindra/llwindow/llwindowwin32.h4
-rwxr-xr-xindra/lscript/lscript_execute/lscript_execute.cpp1
-rwxr-xr-xindra/media_plugins/quicktime/media_plugin_quicktime.cpp21
-rwxr-xr-xindra/media_plugins/webkit/mac_volume_catcher.cpp1
-rwxr-xr-xindra/newview/CMakeLists.txt12
-rwxr-xr-xindra/newview/app_settings/settings.xml102
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl49
-rw-r--r--[-rwxr-xr-x]indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl (renamed from indra/llcommon/reflective.cpp)26
-rw-r--r--[-rwxr-xr-x]indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl (renamed from indra/llcommon/metaproperty.cpp)52
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl41
-rwxr-xr-xindra/newview/gpu_table.txt516
-rwxr-xr-xindra/newview/llagent.cpp60
-rwxr-xr-xindra/newview/llagent.h2
-rwxr-xr-xindra/newview/llagentcamera.cpp51
-rwxr-xr-xindra/newview/llagentwearables.cpp77
-rwxr-xr-xindra/newview/llappearancemgr.h1
-rwxr-xr-xindra/newview/llappviewer.cpp246
-rwxr-xr-xindra/newview/llappviewer.h5
-rwxr-xr-xindra/newview/llappviewerwin32.cpp5
-rwxr-xr-xindra/newview/llcallingcard.cpp20
-rwxr-xr-xindra/newview/llchatbar.cpp18
-rwxr-xr-xindra/newview/llcompilequeue.cpp2
-rwxr-xr-xindra/newview/lldebugview.cpp10
-rwxr-xr-xindra/newview/lldirpicker.cpp2
-rwxr-xr-xindra/newview/lldirpicker.h5
-rwxr-xr-xindra/newview/lldrawable.cpp340
-rwxr-xr-xindra/newview/lldrawable.h65
-rwxr-xr-xindra/newview/lldrawpoolalpha.cpp22
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp24
-rwxr-xr-xindra/newview/lldrawpoolwater.cpp2
-rwxr-xr-xindra/newview/llface.cpp118
-rwxr-xr-xindra/newview/llface.h4
-rwxr-xr-xindra/newview/llfasttimerview.cpp1652
-rwxr-xr-xindra/newview/llfasttimerview.h112
-rwxr-xr-xindra/newview/llfilepicker.h1
-rwxr-xr-xindra/newview/llfloaterabout.cpp3
-rwxr-xr-xindra/newview/llfloateravatarpicker.cpp4
-rwxr-xr-xindra/newview/llfloateravatartextures.cpp1
-rwxr-xr-xindra/newview/llfloaterbuyland.cpp4
-rwxr-xr-xindra/newview/llfloatercolorpicker.cpp4
-rwxr-xr-xindra/newview/llfloaterimnearbychat.cpp4
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloaterimsession.cpp4
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloaterimsession.h10
-rwxr-xr-xindra/newview/llfloaterjoystick.cpp27
-rwxr-xr-xindra/newview/llfloaterjoystick.h1
-rwxr-xr-xindra/newview/llfloaterlagmeter.cpp375
-rwxr-xr-xindra/newview/llfloaterlagmeter.h80
-rwxr-xr-xindra/newview/llfloaterland.cpp4
-rwxr-xr-xindra/newview/llfloaterland.h2
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp2
-rwxr-xr-xindra/newview/llfloaterregioninfo.cpp4
-rwxr-xr-xindra/newview/llfloaterregioninfo.h2
-rw-r--r--indra/newview/llfloatersceneloadstats.cpp40
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloatersceneloadstats.h (renamed from indra/llprimitive/llvolumexml.h)28
-rwxr-xr-xindra/newview/llfloatersnapshot.cpp6
-rwxr-xr-xindra/newview/llfollowcam.cpp10
-rwxr-xr-xindra/newview/llgesturemgr.cpp2
-rwxr-xr-xindra/newview/llgroupmgr.cpp2
-rwxr-xr-xindra/newview/llhudicon.h3
-rwxr-xr-xindra/newview/llhudmanager.h8
-rwxr-xr-xindra/newview/llhudnametag.cpp7
-rwxr-xr-xindra/newview/llimview.cpp5
-rwxr-xr-xindra/newview/llimview.h5
-rwxr-xr-xindra/newview/llinventorybridge.cpp1
-rwxr-xr-xindra/newview/llinventoryicon.cpp3
-rwxr-xr-xindra/newview/llinventoryicon.h5
-rwxr-xr-xindra/newview/llinventorymodel.h4
-rwxr-xr-xindra/newview/llinventorypanel.cpp3
-rwxr-xr-xindra/newview/lllandmarklist.cpp1
-rwxr-xr-xindra/newview/lllocalbitmaps.cpp5
-rwxr-xr-xindra/newview/lllocalbitmaps.h2
-rwxr-xr-xindra/newview/llmaniprotate.cpp18
-rwxr-xr-xindra/newview/llmanipscale.cpp4
-rwxr-xr-xindra/newview/llmaniptranslate.cpp12
-rwxr-xr-xindra/newview/llmediactrl.cpp6
-rwxr-xr-xindra/newview/llmediactrl.h4
-rwxr-xr-xindra/newview/llmeshrepository.cpp3
-rwxr-xr-xindra/newview/llnetmap.cpp2
-rwxr-xr-xindra/newview/llpanelclassified.cpp1
-rwxr-xr-xindra/newview/llpaneleditwearable.cpp1
-rwxr-xr-xindra/newview/llpanelface.cpp148
-rwxr-xr-xindra/newview/llpanelface.h2
-rwxr-xr-xindra/newview/llpanelnearbymedia.cpp2
-rwxr-xr-xindra/newview/llpanelnearbymedia.h2
-rwxr-xr-xindra/newview/llpaneloutfitedit.cpp6
-rwxr-xr-xindra/newview/llpaneloutfitedit.h2
-rwxr-xr-xindra/newview/llpanelpeople.h1
-rwxr-xr-xindra/newview/llpanelpermissions.cpp1
-rwxr-xr-xindra/newview/llpanelplaceprofile.cpp4
-rwxr-xr-xindra/newview/llpanelplaceprofile.h4
-rwxr-xr-xindra/newview/llpanelplaces.cpp4
-rwxr-xr-xindra/newview/llpanelplaces.h2
-rwxr-xr-xindra/newview/llpanelprofile.cpp1
-rwxr-xr-xindra/newview/llpaneltopinfobar.cpp4
-rwxr-xr-xindra/newview/llpaneltopinfobar.h2
-rwxr-xr-xindra/newview/llpanelvoicedevicesettings.cpp2
-rwxr-xr-xindra/newview/llpanelvoicedevicesettings.h2
-rwxr-xr-xindra/newview/llpanelvoiceeffect.cpp1
-rwxr-xr-xindra/newview/llpanelvolumepulldown.cpp2
-rwxr-xr-xindra/newview/llpanelvolumepulldown.h2
-rwxr-xr-xindra/newview/llpreviewgesture.cpp6
-rwxr-xr-xindra/newview/llpreviewgesture.h2
-rwxr-xr-xindra/newview/llpreviewnotecard.cpp2
-rwxr-xr-xindra/newview/llpreviewscript.cpp9
-rw-r--r--indra/newview/llscenemonitor.cpp702
-rw-r--r--indra/newview/llscenemonitor.h124
-rwxr-xr-xindra/newview/llsecapi.h1
-rwxr-xr-xindra/newview/llselectmgr.cpp10
-rwxr-xr-xindra/newview/llsidepanelappearance.cpp6
-rwxr-xr-xindra/newview/llsidepanelappearance.h4
-rwxr-xr-xindra/newview/llsidepaneltaskinfo.cpp3
-rwxr-xr-xindra/newview/llsidepaneltaskinfo.h2
-rwxr-xr-xindra/newview/llsimplestat.h58
-rwxr-xr-xindra/newview/llspatialpartition.cpp1403
-rwxr-xr-xindra/newview/llspatialpartition.h170
-rwxr-xr-xindra/newview/llspeakers.cpp2
-rwxr-xr-xindra/newview/llstartup.cpp13
-rwxr-xr-xindra/newview/llstatusbar.cpp34
-rwxr-xr-xindra/newview/llsurface.h1
-rwxr-xr-xindra/newview/lltexturecache.cpp8
-rwxr-xr-xindra/newview/lltexturecache.h2
-rwxr-xr-xindra/newview/lltexturectrl.cpp6
-rwxr-xr-xindra/newview/lltexturefetch.cpp76
-rwxr-xr-xindra/newview/lltexturefetch.h10
-rwxr-xr-xindra/newview/lltextureview.cpp43
-rwxr-xr-xindra/newview/lltoastalertpanel.cpp1
-rwxr-xr-xindra/newview/lltoolbarview.cpp2
-rwxr-xr-xindra/newview/lltooldraganddrop.cpp6
-rwxr-xr-xindra/newview/lltoolpie.cpp1
-rwxr-xr-xindra/newview/lltoolplacer.cpp2
-rwxr-xr-xindra/newview/lltoolselect.cpp1
-rwxr-xr-xindra/newview/lltoolselect.h2
-rwxr-xr-xindra/newview/llviewerassetstats.cpp809
-rwxr-xr-xindra/newview/llviewerassetstats.h235
-rwxr-xr-xindra/newview/llviewerassetstorage.cpp8
-rwxr-xr-xindra/newview/llvieweraudio.cpp27
-rwxr-xr-xindra/newview/llviewercamera.cpp14
-rwxr-xr-xindra/newview/llviewercamera.h18
-rwxr-xr-xindra/newview/llviewerdisplay.cpp43
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp30
-rwxr-xr-xindra/newview/llviewerjoystick.cpp6
-rwxr-xr-xindra/newview/llviewerkeyboard.cpp5
-rwxr-xr-xindra/newview/llviewermenu.cpp2
-rwxr-xr-xindra/newview/llviewermenufile.cpp15
-rwxr-xr-xindra/newview/llviewermenufile.h2
-rwxr-xr-xindra/newview/llviewermessage.cpp216
-rwxr-xr-xindra/newview/llviewerobject.cpp259
-rwxr-xr-xindra/newview/llviewerobject.h50
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp306
-rwxr-xr-xindra/newview/llviewerobjectlist.h23
-rw-r--r--indra/newview/llvieweroctree.cpp1459
-rw-r--r--indra/newview/llvieweroctree.h422
-rwxr-xr-xindra/newview/llviewerpartsim.cpp18
-rwxr-xr-xindra/newview/llviewerpartsim.h4
-rwxr-xr-xindra/newview/llviewerprecompiledheaders.h8
-rwxr-xr-xindra/newview/llviewerregion.cpp975
-rwxr-xr-xindra/newview/llviewerregion.h75
-rwxr-xr-xindra/newview/llviewershadermgr.cpp44
-rwxr-xr-xindra/newview/llviewershadermgr.h4
-rwxr-xr-xindra/newview/llviewerstats.cpp544
-rwxr-xr-xindra/newview/llviewerstats.h338
-rwxr-xr-xindra/newview/llviewerstatsrecorder.cpp2
-rwxr-xr-xindra/newview/llviewertexlayer.cpp2
-rwxr-xr-xindra/newview/llviewertexture.cpp150
-rwxr-xr-xindra/newview/llviewertexture.h28
-rwxr-xr-xindra/newview/llviewertexturelist.cpp79
-rwxr-xr-xindra/newview/llviewertexturelist.h15
-rwxr-xr-xindra/newview/llviewerthrottle.cpp5
-rw-r--r--indra/newview/llviewerwearable.cpp1
-rwxr-xr-xindra/newview/llviewerwindow.cpp61
-rwxr-xr-xindra/newview/llviewerwindow.h7
-rwxr-xr-xindra/newview/llvoavatar.cpp247
-rwxr-xr-xindra/newview/llvoavatar.h13
-rwxr-xr-xindra/newview/llvoavatarself.cpp88
-rwxr-xr-xindra/newview/llvocache.cpp383
-rwxr-xr-xindra/newview/llvocache.h125
-rwxr-xr-xindra/newview/llvograss.cpp14
-rwxr-xr-xindra/newview/llvoicechannel.cpp2
-rwxr-xr-xindra/newview/llvoiceclient.h1
-rwxr-xr-xindra/newview/llvoinventorylistener.h4
-rwxr-xr-xindra/newview/llvopartgroup.cpp20
-rwxr-xr-xindra/newview/llvosky.cpp2
-rwxr-xr-xindra/newview/llvosurfacepatch.cpp4
-rwxr-xr-xindra/newview/llvosurfacepatch.h2
-rwxr-xr-xindra/newview/llvotree.cpp4
-rwxr-xr-xindra/newview/llvovolume.cpp162
-rwxr-xr-xindra/newview/llvowater.cpp6
-rwxr-xr-xindra/newview/llvowlsky.cpp2
-rwxr-xr-xindra/newview/llwatchdog.cpp1
-rwxr-xr-xindra/newview/llwearablelist.cpp1
-rwxr-xr-xindra/newview/llwindebug.h1
-rwxr-xr-xindra/newview/llworld.cpp59
-rwxr-xr-xindra/newview/llworld.h3
-rwxr-xr-xindra/newview/llworldmapmessage.h2
-rwxr-xr-xindra/newview/llworldmapview.cpp4
-rwxr-xr-xindra/newview/llxmlrpctransaction.cpp2
-rwxr-xr-xindra/newview/pipeline.cpp187
-rwxr-xr-xindra/newview/pipeline.h27
-rwxr-xr-xindra/newview/skins/default/xui/da/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/de/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_fast_timers.xml69
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_lagmeter.xml336
-rw-r--r--indra/newview/skins/default/xui/en/floater_scene_load_stats.xml446
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_stats.xml137
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml28
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml6
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml2
-rwxr-xr-xindra/newview/skins/default/xui/es/floater_lagmeter.xml154
-rwxr-xr-xindra/newview/skins/default/xui/fr/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/it/floater_lagmeter.xml154
-rwxr-xr-xindra/newview/skins/default/xui/ja/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/pt/floater_lagmeter.xml154
-rwxr-xr-xindra/newview/skins/default/xui/ru/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/tr/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/skins/default/xui/zh/floater_lagmeter.xml151
-rwxr-xr-xindra/newview/tests/llviewerassetstats_test.cpp688
-rwxr-xr-xindra/test/CMakeLists.txt1
-rwxr-xr-xindra/test/io.cpp5
-rwxr-xr-xindra/test/llhttpdate_tut.cpp7
-rwxr-xr-xindra/test/lliohttpserver_tut.cpp5
-rwxr-xr-xindra/test/lluuidhashmap_tut.cpp455
-rwxr-xr-xindra/test/test.cpp17
-rwxr-xr-xindra/test_apps/llplugintest/llmediaplugintest.cpp10
437 files changed, 16734 insertions, 20612 deletions
diff --git a/.hgignore b/.hgignore
index c845758e7c..7dca2f0778 100755
--- a/.hgignore
+++ b/.hgignore
@@ -74,4 +74,6 @@ glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt
glob:indra/newview/avatar_lad.log
glob:*.diff
-#*.rej
+indra/newview/pilot.txt
+indra/newview/pilot.xml
+*.rej
diff --git a/autobuild.xml b/autobuild.xml
index 628d3f6883..5740d6b26c 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -498,9 +498,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>10352aab979c333a52dbad21b6e6fba9</string>
+ <string>10352aab979c333a52dbad21b6e6fba9</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -510,7 +510,7 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>79e45527aa9fb90b813599dff5ce01a7</string>
+ <string>79e45527aa9fb90b813599dff5ce01a7</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274378/arch/Linux/installer/fmodex-4.44-linux-20130419.tar.bz2</string>
</map>
@@ -762,9 +762,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>aff5566e04003de0383941981198e04e</string>
+ <string>aff5566e04003de0383941981198e04e</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/Darwin/installer/google_breakpad-0.0.0-rev1099-darwin-20130329.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/Darwin/installer/google_breakpad-0.0.0-rev1099-darwin-20130329.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -776,7 +776,7 @@
<key>hash</key>
<string>52257e5eb166a0b69c9c0c38f6e1920e</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273079/arch/Linux/installer/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273079/arch/Linux/installer/google_breakpad-0.0.0-rev1099-linux-20130329.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -788,7 +788,7 @@
<key>hash</key>
<string>d812a6dfcabe6528198a3191068dac09</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130329.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130329.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1326,9 +1326,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>5bc44db15eb3cca021382e40e04a9a38</string>
+ <string>9e5461d203b8259d3b6eb7df8c18b8fa</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/271972/arch/Linux/installer/llappearanceutility_source-0.1-linux-20130315.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-interesting-source/rev/277616/arch/Linux/installer/llappearanceutility_source-0.1-linux-20130620.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -2567,7 +2567,7 @@
<string>"Visual Studio 10"</string>
<string>-DUNATTENDED:BOOL=ON</string>
<string>-DUSE_KDU=FALSE</string>
- </array>
+ </array>
</map>
<key>name</key>
<string>DebugOS</string>
@@ -2655,7 +2655,7 @@
<string>-DUNATTENDED:BOOL=ON</string>
<string>-DINSTALL_PROPRIETARY=FALSE</string>
<string>-DUSE_KDU=FALSE</string>
- </array>
+ </array>
</map>
<key>name</key>
<string>RelWithDebInfoOS</string>
@@ -2742,7 +2742,7 @@
<string>-DUNATTENDED:BOOL=ON</string>
<string>-DINSTALL_PROPRIETARY=FALSE</string>
<string>-DUSE_KDU=FALSE</string>
- </array>
+ </array>
</map>
<key>name</key>
<string>ReleaseOS</string>
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 472f271fa8..ac9e717c82 100755
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -61,6 +61,7 @@ if (WINDOWS)
add_definitions(
/DLL_WINDOWS=1
+ /DNOMINMAX
/DDOM_DYNAMIC
/DUNICODE
/D_UNICODE
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 3bb759d458..35d1a8b247 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -36,8 +36,8 @@
#include "llavatarappearancedefines.h"
#include "llavatarjointmesh.h"
#include "imageids.h"
-#include "lldir.h"
#include "lldeleteutils.h"
+#include "lldir.h"
#include "llpolymorph.h"
#include "llpolymesh.h"
#include "llpolyskeletaldistortion.h"
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
index 4a5cff1dc3..753805b314 100644
--- a/indra/llappearance/llavatarjointmesh.cpp
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -117,7 +117,6 @@ BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
//-----------------------------------------------------------------------------
BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
-EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
LLColor4 LLAvatarJointMesh::sClothingInnerColor;
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
index 6486932cdf..5980b29b46 100644
--- a/indra/llappearance/llavatarjointmesh.h
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -82,7 +82,6 @@ public:
static BOOL sPipelineRender;
//RN: this is here for testing purposes
static U32 sClothingMaskImageName;
- static EAvatarRenderPass sRenderPass;
static LLColor4 sClothingInnerColor;
public:
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 93c2f15a53..6bda38bd97 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -35,6 +35,7 @@
#include "llxmltree.h"
#include "llendianswizzle.h"
#include "llpolymesh.h"
+#include "llfasttimer.h"
//#include "../tools/imdebug/imdebug.h"
@@ -619,9 +620,9 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
tangent.setCross3(scaled_binormals[vert_index_mesh], norm);
LLVector4a& normalized_binormal = binormals[vert_index_mesh];
- normalized_binormal.setCross3(norm, tangent);
+ normalized_binormal.setCross3(norm, tangent);
normalized_binormal.normalize3fast();
-
+
tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
}
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
index 4ba16691c2..a98a11b357 100644
--- a/indra/llappearance/llpolyskeletaldistortion.cpp
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -29,18 +29,11 @@
//-----------------------------------------------------------------------------
#include "llpreprocessor.h"
#include "llerrorlegacy.h"
-//#include "llcommon.h"
-//#include "llmemory.h"
#include "llavatarappearance.h"
#include "llavatarjoint.h"
#include "llpolymorph.h"
-//#include "llviewercontrol.h"
-//#include "llxmltree.h"
-//#include "llvoavatar.h"
#include "llwearable.h"
-//#include "lldir.h"
-//#include "llvolume.h"
-//#include "llendianswizzle.h"
+#include "llfasttimer.h"
#include "llpolyskeletaldistortion.h"
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index f951a982e5..f65829febe 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -38,11 +38,13 @@
#include "llvfs.h"
#include "lltexlayerparams.h"
#include "lltexturemanagerbridge.h"
+#include "lllocaltextureobject.h"
#include "../llui/llui.h"
#include "llwearable.h"
#include "llwearabledata.h"
#include "llvertexbuffer.h"
#include "llviewervisualparam.h"
+#include "llfasttimer.h"
//#include "../tools/imdebug/imdebug.h"
diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
index 6aae9a8cc1..674e8c3c06 100644
--- a/indra/llappearance/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -35,6 +35,7 @@
#include "lltexturemanagerbridge.h"
#include "../llui/llui.h"
#include "llwearable.h"
+#include "llfasttimer.h"
//-----------------------------------------------------------------------------
// LLTexLayerParam
diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h
index 6f5a1e14e8..6e4d2b2242 100644
--- a/indra/llappearance/llwearable.h
+++ b/indra/llappearance/llwearable.h
@@ -32,12 +32,12 @@
#include "llpermissions.h"
#include "llsaleinfo.h"
#include "llwearabletype.h"
-#include "lllocaltextureobject.h"
class LLMD5;
class LLVisualParam;
class LLTexGlobalColorInfo;
class LLTexGlobalColor;
+class LLLocalTextureObject;
class LLAvatarAppearance;
// Abstract class.
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 6c97a64ed7..bcff03ceaa 100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -40,6 +40,7 @@
#include "vorbis/codec.h"
#include "vorbis/vorbisfile.h"
+#include <iterator>
extern LLAudioEngine *gAudiop;
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 85cf1cd3f5..045b4abf50 100755
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -32,6 +32,7 @@
#include "llcharacter.h"
#include "llstring.h"
+#include "llfasttimer.h"
#define SKEL_HEADER "Linden Skeleton 1.0"
diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp
index 0d0b85ba60..ff7ad1c289 100755
--- a/indra/llcharacter/lleditingmotion.cpp
+++ b/indra/llcharacter/lleditingmotion.cpp
@@ -232,7 +232,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
mIKSolver.solve();
// use blending...
- F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE);
+ F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE);
shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);
elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot);
diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp
index 15a58a8389..4a8af2f00c 100755
--- a/indra/llcharacter/llheadrotmotion.cpp
+++ b/indra/llcharacter/llheadrotmotion.cpp
@@ -182,8 +182,8 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation();
LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld;
- F32 head_slerp_amt = LLCriticalDamp::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE);
- F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE);
+ F32 head_slerp_amt = LLSmoothInterpolation::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE);
+ F32 torso_slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE);
LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 2b1e2005c6..07374b7814 100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -31,6 +31,7 @@
// Header Files
//-----------------------------------------------------------------------------
#include <string>
+#include <list>
#include "linked_lists.h"
#include "v3math.h"
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index c6f45bffa2..831a0a6719 100755
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1031,11 +1031,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
if (constraint->mSharedData->mChainLength != 0 &&
dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)
{
- constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f));
+ constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 0.f, 0.1f);
}
else
{
- constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f));
+ constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 1.f, 0.3f);
}
F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f :
@@ -1082,9 +1082,9 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
// convert intermediate joint positions to world coordinates
positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition();
F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f);
-// llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
+// llinfos << "Interpolant " << LLSmoothInterpolation::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;
positions[joint_num] = lerp(positions[joint_num], kinematic_position,
- LLCriticalDamp::getInterpolant(time_constant, FALSE));
+ LLSmoothInterpolation::getInterpolant(time_constant, FALSE));
}
S32 iteration_count;
diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp
index d52eb89a5c..c6ca0b542e 100755
--- a/indra/llcharacter/llkeyframewalkmotion.cpp
+++ b/indra/llcharacter/llkeyframewalkmotion.cpp
@@ -258,7 +258,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)
// but this will cause the animation playback rate calculation below to
// kick in too slowly and sometimes start playing the animation in reverse.
- //mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLCriticalDamp::getInterpolant(0.1f));
+ //mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLSmoothInterpolation::getInterpolant(0.1f));
////F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL * (llclamp(speed, 0.f, DRIFT_COMP_MAX_SPEED) / DRIFT_COMP_MAX_SPEED);
//F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL;
@@ -287,7 +287,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)
F32 desired_speed_multiplier = llclamp(speed / foot_speed, min_speed_multiplier, ANIM_SPEED_MAX);
// blend towards new speed adjustment value
- F32 new_speed_adjust = lerp(mAdjustedSpeed, desired_speed_multiplier, LLCriticalDamp::getInterpolant(SPEED_ADJUST_TIME_CONSTANT));
+ F32 new_speed_adjust = LLSmoothInterpolation::lerp(mAdjustedSpeed, desired_speed_multiplier, SPEED_ADJUST_TIME_CONSTANT);
// limit that rate at which the speed adjustment changes
F32 speedDelta = llclamp(new_speed_adjust - mAdjustedSpeed, -SPEED_ADJUST_MAX_SEC * delta_time, SPEED_ADJUST_MAX_SEC * delta_time);
@@ -305,8 +305,8 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)
{ // standing/turning
// damp out speed adjustment to 0
- mAnimSpeed = lerp(mAnimSpeed, 1.f, LLCriticalDamp::getInterpolant(0.2f));
- //mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLCriticalDamp::getInterpolant(0.2f));
+ mAnimSpeed = LLSmoothInterpolation::lerp(mAnimSpeed, 1.f, 0.2f);
+ //mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.2f));
}
// broadcast walk speed change
@@ -383,7 +383,7 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)
F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor;
// roll is critically damped interpolation between current roll and angular velocity-derived target roll
- mRoll = lerp(mRoll, target_roll, LLCriticalDamp::getInterpolant(0.1f));
+ mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, LLUnit<F32, LLUnits::Milliseconds>(100));
LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f));
mPelvisState->setRotation(roll);
diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp
index 2551f125d0..af2e10220a 100755
--- a/indra/llcharacter/llmotion.cpp
+++ b/indra/llcharacter/llmotion.cpp
@@ -73,7 +73,7 @@ void LLMotion::fadeOut()
{
if (mFadeWeight > 0.01f)
{
- mFadeWeight = lerp(mFadeWeight, 0.f, LLCriticalDamp::getInterpolant(0.15f));
+ mFadeWeight = lerp(mFadeWeight, 0.f, LLSmoothInterpolation::getInterpolant(0.15f));
}
else
{
@@ -88,7 +88,7 @@ void LLMotion::fadeIn()
{
if (mFadeWeight < 0.99f)
{
- mFadeWeight = lerp(mFadeWeight, 1.f, LLCriticalDamp::getInterpolant(0.15f));
+ mFadeWeight = lerp(mFadeWeight, 1.f, LLSmoothInterpolation::getInterpolant(0.15f));
}
else
{
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index e9fb91ad73..d1c605451a 100755
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -30,6 +30,7 @@
#include "linden_common.h"
#include "llmotioncontroller.h"
+#include "llfasttimer.h"
#include "llkeyframemotion.h"
#include "llmath.h"
#include "lltimer.h"
diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index 52eaf557b1..2bd5271c4f 100755
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/indra/llcharacter/llmotioncontroller.h
@@ -34,7 +34,6 @@
#include <map>
#include <deque>
-#include "lluuidhashmap.h"
#include "llmotion.h"
#include "llpose.h"
#include "llframetimer.h"
diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp
index 489aef923c..633c1d51eb 100755
--- a/indra/llcharacter/lltargetingmotion.cpp
+++ b/indra/llcharacter/lltargetingmotion.cpp
@@ -106,7 +106,7 @@ BOOL LLTargetingMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)
{
- F32 slerp_amt = LLCriticalDamp::getInterpolant(TORSO_TARGET_HALF_LIFE);
+ F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE);
LLVector3 target;
LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 3a4a8facc2..bf99a4c3a0 100755
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -75,8 +75,10 @@ set(llcommon_SOURCE_FILES
llmetrics.cpp
llmetricperformancetester.cpp
llmortician.cpp
+ llmutex.cpp
lloptioninterface.cpp
llptrto.cpp
+ llpredicate.cpp
llprocess.cpp
llprocessor.cpp
llqueuedthread.cpp
@@ -90,7 +92,6 @@ set(llcommon_SOURCE_FILES
llsdutil.cpp
llsecondlifeurls.cpp
llsingleton.cpp
- llstat.cpp
llstacktrace.cpp
llstreamqueue.cpp
llstreamtools.cpp
@@ -98,14 +99,15 @@ set(llcommon_SOURCE_FILES
llstringtable.cpp
llsys.cpp
llthread.cpp
+ llthreadlocalstorage.cpp
llthreadsafequeue.cpp
lltimer.cpp
+ lltrace.cpp
+ lltracerecording.cpp
+ lltracethreadrecorder.cpp
lluri.cpp
lluuid.cpp
llworkerthread.cpp
- metaclass.cpp
- metaproperty.cpp
- reflective.cpp
timing.cpp
u64.cpp
)
@@ -115,7 +117,6 @@ set(llcommon_HEADER_FILES
bitpack.h
ctype_workaround.h
- doublelinkedlist.h
fix_macros.h
imageids.h
indra_constants.h
@@ -129,7 +130,6 @@ set(llcommon_HEADER_FILES
llapp.h
llapr.h
llassettype.h
- llassoclist.h
llavatarconstants.h
llbase32.h
llbase64.h
@@ -143,18 +143,14 @@ set(llcommon_HEADER_FILES
llcriticaldamp.h
llcursortypes.h
lldarray.h
- lldarrayptr.h
lldate.h
lldefs.h
lldependencies.h
lldeleteutils.h
lldepthstack.h
lldictionary.h
- lldlinked.h
lldoubledispatch.h
- lldqueueptr.h
llendianswizzle.h
- llenum.h
llerror.h
llerrorcontrol.h
llerrorlegacy.h
@@ -178,18 +174,15 @@ set(llcommon_HEADER_FILES
llhash.h
llheartbeat.h
llhttpstatuscodes.h
- llindexedqueue.h
llinitparam.h
llinstancetracker.h
llkeythrottle.h
- lllazy.h
llleap.h
llleaplistener.h
lllistenerwrapper.h
lllinkedqueue.h
llliveappconfig.h
lllivefile.h
- lllocalidhashmap.h
lllog.h
lllslconstants.h
llmap.h
@@ -199,15 +192,15 @@ set(llcommon_HEADER_FILES
llmetrics.h
llmetricperformancetester.h
llmortician.h
+ llmutex.h
llnametable.h
lloptioninterface.h
llpointer.h
+ llpredicate.h
llpreprocessor.h
llpriqueuemap.h
llprocess.h
llprocessor.h
- llptrskiplist.h
- llptrskipmap.h
llptrto.h
llqueuedthread.h
llrand.h
@@ -224,12 +217,7 @@ set(llcommon_HEADER_FILES
llsecondlifeurls.h
llsimplehash.h
llsingleton.h
- llskiplist.h
- llskipmap.h
- llsortedvector.h
- llstack.h
llstacktrace.h
- llstat.h
llstatenums.h
llstl.h
llstreamqueue.h
@@ -239,22 +227,21 @@ set(llcommon_HEADER_FILES
llstringtable.h
llsys.h
llthread.h
+ llthreadlocalstorage.h
llthreadsafequeue.h
lltimer.h
+ lltrace.h
+ lltracerecording.h
+ lltracethreadrecorder.h
lltreeiterators.h
- lltypeinfolookup.h
+ llunit.h
lluri.h
lluuid.h
- lluuidhashmap.h
llversionserver.h
+ llwin32headers.h
+ llwin32headerslean.h
llworkerthread.h
ll_template_cast.h
- metaclass.h
- metaclasst.h
- metaproperty.h
- metapropertyt.h
- reflective.h
- reflectivet.h
roles_constants.h
stdenums.h
stdtypes.h
@@ -326,7 +313,6 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
@@ -334,7 +320,7 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY}")
diff --git a/indra/llcommon/doublelinkedlist.h b/indra/llcommon/doublelinkedlist.h
deleted file mode 100755
index 0aeaa69df3..0000000000
--- a/indra/llcommon/doublelinkedlist.h
+++ /dev/null
@@ -1,1397 +0,0 @@
-/**
- * @file doublelinkedlist.h
- * @brief Provides a standard doubly linked list for fun and profit.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_DOUBLELINKEDLIST_H
-#define LL_DOUBLELINKEDLIST_H
-
-#include "llerror.h"
-#include "llrand.h"
-
-// node that actually contains the data
-template <class DATA_TYPE> class LLDoubleLinkedNode
-{
-public:
- DATA_TYPE *mDatap;
- LLDoubleLinkedNode *mNextp;
- LLDoubleLinkedNode *mPrevp;
-
-
-public:
- // assign the mDatap pointer
- LLDoubleLinkedNode(DATA_TYPE *data);
-
- // destructor does not, by default, destroy associated data
- // however, the mDatap must be NULL to ensure that we aren't causing memory leaks
- ~LLDoubleLinkedNode();
-
- // delete associated data and NULL out pointer
- void deleteData();
-
- // remove associated data and NULL out pointer
- void removeData();
-};
-
-
-const U32 LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH = 4;
-
-template <class DATA_TYPE> class LLDoubleLinkedList
-{
-private:
- LLDoubleLinkedNode<DATA_TYPE> mHead; // head node
- LLDoubleLinkedNode<DATA_TYPE> mTail; // tail node
- LLDoubleLinkedNode<DATA_TYPE> *mQueuep; // The node in the batter's box
- LLDoubleLinkedNode<DATA_TYPE> *mCurrentp; // The node we're talking about
-
- // The state stack allows nested exploration of the LLDoubleLinkedList
- // but should be used with great care
- LLDoubleLinkedNode<DATA_TYPE> *mQueuepStack[LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH];
- LLDoubleLinkedNode<DATA_TYPE> *mCurrentpStack[LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH];
- U32 mStateStackDepth;
- U32 mCount;
-
- // mInsertBefore is a pointer to a user-set function that returns
- // TRUE if "first" should be located before "second"
- // NOTE: mInsertBefore() should never return TRUE when ("first" == "second")
- // or never-ending loops can occur
- BOOL (*mInsertBefore)(DATA_TYPE *first, DATA_TYPE *second);
-
-public:
- LLDoubleLinkedList();
-
- // destructor destroys list and nodes, but not data in nodes
- ~LLDoubleLinkedList();
-
- // put data into a node and stick it at the front of the list
- // set mCurrentp to mQueuep
- void addData(DATA_TYPE *data);
-
- // put data into a node and stick it at the end of the list
- // set mCurrentp to mQueuep
- void addDataAtEnd(DATA_TYPE *data);
-
- S32 getLength() const;
- // search the list starting at mHead.mNextp and remove the link with mDatap == data
- // set mCurrentp to mQueuep
- // return TRUE if found, FALSE if not found
- BOOL removeData(const DATA_TYPE *data);
-
- // search the list starting at mHead.mNextp and delete the link with mDatap == data
- // set mCurrentp to mQueuep
- // return TRUE if found, FALSE if not found
- BOOL deleteData(DATA_TYPE *data);
-
- // remove all nodes from the list and delete the associated data
- void deleteAllData();
-
- // remove all nodes from the list but do not delete data
- void removeAllNodes();
-
- BOOL isEmpty();
-
- // check to see if data is in list
- // set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep
- // return TRUE if found, FALSE if not found
- BOOL checkData(const DATA_TYPE *data);
-
- // NOTE: This next two funtions are only included here
- // for those too familiar with the LLLinkedList template class.
- // They are depreciated. resetList() is unecessary while
- // getCurrentData() is identical to getNextData() and has
- // a misleading name.
- //
- // The recommended way to loop through a list is as follows:
- //
- // datap = list.getFirstData();
- // while (datap)
- // {
- // /* do stuff */
- // datap = list.getNextData();
- // }
-
- // place mQueuep on mHead node
- void resetList();
-
- // return the data currently pointed to,
- // set mCurrentp to that node and bump mQueuep down the list
- // NOTE: this function is identical to getNextData()
- DATA_TYPE *getCurrentData();
-
-
- // reset the list and return the data currently pointed to,
- // set mCurrentp to that node and bump mQueuep down the list
- DATA_TYPE *getFirstData();
-
-
- // reset the list and return the data at position n, set mCurentp
- // to that node and bump mQueuep down the list
- // Note: n=0 will behave like getFirstData()
- DATA_TYPE *getNthData(U32 n);
-
- // reset the list and return the last data in it,
- // set mCurrentp to that node and bump mQueuep up the list
- DATA_TYPE *getLastData();
-
- // return data in mQueuep,
- // set mCurrentp mQueuep and bump mQueuep down the list
- DATA_TYPE *getNextData();
-
- // return the data in mQueuep,
- // set mCurrentp to mQueuep and bump mQueuep up the list
- DATA_TYPE *getPreviousData();
-
- // remove the Node at mCurrentp
- // set mCurrentp to mQueuep
- void removeCurrentData();
-
- // delete the Node at mCurrentp
- // set mCurrentp to mQueuep
- void deleteCurrentData();
-
- // remove the Node at mCurrentp and insert it into newlist
- // set mCurrentp to mQueuep
- void moveCurrentData(LLDoubleLinkedList<DATA_TYPE> *newlist);
-
- // insert the node in front of mCurrentp
- // set mCurrentp to mQueuep
- void insertNode(LLDoubleLinkedNode<DATA_TYPE> *node);
-
- // insert the data in front of mCurrentp
- // set mCurrentp to mQueuep
- void insertData(DATA_TYPE *data);
-
- // if mCurrentp has a previous node then :
- // * swaps mCurrentp with its previous
- // * set mCurrentp to mQueuep
- // (convenient for forward bubble-sort)
- // otherwise does nothing
- void swapCurrentWithPrevious();
-
- // if mCurrentp has a next node then :
- // * swaps mCurrentp with its next
- // * set mCurrentp to mQueuep
- // (convenient for backwards bubble-sort)
- // otherwise does nothing
- void swapCurrentWithNext();
-
- // move mCurrentp to the front of the list
- // set mCurrentp to mQueuep
- void moveCurrentToFront();
-
- // move mCurrentp to the end of the list
- // set mCurrentp to mQueuep
- void moveCurrentToEnd();
-
- // set mInsertBefore
- void setInsertBefore(BOOL (*insert_before)(DATA_TYPE *first, DATA_TYPE *second));
-
- // add data in front of first node for which mInsertBefore(datap, node->mDatap) returns TRUE
- // set mCurrentp to mQueuep
- BOOL addDataSorted(DATA_TYPE *datap);
-
- // sort the list using bubble-sort
- // Yes, this is a different name than the same function in LLLinkedList.
- // When it comes time for a name consolidation hopefully this one will win.
- BOOL bubbleSort();
-
- // does a single bubble sort pass on the list
- BOOL lazyBubbleSort();
-
- // returns TRUE if state successfully pushed (state stack not full)
- BOOL pushState();
-
- // returns TRUE if state successfully popped (state stack not empty)
- BOOL popState();
-
- // empties the state stack
- void clearStateStack();
-
- // randomly move the the links in the list for debug or (Discordian) purposes
- // sets mCurrentp and mQueuep to top of list
- void scramble();
-
-private:
- // add node to beginning of list
- // set mCurrentp to mQueuep
- void addNode(LLDoubleLinkedNode<DATA_TYPE> *node);
-
- // add node to end of list
- // set mCurrentp to mQueuep
- void addNodeAtEnd(LLDoubleLinkedNode<DATA_TYPE> *node);
-};
-
-//#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////
-
-// doublelinkedlist.cpp
-// LLDoubleLinkedList template class implementation file.
-// Provides a standard doubly linked list for fun and profit.
-//
-// Copyright 2001, Linden Research, Inc.
-
-//#include "llerror.h"
-//#include "doublelinkedlist.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////
-// LLDoubleLinkedNode
-//////////////////////////////////////////////////////////////////////////////////////////
-
-
-// assign the mDatap pointer
-template <class DATA_TYPE>
-LLDoubleLinkedNode<DATA_TYPE>::LLDoubleLinkedNode(DATA_TYPE *data) :
- mDatap(data), mNextp(NULL), mPrevp(NULL)
-{
-}
-
-
-// destructor does not, by default, destroy associated data
-// however, the mDatap must be NULL to ensure that we aren't causing memory leaks
-template <class DATA_TYPE>
-LLDoubleLinkedNode<DATA_TYPE>::~LLDoubleLinkedNode()
-{
- if (mDatap)
- {
- llerror("Attempting to call LLDoubleLinkedNode destructor with a non-null mDatap!", 1);
- }
-}
-
-
-// delete associated data and NULL out pointer
-template <class DATA_TYPE>
-void LLDoubleLinkedNode<DATA_TYPE>::deleteData()
-{
- delete mDatap;
- mDatap = NULL;
-}
-
-
-template <class DATA_TYPE>
-void LLDoubleLinkedNode<DATA_TYPE>::removeData()
-{
- mDatap = NULL;
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////////
-// LLDoubleLinkedList
-//////////////////////////////////////////////////////////////////////////////////////
-
-// <------- up -------
-//
-// mCurrentp
-// mQueuep |
-// | |
-// | |
-// .------. .------. .------. .------.
-// | |---->| |---->| |----->| |-----> NULL
-// NULL <-----| |<----| |<----| |<-----| |
-// _'------' '------' '------' '------:_
-// .------. /| | | |\ .------.
-// NULL <-----|mHead |/ | mQueuep \|mTail |-----> NULL
-// | | mCurrentp | |
-// '------' '------'
-// -------- down --------->
-
-template <class DATA_TYPE>
-LLDoubleLinkedList<DATA_TYPE>::LLDoubleLinkedList()
-: mHead(NULL), mTail(NULL), mQueuep(NULL)
-{
- mCurrentp = mHead.mNextp;
- mQueuep = mHead.mNextp;
- mStateStackDepth = 0;
- mCount = 0;
- mInsertBefore = NULL;
-}
-
-
-// destructor destroys list and nodes, but not data in nodes
-template <class DATA_TYPE>
-LLDoubleLinkedList<DATA_TYPE>::~LLDoubleLinkedList()
-{
- removeAllNodes();
-}
-
-
-// put data into a node and stick it at the front of the list
-// doesn't change mCurrentp nor mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::addData(DATA_TYPE *data)
-{
- // don't allow NULL to be passed to addData
- if (!data)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::addData()", 0);
- }
-
- // make the new node
- LLDoubleLinkedNode<DATA_TYPE> *temp = new LLDoubleLinkedNode<DATA_TYPE> (data);
-
- // add the node to the front of the list
- temp->mPrevp = NULL;
- temp->mNextp = mHead.mNextp;
- mHead.mNextp = temp;
-
- // if there's something in the list, fix its back pointer
- if (temp->mNextp)
- {
- temp->mNextp->mPrevp = temp;
- }
- // otherwise, fix the tail of the list
- else
- {
- mTail.mPrevp = temp;
- }
-
- mCount++;
-}
-
-
-// put data into a node and stick it at the end of the list
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::addDataAtEnd(DATA_TYPE *data)
-{
- // don't allow NULL to be passed to addData
- if (!data)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::addData()", 0);
- }
-
- // make the new node
- LLDoubleLinkedNode<DATA_TYPE> *nodep = new LLDoubleLinkedNode<DATA_TYPE>(data);
-
- addNodeAtEnd(nodep);
- mCount++;
-}
-
-
-// search the list starting at mHead.mNextp and remove the link with mDatap == data
-// set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data
-// return TRUE if found, FALSE if not found
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::removeData(const DATA_TYPE *data)
-{
- BOOL b_found = FALSE;
- // don't allow NULL to be passed to addData
- if (!data)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::removeData()", 0);
- }
-
- mCurrentp = mHead.mNextp;
-
- while (mCurrentp)
- {
- if (mCurrentp->mDatap == data)
- {
- b_found = TRUE;
-
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // remove the node
- mCurrentp->removeData();
- delete mCurrentp;
- mCount--;
- break;
- }
- mCurrentp = mCurrentp->mNextp;
- }
-
- // reset the list back to where it was
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
-
- return b_found;
-}
-
-
-// search the list starting at mHead.mNextp and delete the link with mDatap == data
-// set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data
-// return TRUE if found, FALSE if not found
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::deleteData(DATA_TYPE *data)
-{
- BOOL b_found = FALSE;
- // don't allow NULL to be passed to addData
- if (!data)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::deleteData()", 0);
- }
-
- mCurrentp = mHead.mNextp;
-
- while (mCurrentp)
- {
- if (mCurrentp->mDatap == data)
- {
- b_found = TRUE;
-
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // remove the node
- mCurrentp->deleteData();
- delete mCurrentp;
- mCount--;
- break;
- }
- mCurrentp = mCurrentp->mNextp;
- }
-
- // reset the list back to where it was
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
-
- return b_found;
-}
-
-
-// remove all nodes from the list and delete the associated data
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::deleteAllData()
-{
- mCurrentp = mHead.mNextp;
-
- while (mCurrentp)
- {
- mQueuep = mCurrentp->mNextp;
- mCurrentp->deleteData();
- delete mCurrentp;
- mCurrentp = mQueuep;
- }
-
- // reset mHead and mQueuep
- mHead.mNextp = NULL;
- mTail.mPrevp = NULL;
- mCurrentp = mHead.mNextp;
- mQueuep = mHead.mNextp;
- mStateStackDepth = 0;
- mCount = 0;
-}
-
-
-// remove all nodes from the list but do not delete associated data
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::removeAllNodes()
-{
- mCurrentp = mHead.mNextp;
-
- while (mCurrentp)
- {
- mQueuep = mCurrentp->mNextp;
- mCurrentp->removeData();
- delete mCurrentp;
- mCurrentp = mQueuep;
- }
-
- // reset mHead and mCurrentp
- mHead.mNextp = NULL;
- mTail.mPrevp = NULL;
- mCurrentp = mHead.mNextp;
- mQueuep = mHead.mNextp;
- mStateStackDepth = 0;
- mCount = 0;
-}
-
-template <class DATA_TYPE>
-S32 LLDoubleLinkedList<DATA_TYPE>::getLength() const
-{
-// U32 length = 0;
-// for (LLDoubleLinkedNode<DATA_TYPE>* temp = mHead.mNextp; temp != NULL; temp = temp->mNextp)
-// {
-// length++;
-// }
- return mCount;
-}
-
-// check to see if data is in list
-// set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep
-// return TRUE if found, FALSE if not found
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::checkData(const DATA_TYPE *data)
-{
- mCurrentp = mHead.mNextp;
-
- while (mCurrentp)
- {
- if (mCurrentp->mDatap == data)
- {
- mQueuep = mCurrentp;
- return TRUE;
- }
- mCurrentp = mCurrentp->mNextp;
- }
-
- mCurrentp = mQueuep;
- return FALSE;
-}
-
-// NOTE: This next two funtions are only included here
-// for those too familiar with the LLLinkedList template class.
-// They are depreciated. resetList() is unecessary while
-// getCurrentData() is identical to getNextData() and has
-// a misleading name.
-//
-// The recommended way to loop through a list is as follows:
-//
-// datap = list.getFirstData();
-// while (datap)
-// {
-// /* do stuff */
-// datap = list.getNextData();
-// }
-
- // place mCurrentp and mQueuep on first node
- template <class DATA_TYPE>
- void LLDoubleLinkedList<DATA_TYPE>::resetList()
- {
- mCurrentp = mHead.mNextp;
- mQueuep = mHead.mNextp;
- mStateStackDepth = 0;
- }
-
-
- // return the data currently pointed to,
- // set mCurrentp to that node and bump mQueuep down the list
- template <class DATA_TYPE>
- DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getCurrentData()
- {
- if (mQueuep)
- {
- mCurrentp = mQueuep;
- mQueuep = mQueuep->mNextp;
- return mCurrentp->mDatap;
- }
- else
- {
- return NULL;
- }
- }
-
-
-// reset the list and return the data currently pointed to,
-// set mCurrentp to that node and bump mQueuep down the list
-template <class DATA_TYPE>
-DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getFirstData()
-{
- mQueuep = mHead.mNextp;
- mCurrentp = mQueuep;
- if (mQueuep)
- {
- mQueuep = mQueuep->mNextp;
- return mCurrentp->mDatap;
- }
- else
- {
- return NULL;
- }
-}
-
-
-// reset the list and return the data at position n, set mCurentp
-// to that node and bump mQueuep down the list
-// Note: n=0 will behave like getFirstData()
-template <class DATA_TYPE>
-DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getNthData(U32 n)
-{
- mCurrentp = mHead.mNextp;
-
- if (mCurrentp)
- {
- for (U32 i=0; i<n; i++)
- {
- mCurrentp = mCurrentp->mNextp;
- if (!mCurrentp)
- {
- break;
- }
- }
- }
-
- if (mCurrentp)
- {
- // bump mQueuep down the list
- mQueuep = mCurrentp->mNextp;
- return mCurrentp->mDatap;
- }
- else
- {
- mQueuep = NULL;
- return NULL;
- }
-}
-
-
-// reset the list and return the last data in it,
-// set mCurrentp to that node and bump mQueuep up the list
-template <class DATA_TYPE>
-DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getLastData()
-{
- mQueuep = mTail.mPrevp;
- mCurrentp = mQueuep;
- if (mQueuep)
- {
- mQueuep = mQueuep->mPrevp;
- return mCurrentp->mDatap;
- }
- else
- {
- return NULL;
- }
-}
-
-
-// return the data in mQueuep,
-// set mCurrentp to mQueuep and bump mQueuep down the list
-template <class DATA_TYPE>
-DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getNextData()
-{
- if (mQueuep)
- {
- mCurrentp = mQueuep;
- mQueuep = mQueuep->mNextp;
- return mCurrentp->mDatap;
- }
- else
- {
- return NULL;
- }
-}
-
-
-// return the data in mQueuep,
-// set mCurrentp to mQueuep and bump mQueuep up the list
-template <class DATA_TYPE>
-DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getPreviousData()
-{
- if (mQueuep)
- {
- mCurrentp = mQueuep;
- mQueuep = mQueuep->mPrevp;
- return mCurrentp->mDatap;
- }
- else
- {
- return NULL;
- }
-}
-
-
-// remove the Node at mCurrentp
-// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep)
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::removeCurrentData()
-{
- if (mCurrentp)
- {
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // otherwise we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // otherwise we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // remove the node
- mCurrentp->removeData();
- delete mCurrentp;
- mCount--;
-
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- }
-}
-
-
-// delete the Node at mCurrentp
-// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep)
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::deleteCurrentData()
-{
- if (mCurrentp)
- {
- // remove the node
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // otherwise we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // otherwise we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // remove the LLDoubleLinkedNode
- mCurrentp->deleteData();
- delete mCurrentp;
- mCount--;
-
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- }
-}
-
-
-// remove the Node at mCurrentp and insert it into newlist
-// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep)
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::moveCurrentData(LLDoubleLinkedList<DATA_TYPE> *newlist)
-{
- if (mCurrentp)
- {
- // remove the node
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // otherwise we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // otherwise we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // move the node to the new list
- newlist->addNode(mCurrentp);
-
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- }
-}
-
-
-// Inserts the node previous to mCurrentp
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::insertNode(LLDoubleLinkedNode<DATA_TYPE> *nodep)
-{
- // don't allow pointer to NULL to be passed
- if (!nodep)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::insertNode()", 0);
- }
- if (!nodep->mDatap)
- {
- llerror("NULL data pointer passed to LLDoubleLinkedList::insertNode()", 0);
- }
-
- if (mCurrentp)
- {
- if (mCurrentp->mPrevp)
- {
- nodep->mPrevp = mCurrentp->mPrevp;
- nodep->mNextp = mCurrentp;
- mCurrentp->mPrevp->mNextp = nodep;
- mCurrentp->mPrevp = nodep;
- }
- else // at beginning of list
- {
- nodep->mPrevp = NULL;
- nodep->mNextp = mCurrentp;
- mHead.mNextp = nodep;
- mCurrentp->mPrevp = nodep;
- }
- mCurrentp = mQueuep;
- }
- else // add to front of list
- {
- addNode(nodep);
- }
-}
-
-
-// insert the data in front of mCurrentp
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::insertData(DATA_TYPE *data)
-{
- if (!data)
- {
- llerror("NULL data pointer passed to LLDoubleLinkedList::insertNode()", 0);
- }
- LLDoubleLinkedNode<DATA_TYPE> *node = new LLDoubleLinkedNode<DATA_TYPE>(data);
- insertNode(node);
- mCount++;
-}
-
-
-// if mCurrentp has a previous node then :
-// * swaps mCurrentp with its previous
-// * set mCurrentp to mQueuep
-// otherwise does nothing
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::swapCurrentWithPrevious()
-{
- if (mCurrentp)
- {
- if (mCurrentp->mPrevp)
- {
- // Pull mCurrentp out of list
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // mCurrentp was at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // Fix mCurrentp's pointers
- mCurrentp->mNextp = mCurrentp->mPrevp;
- mCurrentp->mPrevp = mCurrentp->mNextp->mPrevp;
- mCurrentp->mNextp->mPrevp = mCurrentp;
-
- if (mCurrentp->mPrevp)
- {
- // Fix the backward pointer of mCurrentp's new previous
- mCurrentp->mPrevp->mNextp = mCurrentp;
- }
- else // mCurrentp is now at beginning of list
- {
- mHead.mNextp = mCurrentp;
- }
-
- // Set the list back to the way it was
- mCurrentp = mQueuep;
- }
- }
-}
-
-
-// if mCurrentp has a next node then :
-// * swaps mCurrentp with its next
-// * set mCurrentp to mQueuep
-// otherwise does nothing
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::swapCurrentWithNext()
-{
- if (mCurrentp)
- {
- if (mCurrentp->mNextp)
- {
- // Pull mCurrentp out of list
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // mCurrentp was at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // Fix mCurrentp's pointers
- mCurrentp->mPrevp = mCurrentp->mNextp;
- mCurrentp->mNextp = mCurrentp->mPrevp->mNextp;
- mCurrentp->mPrevp->mNextp = mCurrentp;
-
- if (mCurrentp->mNextp)
- {
- // Fix the back pointer of mCurrentp's new next
- mCurrentp->mNextp->mPrevp = mCurrentp;
- }
- else // mCurrentp is now at end of list
- {
- mTail.mPrevp = mCurrentp;
- }
-
- // Set the list back to the way it was
- mCurrentp = mQueuep;
- }
- }
-}
-
-// move mCurrentp to the front of the list
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::moveCurrentToFront()
-{
- if (mCurrentp)
- {
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // otherwise we are at beginning of list
- {
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- return;
- }
-
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // otherwise we are at end of list
- {
- mTail.mPrevp = mCurrentp->mPrevp;
- }
-
- // add mCurrentp to beginning of list
- mCurrentp->mNextp = mHead.mNextp;
- mHead.mNextp->mPrevp = mCurrentp; // mHead.mNextp MUST be valid,
- // or the list had only one node
- // and we would have returned already
- mCurrentp->mPrevp = NULL;
- mHead.mNextp = mCurrentp;
-
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- }
-
-}
-
-// move mCurrentp to the end of the list
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::moveCurrentToEnd()
-{
- if (mCurrentp)
- {
- // if there is a next one, fix it
- if (mCurrentp->mNextp)
- {
- mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp;
- }
- else // otherwise we are at end of list and we're done
- {
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- return;
- }
-
- // if there is a previous one, fix it
- if (mCurrentp->mPrevp)
- {
- mCurrentp->mPrevp->mNextp = mCurrentp->mNextp;
- }
- else // otherwise we are at beginning of list
- {
- mHead.mNextp = mCurrentp->mNextp;
- }
-
- // add mCurrentp to end of list
- mCurrentp->mPrevp = mTail.mPrevp;
- mTail.mPrevp->mNextp = mCurrentp; // mTail.mPrevp MUST be valid,
- // or the list had only one node
- // and we would have returned already
- mCurrentp->mNextp = NULL;
- mTail.mPrevp = mCurrentp;
-
- // check for redundant pointing
- if (mCurrentp == mQueuep)
- {
- mCurrentp = mQueuep = NULL;
- }
- else
- {
- mCurrentp = mQueuep;
- }
- }
-}
-
-
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::setInsertBefore(BOOL (*insert_before)(DATA_TYPE *first, DATA_TYPE *second) )
-{
- mInsertBefore = insert_before;
-}
-
-
-// add data in front of the first node for which mInsertBefore(datap, node->mDatap) returns TRUE
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::addDataSorted(DATA_TYPE *datap)
-{
- // don't allow NULL to be passed to addData()
- if (!datap)
- {
- llerror("NULL pointer passed to LLDoubleLinkedList::addDataSorted()", 0);
- }
-
- // has mInsertBefore not been set?
- if (!mInsertBefore)
- {
- addData(datap);
- return FALSE;
- }
-
- // is the list empty?
- if (!mHead.mNextp)
- {
- addData(datap);
- return TRUE;
- }
-
- // Note: this step has been added so that the behavior of LLDoubleLinkedList
- // is as rigorous as the LLLinkedList class about adding duplicate nodes.
- // Duplicate nodes can cause a problem when sorting if mInsertBefore(foo, foo)
- // returns TRUE. However, if mInsertBefore(foo, foo) returns FALSE, then there
- // shouldn't be any reason to exclude duplicate nodes (as we do here).
- if (checkData(datap))
- {
- return FALSE;
- }
-
- mCurrentp = mHead.mNextp;
- while (mCurrentp)
- {
- // check to see if datap is already in the list
- if (datap == mCurrentp->mDatap)
- {
- return FALSE;
- }
- else if (mInsertBefore(datap, mCurrentp->mDatap))
- {
- insertData(datap);
- return TRUE;
- }
- mCurrentp = mCurrentp->mNextp;
- }
-
- addDataAtEnd(datap);
- return TRUE;
-}
-
-
-// bubble-sort until sorted and return TRUE if anything was sorted
-// leaves mQueuep pointing at last node that was swapped with its mNextp
-//
-// NOTE: if you find this function looping for really long times, then you
-// probably need to check your implementation of mInsertBefore(a,b) and make
-// sure it does not return TRUE when (a == b)!
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::bubbleSort()
-{
- BOOL b_swapped = FALSE;
- U32 count = 0;
- while (lazyBubbleSort())
- {
- b_swapped = TRUE;
- if (count++ > 0x7FFFFFFF)
- {
- llwarning("LLDoubleLinkedList::bubbleSort() : too many passes...", 1);
- llwarning(" make sure the mInsertBefore(a, b) does not return TRUE for a == b", 1);
- break;
- }
- }
- return b_swapped;
-}
-
-
-// do a single bubble-sort pass and return TRUE if anything was sorted
-// leaves mQueuep pointing at last node that was swapped with its mNextp
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::lazyBubbleSort()
-{
- // has mInsertBefore been set?
- if (!mInsertBefore)
- {
- return FALSE;
- }
-
- // is list empty?
- mCurrentp = mHead.mNextp;
- if (!mCurrentp)
- {
- return FALSE;
- }
-
- BOOL b_swapped = FALSE;
-
- // the sort will exit after 0x7FFFFFFF nodes or the end of the list, whichever is first
- S32 length = 0x7FFFFFFF;
- S32 count = 0;
-
- while (mCurrentp && mCurrentp->mNextp && count<length)
- {
- if (mInsertBefore(mCurrentp->mNextp->mDatap, mCurrentp->mDatap))
- {
- b_swapped = TRUE;
- mQueuep = mCurrentp;
- swapCurrentWithNext(); // sets mCurrentp to mQueuep
- }
- count++;
- mCurrentp = mCurrentp->mNextp;
- }
-
- return b_swapped;
-}
-
-
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::pushState()
-{
- if (mStateStackDepth < LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH)
- {
- *(mQueuepStack + mStateStackDepth) = mQueuep;
- *(mCurrentpStack + mStateStackDepth) = mCurrentp;
- mStateStackDepth++;
- return TRUE;
- }
- return FALSE;
-}
-
-
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::popState()
-{
- if (mStateStackDepth > 0)
- {
- mStateStackDepth--;
- mQueuep = *(mQueuepStack + mStateStackDepth);
- mCurrentp = *(mCurrentpStack + mStateStackDepth);
- return TRUE;
- }
- return FALSE;
-}
-
-
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::clearStateStack()
-{
- mStateStackDepth = 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-// private members
-//////////////////////////////////////////////////////////////////////////////////////////
-
-// add node to beginning of list
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::addNode(LLDoubleLinkedNode<DATA_TYPE> *nodep)
-{
- // add the node to the front of the list
- nodep->mPrevp = NULL;
- nodep->mNextp = mHead.mNextp;
- mHead.mNextp = nodep;
-
- // if there's something in the list, fix its back pointer
- if (nodep->mNextp)
- {
- nodep->mNextp->mPrevp = nodep;
- }
- else // otherwise fix the tail node
- {
- mTail.mPrevp = nodep;
- }
-
- mCurrentp = mQueuep;
-}
-
-
-// add node to end of list
-// set mCurrentp to mQueuep
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::addNodeAtEnd(LLDoubleLinkedNode<DATA_TYPE> *node)
-{
- // add the node to the end of the list
- node->mNextp = NULL;
- node->mPrevp = mTail.mPrevp;
- mTail.mPrevp = node;
-
- // if there's something in the list, fix its back pointer
- if (node->mPrevp)
- {
- node->mPrevp->mNextp = node;
- }
- else // otherwise fix the head node
- {
- mHead.mNextp = node;
- }
-
- mCurrentp = mQueuep;
-}
-
-
-// randomly move nodes in the list for DEBUG (or Discordian) purposes
-// sets mCurrentp and mQueuep to top of list
-template <class DATA_TYPE>
-void LLDoubleLinkedList<DATA_TYPE>::scramble()
-{
- S32 random_number;
- DATA_TYPE *datap = getFirstData();
- while(datap)
- {
- random_number = ll_rand(5);
-
- if (0 == random_number)
- {
- removeCurrentData();
- addData(datap);
- }
- else if (1 == random_number)
- {
- removeCurrentData();
- addDataAtEnd(datap);
- }
- else if (2 == random_number)
- {
- swapCurrentWithPrevious();
- }
- else if (3 == random_number)
- {
- swapCurrentWithNext();
- }
- datap = getNextData();
- }
- mQueuep = mHead.mNextp;
- mCurrentp = mQueuep;
-}
-
-template <class DATA_TYPE>
-BOOL LLDoubleLinkedList<DATA_TYPE>::isEmpty()
-{
- return (mCount == 0);
-}
-
-
-#endif
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a0802c6adf..b6adb37eba 100755
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llapr.h"
#include "apr_dso.h"
+#include "llthreadlocalstorage.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@@ -37,12 +38,15 @@ apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
+bool gAPRInitialized = false;
+
void ll_init_apr()
{
+ // Initialize APR and create the global pool
+ apr_initialize();
+
if (!gAPRPoolp)
{
- // Initialize APR and create the global pool
- apr_initialize();
apr_pool_create(&gAPRPoolp, NULL);
// Initialize the logging mutex
@@ -54,11 +58,21 @@ void ll_init_apr()
{
LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ;
}
+
+ LLThreadLocalPointerBase::initAllThreadLocalStorage();
+ gAPRInitialized = true;
}
+bool ll_apr_is_initialized()
+{
+ return gAPRInitialized;
+}
+
void ll_cleanup_apr()
{
+ gAPRInitialized = false;
+
LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;
if (gLogMutexp)
@@ -77,6 +91,9 @@ void ll_cleanup_apr()
apr_thread_mutex_destroy(gCallStacksLogMutexp);
gCallStacksLogMutexp = NULL;
}
+
+ LLThreadLocalPointerBase::destroyAllThreadLocalStorage();
+
if (gAPRPoolp)
{
apr_pool_destroy(gAPRPoolp);
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 752574c65d..e9b13c5919 100755
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -32,28 +32,34 @@
#if LL_LINUX || LL_SOLARIS
#include <sys/param.h> // Need PATH_MAX in APR headers...
#endif
-#if LL_WINDOWS
- // Limit Windows API to small and manageable set.
- // If you get undefined symbols, find the appropriate
- // Windows header file and include that in your .cpp file.
- #define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>
- #include <windows.h>
-#endif
#include <boost/noncopyable.hpp>
-
+#include "llwin32headerslean.h"
#include "apr_thread_proc.h"
#include "apr_thread_mutex.h"
#include "apr_getopt.h"
#include "apr_signal.h"
#include "apr_atomic.h"
+
#include "llstring.h"
extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
extern apr_thread_mutex_t* gCallStacksLogMutexp;
struct apr_dso_handle_t;
+/**
+ * @brief Function which appropriately logs error or remains quiet on
+ * APR_SUCCESS.
+ * @return Returns <code>true</code> if status is an error condition.
+ */
+bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
+/// There's a whole other APR error-message function if you pass a DSO handle.
+bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle);
+
+void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
+void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
+
+extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
/**
* @brief initialize the common apr constructs -- apr itself, the
@@ -66,6 +72,9 @@ void LL_COMMON_API ll_init_apr();
*/
void LL_COMMON_API ll_cleanup_apr();
+bool LL_COMMON_API ll_apr_is_initialized();
+
+
//
//LL apr_pool
//manage apr_pool_t, destroy allocated apr_pool in the destruction function.
@@ -163,14 +172,17 @@ public:
LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); };
~LLAtomic32<Type>() {};
- operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
+ operator const Type() { return get(); }
Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
- Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
+ Type operator ++() { apr_atomic_inc32(&mData); return get(); } // ++Type
+ Type operator --(int) { const Type result(get()); apr_atomic_dec32(&mData); return result; } // Type--
+ Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
private:
+ const Type get() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
apr_uint32_t mData;
};
@@ -257,18 +269,5 @@ public:
//*******************************************************************************************************************************
};
-/**
- * @brief Function which appropriately logs error or remains quiet on
- * APR_SUCCESS.
- * @return Returns <code>true</code> if status is an error condition.
- */
-bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
-/// There's a whole other APR error-message function if you pass a DSO handle.
-bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle);
-
-void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
-void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
-
-extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
#endif // LL_LLAPR_H
diff --git a/indra/llcommon/llassoclist.h b/indra/llcommon/llassoclist.h
deleted file mode 100755
index 2950504155..0000000000
--- a/indra/llcommon/llassoclist.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/**
- * @file llassoclist.h
- * @brief LLAssocList class header file
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLASSOCLIST_H
-#define LL_LLASSOCLIST_H
-
-//------------------------------------------------------------------------
-// LLAssocList is an associative list container class.
-//
-// The implementation is a single linked list.
-// Both index and value objects are stored by value (not reference).
-// If pointer values are specified for index and/or value, this
-// container does NOT assume ownership of the referenced objects,
-// and does NOT delete() them on removal or destruction of the container.
-//
-// Note that operations are generally not optimized, and may of them
-// are O(n) complexity.
-//------------------------------------------------------------------------
-
-#include <iostream>
-
-template<class INDEX_TYPE, class VALUE_TYPE>
-class LLAssocList
-{
-private:
- // internal list node type
- class Node
- {
- public:
- Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next)
- {
- mIndex = index;
- mValue = value;
- mNext = next;
- }
- ~Node() { }
- INDEX_TYPE mIndex;
- VALUE_TYPE mValue;
- Node *mNext;
- };
-
- // head of the linked list
- Node *mHead;
-
-public:
- // Constructor
- LLAssocList()
- {
- mHead = NULL;
- }
-
- // Destructor
- ~LLAssocList()
- {
- removeAll();
- }
-
- // Returns TRUE if list is empty.
- BOOL isEmpty()
- {
- return (mHead == NULL);
- }
-
- // Returns the number of items in the list.
- U32 length()
- {
- U32 count = 0;
- for ( Node *node = mHead;
- node;
- node = node->mNext )
- {
- count++;
- }
- return count;
- }
-
- // Removes item with the specified index.
- BOOL remove( const INDEX_TYPE &index )
- {
- if (!mHead)
- return FALSE;
-
- if (mHead->mIndex == index)
- {
- Node *node = mHead;
- mHead = mHead->mNext;
- delete node;
- return TRUE;
- }
-
- for ( Node *prev = mHead;
- prev->mNext;
- prev = prev->mNext )
- {
- if (prev->mNext->mIndex == index)
- {
- Node *node = prev->mNext;
- prev->mNext = prev->mNext->mNext;
- delete node;
- return TRUE;
- }
- }
- return FALSE;
- }
-
- // Removes all items from the list.
- void removeAll()
- {
- while ( mHead )
- {
- Node *node = mHead;
- mHead = mHead->mNext;
- delete node;
- }
- }
-
- // Adds a new item to the head of the list,
- // removing any existing item with same index.
- void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value )
- {
- remove(index);
- Node *node = new Node(index, value, mHead);
- mHead = node;
- }
-
- // Adds a new item to the end of the list,
- // removing any existing item with the same index.
- void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value )
- {
- remove(index);
- Node *node = new Node(index, value, NULL);
- if (!mHead)
- {
- mHead = node;
- return;
- }
- for ( Node *prev=mHead;
- prev;
- prev=prev->mNext )
- {
- if (!prev->mNext)
- {
- prev->mNext=node;
- return;
- }
- }
- }
-
- // Sets the value of a specified index.
- // If index does not exist, a new value will be added only if
- // 'addIfNotFound' is set to TRUE.
- // Returns TRUE if successful.
- BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE )
- {
- VALUE_TYPE *valueP = getValue(index);
- if (valueP)
- {
- *valueP = value;
- return TRUE;
- }
- if (!addIfNotFound)
- return FALSE;
- addToTail(index, value);
- return TRUE;
- }
-
- // Sets the ith value in the list.
- // A new value will NOT be addded, if the ith value does not exist.
- // Returns TRUE if successful.
- BOOL setValueAt( U32 i, const VALUE_TYPE &value )
- {
- VALUE_TYPE *valueP = getValueAt(i);
- if (valueP)
- {
- *valueP = value;
- return TRUE;
- }
- return FALSE;
- }
-
- // Returns a pointer to the value for the specified index,
- // or NULL if no item found.
- VALUE_TYPE *getValue( const INDEX_TYPE &index )
- {
- for ( Node *node = mHead;
- node;
- node = node->mNext )
- {
- if (node->mIndex == index)
- return &node->mValue;
- }
- return NULL;
- }
-
- // Returns a pointer to the ith value in the list, or
- // NULL if i is not valid.
- VALUE_TYPE *getValueAt( U32 i )
- {
- U32 count = 0;
- for ( Node *node = mHead;
- node;
- node = node->mNext )
- {
- if (count == i)
- return &node->mValue;
- count++;
- }
- return NULL;
- }
-
- // Returns a pointer to the index for the specified index,
- // or NULL if no item found.
- INDEX_TYPE *getIndex( const INDEX_TYPE &index )
- {
- for ( Node *node = mHead;
- node;
- node = node->mNext )
- {
- if (node->mIndex == index)
- return &node->mIndex;
- }
- return NULL;
- }
-
- // Returns a pointer to the ith index in the list, or
- // NULL if i is not valid.
- INDEX_TYPE *getIndexAt( U32 i )
- {
- U32 count = 0;
- for ( Node *node = mHead;
- node;
- node = node->mNext )
- {
- if (count == i)
- return &node->mIndex;
- count++;
- }
- return NULL;
- }
-
- // Returns a pointer to the value for the specified index,
- // or NULL if no item found.
- VALUE_TYPE *operator[](const INDEX_TYPE &index)
- {
- return getValue(index);
- }
-
- // Returns a pointer to the ith value in the list, or
- // NULL if i is not valid.
- VALUE_TYPE *operator[](U32 i)
- {
- return getValueAt(i);
- }
-
- // Prints the list contents to the specified stream.
- friend std::ostream &operator<<( std::ostream &os, LLAssocList &map )
- {
- os << "{";
- for ( Node *node = map.mHead;
- node;
- node = node->mNext )
- {
- os << "<" << node->mIndex << ", " << node->mValue << ">";
- if (node->mNext)
- os << ", ";
- }
- os << "}";
-
- return os;
- }
-};
-
-#endif // LL_LLASSOCLIST_H
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 8be9e4f4de..c720df7555 100755
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -29,6 +29,7 @@
#include "llmemory.h"
#include "llthread.h"
+#include "lltrace.h"
//static
BOOL LLCommon::sAprInitialized = FALSE;
@@ -44,15 +45,13 @@ void LLCommon::initClass()
}
LLTimer::initClass();
LLThreadSafeRefCount::initThreadSafeRefCount();
-// LLWorkerThread::initClass();
-// LLFrameCallbackManager::initClass();
+ LLTrace::init();
}
//static
void LLCommon::cleanupClass()
{
-// LLFrameCallbackManager::cleanupClass();
-// LLWorkerThread::cleanupClass();
+ LLTrace::cleanup();
LLThreadSafeRefCount::cleanupThreadSafeRefCount();
LLTimer::cleanupClass();
if (sAprInitialized)
diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 87d79b1ee0..575fc4149e 100755
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -27,18 +27,38 @@
#include "linden_common.h"
#include "llcriticaldamp.h"
+#include <algorithm>
//-----------------------------------------------------------------------------
// static members
//-----------------------------------------------------------------------------
-LLFrameTimer LLCriticalDamp::sInternalTimer;
-std::map<F32, F32> LLCriticalDamp::sInterpolants;
-F32 LLCriticalDamp::sTimeDelta;
+LLFrameTimer LLSmoothInterpolation::sInternalTimer;
+std::vector<LLSmoothInterpolation::Interpolant> LLSmoothInterpolation::sInterpolants;
+F32 LLSmoothInterpolation::sTimeDelta;
+
+// helper functors
+struct LLSmoothInterpolation::CompareTimeConstants
+{
+ bool operator()(const F32& a, const LLSmoothInterpolation::Interpolant& b) const
+ {
+ return a < b.mTimeScale;
+ }
+
+ bool operator()(const LLSmoothInterpolation::Interpolant& a, const F32& b) const
+ {
+ return a.mTimeScale < b; // bottom of a is higher than bottom of b
+ }
+
+ bool operator()(const LLSmoothInterpolation::Interpolant& a, const LLSmoothInterpolation::Interpolant& b) const
+ {
+ return a.mTimeScale < b.mTimeScale; // bottom of a is higher than bottom of b
+ }
+};
//-----------------------------------------------------------------------------
-// LLCriticalDamp()
+// LLSmoothInterpolation()
//-----------------------------------------------------------------------------
-LLCriticalDamp::LLCriticalDamp()
+LLSmoothInterpolation::LLSmoothInterpolation()
{
sTimeDelta = 0.f;
}
@@ -47,43 +67,54 @@ LLCriticalDamp::LLCriticalDamp()
//-----------------------------------------------------------------------------
// updateInterpolants()
//-----------------------------------------------------------------------------
-void LLCriticalDamp::updateInterpolants()
+void LLSmoothInterpolation::updateInterpolants()
{
sTimeDelta = sInternalTimer.getElapsedTimeAndResetF32();
- F32 time_constant;
-
- for (std::map<F32, F32>::iterator iter = sInterpolants.begin();
- iter != sInterpolants.end(); iter++)
+ for (S32 i = 0; i < sInterpolants.size(); i++)
{
- time_constant = iter->first;
- F32 new_interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
- new_interpolant = llclamp(new_interpolant, 0.f, 1.f);
- sInterpolants[time_constant] = new_interpolant;
+ Interpolant& interp = sInterpolants[i];
+ interp.mInterpolant = calcInterpolant(interp.mTimeScale);
}
}
//-----------------------------------------------------------------------------
// getInterpolant()
//-----------------------------------------------------------------------------
-F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache)
+F32 LLSmoothInterpolation::getInterpolant(LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache)
{
if (time_constant == 0.f)
{
return 1.f;
}
- if (use_cache && sInterpolants.count(time_constant))
+ if (use_cache)
{
- return sInterpolants[time_constant];
+ interpolant_vec_t::iterator find_it = std::lower_bound(sInterpolants.begin(), sInterpolants.end(), time_constant.value(), CompareTimeConstants());
+ if (find_it != sInterpolants.end() && find_it->mTimeScale == time_constant)
+ {
+ return find_it->mInterpolant;
+ }
+ else
+ {
+ Interpolant interp;
+ interp.mTimeScale = time_constant.value();
+ interp.mInterpolant = calcInterpolant(time_constant.value());
+ sInterpolants.insert(find_it, interp);
+ return interp.mInterpolant;
+ }
}
-
- F32 interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
- interpolant = llclamp(interpolant, 0.f, 1.f);
- if (use_cache)
+ else
{
- sInterpolants[time_constant] = interpolant;
+ return calcInterpolant(time_constant.value());
+
}
+}
- return interpolant;
+//-----------------------------------------------------------------------------
+// calcInterpolant()
+//-----------------------------------------------------------------------------
+F32 LLSmoothInterpolation::calcInterpolant(F32 time_constant)
+{
+ return llclamp(1.f - powf(2.f, -sTimeDelta / time_constant), 0.f, 1.f);
}
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 52f052ae25..e174643cd0 100755
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
@@ -28,26 +28,46 @@
#ifndef LL_LLCRITICALDAMP_H
#define LL_LLCRITICALDAMP_H
-#include <map>
+#include <vector>
#include "llframetimer.h"
+#include "llunit.h"
-class LL_COMMON_API LLCriticalDamp
+class LL_COMMON_API LLSmoothInterpolation
{
public:
- LLCriticalDamp();
+ LLSmoothInterpolation();
// MANIPULATORS
static void updateInterpolants();
// ACCESSORS
- static F32 getInterpolant(const F32 time_constant, BOOL use_cache = TRUE);
+ static F32 getInterpolant(LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache = true);
-protected:
+ template<typename T>
+ static T lerp(T a, T b, LLUnit<F32, LLUnits::Seconds> time_constant, bool use_cache = true)
+ {
+ F32 interpolant = getInterpolant(time_constant, use_cache);
+ return ((a * (1.f - interpolant))
+ + (b * interpolant));
+ }
+
+protected:
+ static F32 calcInterpolant(F32 time_constant);
+
+ struct CompareTimeConstants;
static LLFrameTimer sInternalTimer; // frame timer for calculating deltas
- static std::map<F32, F32> sInterpolants;
+ struct Interpolant
+ {
+ F32 mTimeScale;
+ F32 mInterpolant;
+ };
+ typedef std::vector<Interpolant> interpolant_vec_t;
+ static interpolant_vec_t sInterpolants;
static F32 sTimeDelta;
};
+typedef LLSmoothInterpolation LLCriticalDamp;
+
#endif // LL_LLCRITICALDAMP_H
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 030ef6a3c7..7892269e35 100755
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -39,6 +39,7 @@
#include "lltimer.h"
#include "llstring.h"
+#include "llfasttimer.h"
static const F64 DATE_EPOCH = 0.0;
@@ -48,18 +49,15 @@ static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
-{
-}
+{}
LLDate::LLDate(const LLDate& date) :
mSecondsSinceEpoch(date.mSecondsSinceEpoch)
-{
-}
+{}
-LLDate::LLDate(F64 seconds_since_epoch) :
- mSecondsSinceEpoch(seconds_since_epoch)
-{
-}
+LLDate::LLDate(LLUnit<F64, LLUnits::Seconds> seconds_since_epoch) :
+ mSecondsSinceEpoch(seconds_since_epoch.value())
+{}
LLDate::LLDate(const std::string& iso8601_date)
{
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 7ff8b550ad..1067ac5280 100755
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -33,6 +33,7 @@
#include <string>
#include "stdtypes.h"
+#include "llunit.h"
/**
* @class LLDate
@@ -56,9 +57,9 @@ public:
/**
* @brief Construct a date from a seconds since epoch value.
*
- * @pararm seconds_since_epoch The number of seconds since UTC epoch.
+ * @param seconds_since_epoch The number of seconds since UTC epoch.
*/
- LLDate(F64 seconds_since_epoch);
+ LLDate(LLUnit<F64, LLUnits::Seconds> seconds_since_epoch);
/**
* @brief Construct a date from a string representation
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 5a4b8325f4..d57b9dccff 100755
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
@@ -244,5 +244,8 @@ inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
rhs = tmp;
}
+#define LL_GLUE_IMPL(x, y) x##y
+#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
+
#endif // LL_LLDEFS_H
diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h
index f250dc3028..f250dc3028 100755..100644
--- a/indra/llcommon/lldeleteutils.h
+++ b/indra/llcommon/lldeleteutils.h
diff --git a/indra/llcommon/lldepthstack.h b/indra/llcommon/lldepthstack.h
index d9db54efc7..ac435a30fa 100755
--- a/indra/llcommon/lldepthstack.h
+++ b/indra/llcommon/lldepthstack.h
@@ -27,17 +27,20 @@
#ifndef LL_LLDEPTHSTACK_H
#define LL_LLDEPTHSTACK_H
-#include "linked_lists.h"
+#include "llstl.h"
template <class DATA_TYPE> class LLDepthStack
{
private:
- LLLinkedList<DATA_TYPE> mStack;
+ std::deque<DATA_TYPE*> mStack;
U32 mCurrentDepth;
U32 mMaxDepth;
public:
- LLDepthStack() : mCurrentDepth(0), mMaxDepth(0) {}
+ LLDepthStack()
+ : mCurrentDepth(0), mMaxDepth(0)
+ {}
+
~LLDepthStack() {}
void setDepth(U32 depth)
@@ -54,24 +57,27 @@ public:
{
if (mCurrentDepth < mMaxDepth)
{
- mStack.addData(data);
+ mStack.push_back(data);
mCurrentDepth++;
}
else
{
// the last item falls off stack and is deleted
- mStack.getLastData();
- mStack.deleteCurrentData();
- mStack.addData(data);
+ if (!mStack.empty())
+ {
+ mStack.pop_front();
+ }
+ mStack.push_back(data);
}
}
DATA_TYPE *pop()
{
- DATA_TYPE *tempp = mStack.getFirstData();
- if (tempp)
+ DATA_TYPE *tempp = NULL;
+ if (!mStack.empty())
{
- mStack.removeCurrentData();
+ tempp = mStack.back();
+ mStack.pop_back();
mCurrentDepth--;
}
return tempp;
@@ -79,20 +85,20 @@ public:
DATA_TYPE *check()
{
- DATA_TYPE *tempp = mStack.getFirstData();
- return tempp;
+ return mStack.empty() ? NULL : mStack.back();
}
void deleteAllData()
{
mCurrentDepth = 0;
- mStack.deleteAllData();
+ std::for_each(mStack.begin(), mStack.end(), DeletePointer());
+ mStack.clear();
}
void removeAllNodes()
{
mCurrentDepth = 0;
- mStack.removeAllNodes();
+ mStack.clear();
}
};
diff --git a/indra/llcommon/lldlinked.h b/indra/llcommon/lldlinked.h
deleted file mode 100755
index 3f7c197be7..0000000000
--- a/indra/llcommon/lldlinked.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @file lldlinked.h
- * @brief Declaration of the LLDLinked class.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#ifndef LL_LLDLINKED_H
-#define LL_LLDLINKED_H
-
-template <class Type> class LLDLinked
-{
- LLDLinked* mNextp;
- LLDLinked* mPrevp;
-public:
-
- Type* getNext() { return (Type*)mNextp; }
- Type* getPrev() { return (Type*)mPrevp; }
- Type* getFirst() { return (Type*)mNextp; }
-
- void init()
- {
- mNextp = mPrevp = NULL;
- }
-
- void unlink()
- {
- if (mPrevp) mPrevp->mNextp = mNextp;
- if (mNextp) mNextp->mPrevp = mPrevp;
- }
-
- LLDLinked() { mNextp = mPrevp = NULL; }
- virtual ~LLDLinked() { unlink(); }
-
- virtual void deleteAll()
- {
- Type *curp = getFirst();
- while(curp)
- {
- Type *nextp = curp->getNext();
- curp->unlink();
- delete curp;
- curp = nextp;
- }
- }
-
- void relink(Type &after)
- {
- LLDLinked *afterp = (LLDLinked*)&after;
- afterp->mPrevp = this;
- mNextp = afterp;
- }
-
- virtual void append(Type& after)
- {
- LLDLinked *afterp = (LLDLinked*)&after;
- afterp->mPrevp = this;
- afterp->mNextp = mNextp;
- if (mNextp) mNextp->mPrevp = afterp;
- mNextp = afterp;
- }
-
- virtual void insert(Type& before)
- {
- LLDLinked *beforep = (LLDLinked*)&before;
- beforep->mNextp = this;
- beforep->mPrevp = mPrevp;
- if (mPrevp) mPrevp->mNextp = beforep;
- mPrevp = beforep;
- }
-
- virtual void put(Type& obj) { append(obj); }
-};
-
-#endif
diff --git a/indra/llcommon/lldqueueptr.h b/indra/llcommon/lldqueueptr.h
deleted file mode 100755
index 9fe08191e1..0000000000
--- a/indra/llcommon/lldqueueptr.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/**
- * @file lldqueueptr.h
- * @brief LLDynamicQueuePtr declaration
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#ifndef LL_LLDQUEUEPTR_H
-#define LL_LLDQUEUEPTR_H
-
-template <class Type>
-class LLDynamicQueuePtr
-{
-public:
- enum
- {
- OKAY = 0,
- FAIL = -1
- };
-
- LLDynamicQueuePtr(const S32 size=8);
- ~LLDynamicQueuePtr();
-
- void init();
- void destroy();
- void reset();
- void reallocate(U32 newsize);
-
- // ACCESSORS
- const Type& get(const S32 index) const; // no bounds checking
- Type& get(const S32 index); // no bounds checking
- const Type& operator [] (const S32 index) const { return get(index); }
- Type& operator [] (const S32 index) { return get(index); }
- S32 find(const Type &obj) const;
-
- S32 count() const { return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); }
- S32 getMax() const { return mMaxObj; }
- S32 getFirst() const { return mFirstObj; }
- S32 getLast () const { return mLastObj; }
-
- // MANIPULATE
- S32 push(const Type &obj); // add to end of Queue, returns index from start
- S32 pull( Type &obj); // pull from Queue, returns index from start
-
- S32 remove (S32 index); // remove by index
- S32 removeObj(const Type &obj); // remove by object
-
-protected:
- S32 mFirstObj, mLastObj, mMaxObj;
- Type* mMemory;
-
-public:
-
- void print()
- {
- /*
- Convert this to llinfos if it's intended to be used - djs 08/30/02
-
- printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj);
-
- if (mFirstObj <= mLastObj)
- {
- for (S32 i=mFirstObj;i<mLastObj;i++)
- {
- printf("%d ",mMemory[i]);
- }
- }
- else
- {
- for (S32 i=mFirstObj;i<mMaxObj;i++)
- {
- printf("%d ",mMemory[i]);
- }
- for (i=0;i<mLastObj;i++)
- {
- printf("%d ",mMemory[i]);
- }
- }
- printf("\n");
- */
- }
-
-};
-
-
-//--------------------------------------------------------
-// LLDynamicQueuePtrPtr implementation
-//--------------------------------------------------------
-
-
-template <class Type>
-inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size)
-{
- init();
- reallocate(size);
-}
-
-template <class Type>
-inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr()
-{
- destroy();
-}
-
-template <class Type>
-inline void LLDynamicQueuePtr<Type>::init()
-{
- mFirstObj = 0;
- mLastObj = 0;
- mMaxObj = 0;
- mMemory = NULL;
-}
-
-template <class Type>
-inline void LLDynamicQueuePtr<Type>::reallocate(U32 newsize)
-{
- if (newsize)
- {
- if (mFirstObj > mLastObj && newsize > mMaxObj)
- {
- Type* new_memory = new Type[newsize];
-
- llassert(new_memory);
-
- S32 _count = count();
- S32 i, m = 0;
- for (i=mFirstObj; i < mMaxObj; i++)
- {
- new_memory[m++] = mMemory[i];
- }
- for (i=0; i <=mLastObj; i++)
- {
- new_memory[m++] = mMemory[i];
- }
-
- delete[] mMemory;
- mMemory = new_memory;
-
- mFirstObj = 0;
- mLastObj = _count;
- }
- else
- {
- Type* new_memory = new Type[newsize];
-
- llassert(new_memory);
-
- S32 i, m = 0;
- for (i=0; i < mLastObj; i++)
- {
- new_memory[m++] = mMemory[i];
- }
- delete[] mMemory;
- mMemory = new_memory;
- }
- }
- else if (mMemory)
- {
- delete[] mMemory;
- mMemory = NULL;
- }
-
- mMaxObj = newsize;
-}
-
-template <class Type>
-inline void LLDynamicQueuePtr<Type>::destroy()
-{
- reset();
- delete[] mMemory;
- mMemory = NULL;
-}
-
-
-template <class Type>
-void LLDynamicQueuePtr<Type>::reset()
-{
- for (S32 i=0; i < mMaxObj; i++)
- {
- get(i) = NULL; // unrefs for pointers
- }
-
- mFirstObj = 0;
- mLastObj = 0;
-}
-
-
-template <class Type>
-inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const
-{
- S32 i;
- if (mFirstObj <= mLastObj)
- {
- for ( i = mFirstObj; i < mLastObj; i++ )
- {
- if (mMemory[i] == obj)
- {
- return i;
- }
- }
- }
- else
- {
- for ( i = mFirstObj; i < mMaxObj; i++ )
- {
- if (mMemory[i] == obj)
- {
- return i;
- }
- }
- for ( i = 0; i < mLastObj; i++ )
- {
- if (mMemory[i] == obj)
- {
- return i;
- }
- }
- }
-
- return FAIL;
-}
-
-template <class Type>
-inline S32 LLDynamicQueuePtr<Type>::remove(S32 i)
-{
- if (mFirstObj > mLastObj)
- {
- if (i >= mFirstObj && i < mMaxObj)
- {
- while( i > mFirstObj)
- {
- mMemory[i] = mMemory[i-1];
- i--;
- }
- mMemory[mFirstObj] = NULL;
- mFirstObj++;
- if (mFirstObj >= mMaxObj) mFirstObj = 0;
-
- return count();
- }
- else if (i < mLastObj && i >= 0)
- {
- while(i < mLastObj)
- {
- mMemory[i] = mMemory[i+1];
- i++;
- }
- mMemory[mLastObj] = NULL;
- mLastObj--;
- if (mLastObj < 0) mLastObj = mMaxObj-1;
-
- return count();
- }
- }
- else if (i <= mLastObj && i >= mFirstObj)
- {
- while(i < mLastObj)
- {
- mMemory[i] = mMemory[i+1];
- i++;
- }
- mMemory[mLastObj] = NULL;
- mLastObj--;
- if (mLastObj < 0) mLastObj = mMaxObj-1;
-
- return count();
- }
-
-
- return FAIL;
-}
-
-template <class Type>
-inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj)
-{
- S32 ind = find(obj);
- if (ind >= 0)
- {
- return remove(ind);
- }
- return FAIL;
-}
-
-template <class Type>
-inline S32 LLDynamicQueuePtr<Type>::push(const Type &obj)
-{
- if (mMaxObj - count() <= 1)
- {
- reallocate(mMaxObj * 2);
- }
-
- mMemory[mLastObj++] = obj;
-
- if (mLastObj >= mMaxObj)
- {
- mLastObj = 0;
- }
-
- return count();
-}
-
-template <class Type>
-inline S32 LLDynamicQueuePtr<Type>::pull(Type &obj)
-{
- obj = NULL;
-
- if (count() < 1) return -1;
-
- obj = mMemory[mFirstObj];
- mMemory[mFirstObj] = NULL;
-
- mFirstObj++;
-
- if (mFirstObj >= mMaxObj)
- {
- mFirstObj = 0;
- }
-
- return count();
-}
-
-template <class Type>
-inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const
-{
- return mMemory[i];
-}
-
-template <class Type>
-inline Type& LLDynamicQueuePtr<Type>::get(const S32 i)
-{
- return mMemory[i];
-}
-
-
-#endif // LL_LLDQUEUEPTR_H
diff --git a/indra/llcommon/llenum.h b/indra/llcommon/llenum.h
deleted file mode 100755
index f57b2bc0b5..0000000000
--- a/indra/llcommon/llenum.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file llenum.h
- * @author Tom Yedwab
- * @brief Utility class for storing enum value <-> string lookup.
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLENUM_H
-#define LL_LLENUM_H
-
-class LLEnum
-{
-public:
- typedef std::pair<const std::string, const U32> enum_t;
- enum
- {
- UNDEFINED = 0xffffffff,
- };
-
- LLEnum(const enum_t values_array[], const U32 length)
- {
- for (U32 i=0; i<length; ++i)
- {
- mEnumMap.insert(values_array[i]);
- if (values_array[i].second >= mEnumArray.size())
- {
- mEnumArray.resize(values_array[i].second+1);
- }
- mEnumArray[values_array[i].second] = values_array[i].first;
- }
- }
-
- U32 operator[](std::string str)
- {
- std::map<const std::string, const U32>::iterator itor;
- itor = mEnumMap.find(str);
- if (itor != mEnumMap.end())
- {
- return itor->second;
- }
- return UNDEFINED;
- }
-
- const std::string operator[](U32 index)
- {
- if (index < mEnumArray.size())
- {
- return mEnumArray[index];
- }
- return "";
- }
-
-private:
- std::map<const std::string, const U32> mEnumMap;
- std::vector<std::string> mEnumArray;
-};
-
-#endif // LL_LLENUM_H
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 37cee579cd..50c95339e4 100755
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
@@ -29,6 +29,7 @@
#define LL_LLERRORLEGACY_H
#include "llpreprocessor.h"
+#include <boost/static_assert.hpp>
/*
LEGACY -- DO NOT USE THIS STUFF ANYMORE
@@ -111,6 +112,14 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
#define llverify(func) do {if (func) {}} while(0)
#endif
+#ifdef LL_WINDOWS
+#define LL_STATIC_ASSERT(func, msg) static_assert(func, msg)
+#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg)
+#else
+#define LL_STATIC_ASSERT(func, msg) BOOST_STATIC_ASSERT(func)
+#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && false);
+#endif
+
// handy compile-time assert - enforce those template parameters!
#define cassert(expn) typedef char __C_ASSERT__[(expn)?1:-1] /* Flawfinder: ignore */
//XXX: used in two places in llcommon/llskipmap.h
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 0855180dcd..1c928b3db8 100755
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -41,7 +41,6 @@
#include <algorithm>
// std headers
#include <typeinfo>
-#include <cassert>
#include <cmath>
#include <cctype>
// external library headers
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 024fdd1b4d..60c451b137 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -32,8 +32,13 @@
#include "llsingleton.h"
#include "lltreeiterators.h"
#include "llsdserialize.h"
+#include "llunit.h"
+#include "llsd.h"
+#include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
#include <boost/bind.hpp>
+#include <queue>
#if LL_WINDOWS
@@ -49,37 +54,36 @@
#error "architecture not supported"
#endif
+namespace LLTrace
+{
+
//////////////////////////////////////////////////////////////////////////////
// statics
-S32 LLFastTimer::sCurFrameIndex = -1;
-S32 LLFastTimer::sLastFrameIndex = -1;
-U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64();
-bool LLFastTimer::sPauseHistory = 0;
-bool LLFastTimer::sResetHistory = 0;
-LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
-BOOL LLFastTimer::sLog = FALSE;
-std::string LLFastTimer::sLogName = "";
-BOOL LLFastTimer::sMetricLog = FALSE;
-LLMutex* LLFastTimer::sLogLock = NULL;
-std::queue<LLSD> LLFastTimer::sLogQueue;
+bool TimeBlock::sLog = false;
+std::string TimeBlock::sLogName = "";
+bool TimeBlock::sMetricLog = false;
#if LL_LINUX || LL_SOLARIS
-U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution
+U64 TimeBlock::sClockResolution = 1000000000; // Nanosecond resolution
#else
-U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
+U64 TimeBlock::sClockResolution = 1000000; // Microsecond resolution
#endif
+static LLMutex* sLogLock = NULL;
+static std::queue<LLSD> sLogQueue;
+
+
// FIXME: move these declarations to the relevant modules
// helper functions
-typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
+typedef LLTreeDFSPostIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_bottom_up_iterator_t;
-static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)
+static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(TimeBlock& id)
{
return timer_tree_bottom_up_iterator_t(&id,
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+ boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),
+ boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));
}
static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
@@ -87,14 +91,14 @@ static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()
return timer_tree_bottom_up_iterator_t();
}
-typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
+typedef LLTreeDFSIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_dfs_iterator_t;
-static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+static timer_tree_dfs_iterator_t begin_timer_tree(TimeBlock& id)
{
return timer_tree_dfs_iterator_t(&id,
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+ boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),
+ boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));
}
static timer_tree_dfs_iterator_t end_timer_tree()
@@ -102,90 +106,48 @@ static timer_tree_dfs_iterator_t end_timer_tree()
return timer_tree_dfs_iterator_t();
}
-// factory class that creates NamedTimers via static DeclareTimer objects
-class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
-{
-public:
- NamedTimerFactory()
- : mTimerRoot(NULL)
- {}
- /*virtual */ void initSingleton()
+// sort child timers by name
+struct SortTimerByName
+{
+ bool operator()(const TimeBlock* i1, const TimeBlock* i2)
{
- mTimerRoot = new LLFastTimer::NamedTimer("root");
- mRootFrameState.setNamedTimer(mTimerRoot);
- mTimerRoot->setFrameState(&mRootFrameState);
- mTimerRoot->mParent = mTimerRoot;
- mTimerRoot->setCollapsed(false);
- mRootFrameState.mParent = &mRootFrameState;
+ return i1->getName() < i2->getName();
}
+};
- ~NamedTimerFactory()
+TimeBlock& TimeBlock::getRootTimeBlock()
{
- std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
-
- delete mTimerRoot;
+ static TimeBlock root_timer("root", NULL);
+ return root_timer;
}
- LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state)
+void TimeBlock::pushLog(LLSD log)
{
- LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
- timer->setFrameState(state);
- timer->setParent(mTimerRoot);
- mTimers.insert(std::make_pair(name, timer));
+ LLMutexLock lock(sLogLock);
- return *timer;
+ sLogQueue.push(log);
}
- LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
+void TimeBlock::setLogLock(LLMutex* lock)
{
- timer_map_t::iterator found_it = mTimers.find(name);
- if (found_it != mTimers.end())
- {
- return found_it->second;
- }
- return NULL;
+ sLogLock = lock;
}
- LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
-
- typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t;
- timer_map_t::iterator beginTimers() { return mTimers.begin(); }
- timer_map_t::iterator endTimers() { return mTimers.end(); }
- S32 timerCount() { return mTimers.size(); }
-
-private:
- timer_map_t mTimers;
-
- LLFastTimer::NamedTimer* mTimerRoot;
- LLFastTimer::FrameState mRootFrameState;
-};
-
-LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
-: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
-{
- mTimer.setCollapsed(!open);
-}
-
-LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
-: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState))
-{
-}
//static
#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
-U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+U64 TimeBlock::countsPerSecond()
{
- return sClockResolution >> 8;
+ return sClockResolution;
}
#else // windows or x86-mac or x86-linux or x86-solaris
-U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+U64 TimeBlock::countsPerSecond()
{
#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS
//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
- static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0);
-
- // we drop the low-order byte in our timers, so report a lower frequency
+ static LLUnit<U64, LLUnits::Hertz> sCPUClockFrequency = LLProcessorInfo().getCPUFrequency();
+ return sCPUClockFrequency.value();
#else
// If we're not using RDTSC, each fasttimer tick is just a performance counter tick.
// Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency())
@@ -197,270 +159,207 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency);
firstcall = false;
}
+ return sCPUClockFrequency.value();
#endif
- return sCPUClockFrequency >> 8;
}
#endif
-LLFastTimer::FrameState::FrameState()
-: mActiveCount(0),
- mCalls(0),
- mSelfTimeCounter(0),
- mParent(NULL),
- mLastCaller(NULL),
- mMoveUpTree(false)
-{}
-
-
-LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
-: mName(name),
- mCollapsed(true),
- mParent(NULL),
- mTotalTimeCounter(0),
- mCountAverage(0),
- mCallAverage(0),
- mNeedsSorting(false),
- mFrameState(NULL)
+TimeBlock::TimeBlock(const char* name, TimeBlock* parent)
+: TraceType<TimeBlockAccumulator>(name)
{
- mCountHistory = new U32[HISTORY_NUM];
- memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
- mCallHistory = new U32[HISTORY_NUM];
- memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
}
-LLFastTimer::NamedTimer::~NamedTimer()
+TimeBlockTreeNode& TimeBlock::getTreeNode() const
{
- delete[] mCountHistory;
- delete[] mCallHistory;
+ TimeBlockTreeNode* nodep = LLTrace::get_thread_recorder()->getTimeBlockTreeNode(getIndex());
+ llassert(nodep);
+ return *nodep;
}
-std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
-{
- F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond();
- if (history_idx < 0)
- {
- // by default, show average number of call
- return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage());
- }
- else
- {
- return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx));
- }
-}
-void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
+void TimeBlock::bootstrapTimerTree()
{
- llassert_always(parent != this);
- llassert_always(parent != NULL);
-
- if (mParent)
- {
- // subtract our accumulated from previous parent
- for (S32 i = 0; i < HISTORY_NUM; i++)
+ for (LLInstanceTracker<TimeBlock>::instance_iter begin_it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(), it = begin_it;
+ it != end_it;
+ ++it)
{
- mParent->mCountHistory[i] -= mCountHistory[i];
- }
+ TimeBlock& timer = *it;
+ if (&timer == &TimeBlock::getRootTimeBlock()) continue;
- // subtract average timing from previous parent
- mParent->mCountAverage -= mCountAverage;
-
- std::vector<NamedTimer*>& children = mParent->getChildren();
- std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
- if (found_it != children.end())
+ // bootstrap tree construction by attaching to last timer to be on stack
+ // when this timer was called
+ if (timer.getParent() == &TimeBlock::getRootTimeBlock())
{
- children.erase(found_it);
- }
- }
+ TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
- mParent = parent;
- if (parent)
+ if (accumulator->mLastCaller)
{
- getFrameState().mParent = &parent->getFrameState();
- parent->getChildren().push_back(this);
- parent->mNeedsSorting = true;
+ 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;
}
-
-S32 LLFastTimer::NamedTimer::getDepth()
-{
- S32 depth = 0;
- NamedTimer* timerp = mParent;
- while(timerp)
- {
- depth++;
- if (timerp->getParent() == timerp) break;
- timerp = timerp->mParent;
}
- return depth;
-}
-
-// static
-void LLFastTimer::NamedTimer::processTimes()
-{
- if (sCurFrameIndex < 0) return;
-
- buildHierarchy();
- accumulateTimings();
}
-// sort child timers by name
-struct SortTimerByName
+// bump timers up tree if they have been flagged as being in the wrong place
+// do this in a bottom up order to promote descendants first before promoting ancestors
+// this preserves partial order derived from current frame's observations
+void TimeBlock::incrementalUpdateTimerTree()
{
- bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
+ for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(TimeBlock::getRootTimeBlock());
+ it != end_timer_tree_bottom_up();
+ ++it)
{
- return i1->getName() < i2->getName();
- }
-};
-
-//static
-void LLFastTimer::NamedTimer::buildHierarchy()
-{
- if (sCurFrameIndex < 0 ) return;
+ TimeBlock* timerp = *it;
- // set up initial tree
- {
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
- if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
-
- // bootstrap tree construction by attaching to last timer to be on stack
- // when this timer was called
- if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
+ // sort timers by time last called, so call graph makes sense
+ TimeBlockTreeNode& tree_node = timerp->getTreeNode();
+ if (tree_node.mNeedsSorting)
{
- timer.setParent(timer.getFrameState().mLastCaller->mTimer);
- // no need to push up tree on first use, flag can be set spuriously
- timer.getFrameState().mMoveUpTree = false;
- }
- }
+ std::sort(tree_node.mChildren.begin(), tree_node.mChildren.end(), SortTimerByName());
}
- // bump timers up tree if they've been flagged as being in the wrong place
- // do this in a bottom up order to promote descendants first before promoting ancestors
- // this preserves partial order derived from current frame's observations
- for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree_bottom_up();
- ++it)
- {
- NamedTimer* timerp = *it;
// skip root timer
- if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
+ if (timerp != &TimeBlock::getRootTimeBlock())
+ {
+ TimeBlockAccumulator* accumulator = timerp->getPrimaryAccumulator();
- if (timerp->getFrameState().mMoveUpTree)
+ if (accumulator->mMoveUpTree)
{
- // since ancestors have already been visited, reparenting won't affect tree traversal
+ // since ancestors have already been visited, re-parenting won't affect tree traversal
//step up tree, bringing our descendants with us
LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL;
timerp->setParent(timerp->getParent()->getParent());
- timerp->getFrameState().mMoveUpTree = false;
+ accumulator->mParent = timerp->getParent();
+ accumulator->mMoveUpTree = false;
// don't bubble up any ancestors until descendants are done bubbling up
+ // as ancestors may call this timer only on certain paths, so we want to resolve
+ // child-most block locations before their parents
it.skipAncestors();
}
}
+ }
+}
- // sort timers by time last called, so call graph makes sense
- for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree();
- ++it)
+
+void TimeBlock::updateTimes()
{
- NamedTimer* timerp = (*it);
- if (timerp->mNeedsSorting)
+ U64 cur_time = getCPUClockCount64();
+
+ // walk up stack of active timers and accumulate current time while leaving timing structures active
+ BlockTimerStackRecord* stack_record = ThreadTimerStack::getInstance();
+ BlockTimer* cur_timer = stack_record->mActiveTimer;
+ TimeBlockAccumulator* accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
+
+ while(cur_timer
+ && cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self
{
- std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
- }
- timerp->mNeedsSorting = false;
+ U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;
+ accumulator->mTotalTimeCounter += cumulative_time_delta
+ - (accumulator->mTotalTimeCounter
+ - cur_timer->mBlockStartTotalTimeCounter);
+ accumulator->mSelfTimeCounter += cumulative_time_delta - stack_record->mChildTime;
+ stack_record->mChildTime = 0;
+
+ cur_timer->mStartTime = cur_time;
+ cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
+
+ stack_record = &cur_timer->mParentTimerData;
+ accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
+ cur_timer = stack_record->mActiveTimer;
+
+ stack_record->mChildTime += cumulative_time_delta;
}
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_TIMES("Process FastTimer Times");
+
+// not thread safe, so only call on main thread
//static
-void LLFastTimer::NamedTimer::accumulateTimings()
+void TimeBlock::processTimes()
{
- U32 cur_time = getCPUClockCount32();
+ LLFastTimer _(FTM_PROCESS_TIMES);
+ get_clock_count(); // good place to calculate clock frequency
- // walk up stack of active timers and accumulate current time while leaving timing structures active
- LLFastTimer* cur_timer = sCurTimerData.mCurTimer;
- // root defined by parent pointing to self
- CurTimerData* cur_data = &sCurTimerData;
- while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)
- {
- U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
- U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
- cur_data->mChildTime = 0;
- cur_timer->mFrameState->mSelfTimeCounter += self_time_delta;
- cur_timer->mStartTime = cur_time;
+ // set up initial tree
+ bootstrapTimerTree();
- cur_data = &cur_timer->mLastTimerData;
- cur_data->mChildTime += cumulative_time_delta;
+ incrementalUpdateTimerTree();
- cur_timer = cur_timer->mLastTimerData.mCurTimer;
- }
+ updateTimes();
- // traverse tree in DFS post order, or bottom up
- for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
- it != end_timer_tree_bottom_up();
+ // reset for next frame
+ for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(),
+ end_it = LLInstanceTracker<TimeBlock>::endInstances();
+ it != end_it;
++it)
{
- NamedTimer* timerp = (*it);
- timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter;
- for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
+ TimeBlock& timer = *it;
+ TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
+
+ accumulator->mLastCaller = NULL;
+ accumulator->mMoveUpTree = false;
+ }
+}
+
+std::vector<TimeBlock*>::iterator TimeBlock::beginChildren()
{
- timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter;
+ return getTreeNode().mChildren.begin();
}
- S32 cur_frame = sCurFrameIndex;
- if (cur_frame >= 0)
+std::vector<TimeBlock*>::iterator TimeBlock::endChildren()
{
- // update timer history
- int hidx = cur_frame % HISTORY_NUM;
+ return getTreeNode().mChildren.end();
+}
- timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
- timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
- timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
- timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
- }
- }
+std::vector<TimeBlock*>& TimeBlock::getChildren()
+{
+ return getTreeNode().mChildren;
}
// static
-void LLFastTimer::NamedTimer::resetFrame()
+void TimeBlock::logStats()
{
+ // get ready for next frame
if (sLog)
{ //output current frame counts to performance log
static S32 call_count = 0;
if (call_count % 100 == 0)
{
- LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL;
- LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl;
+ LL_DEBUGS("FastTimers") << "countsPerSecond: " << countsPerSecond() << LL_ENDL;
LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL;
LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL;
LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL;
- LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL;
+ LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit<F64, LLUnits::Hertz>(LLProcessorInfo().getCPUFrequency())) << LL_ENDL;
}
call_count++;
- F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency
-
- F64 total_time = 0;
+ LLUnit<F64, LLUnits::Seconds> total_time(0);
LLSD sd;
{
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
+ for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(),
+ end_it = LLInstanceTracker<TimeBlock>::endInstances();
+ it != end_it;
+ ++it)
{
- NamedTimer& timer = *it;
- FrameState& info = timer.getFrameState();
- sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);
- sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
+ TimeBlock& timer = *it;
+ LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording();
+ sd[timer.getName()]["Time"] = (LLSD::Real) (frame_recording.getLastRecording().getSum(timer).value());
+ sd[timer.getName()]["Calls"] = (LLSD::Integer) (frame_recording.getLastRecording().getSum(timer.callCount()));
// computing total time here because getting the root timer's getCountHistory
// doesn't work correctly on the first frame
- total_time = total_time + info.mSelfTimeCounter * iclock_freq;
+ total_time += frame_recording.getLastRecording().getSum(timer);
}
}
- sd["Total"]["Time"] = (LLSD::Real) total_time;
+ sd["Total"]["Time"] = (LLSD::Real) total_time.value();
sd["Total"]["Calls"] = (LLSD::Integer) 1;
{
@@ -469,168 +368,44 @@ void LLFastTimer::NamedTimer::resetFrame()
}
}
- // reset for next frame
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
-
- FrameState& info = timer.getFrameState();
- info.mSelfTimeCounter = 0;
- info.mCalls = 0;
- info.mLastCaller = NULL;
- info.mMoveUpTree = false;
- // update parent pointer in timer state struct
- if (timer.mParent)
- {
- info.mParent = &timer.mParent->getFrameState();
- }
- }
}
//static
-void LLFastTimer::NamedTimer::reset()
-{
- resetFrame(); // reset frame data
-
- // walk up stack of active timers and reset start times to current time
- // effectively zeroing out any accumulated time
- U32 cur_time = getCPUClockCount32();
-
- // root defined by parent pointing to self
- CurTimerData* cur_data = &sCurTimerData;
- LLFastTimer* cur_timer = cur_data->mCurTimer;
- while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer)
- {
- cur_timer->mStartTime = cur_time;
- cur_data->mChildTime = 0;
-
- cur_data = &cur_timer->mLastTimerData;
- cur_timer = cur_data->mCurTimer;
- }
-
- // reset all history
+void TimeBlock::dumpCurTimes()
{
- for (instance_iter it = beginInstances(); it != endInstances(); ++it)
- {
- NamedTimer& timer = *it;
- if (&timer != NamedTimerFactory::instance().getRootTimer())
- {
- timer.setParent(NamedTimerFactory::instance().getRootTimer());
- }
-
- timer.mCountAverage = 0;
- timer.mCallAverage = 0;
- memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
- memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
- }
- }
-
- sLastFrameIndex = 0;
- sCurFrameIndex = 0;
-}
-
-U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
-{
- S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
- return mCountHistory[history_idx];
-}
-
-U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
-{
- S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
- return mCallHistory[history_idx];
-}
-
-LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
-{
- return *mFrameState;
-}
-
-std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
-{
- return mChildren.begin();
-}
-
-std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
-{
- return mChildren.end();
-}
-
-std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
-{
- return mChildren;
-}
-
-//static
-LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
-{
- return *NamedTimerFactory::instance().getRootTimer();
-}
-
-//static
-void LLFastTimer::nextFrame()
-{
- countsPerSecond(); // good place to calculate clock frequency
- U64 frame_time = getCPUClockCount64();
- if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff)
- {
- llinfos << "Slow frame, fast timers inaccurate" << llendl;
- }
-
- if (!sPauseHistory)
- {
- NamedTimer::processTimes();
- sLastFrameIndex = sCurFrameIndex++;
- }
-
- // get ready for next frame
- NamedTimer::resetFrame();
- sLastFrameTime = frame_time;
-}
-
-//static
-void LLFastTimer::dumpCurTimes()
-{
- // accumulate timings, etc.
- NamedTimer::processTimes();
-
- F64 clock_freq = (F64)countsPerSecond();
- F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
+ LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording();
+ LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();
// walk over timers in depth order and output timings
- for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+ for(timer_tree_dfs_iterator_t it = begin_timer_tree(TimeBlock::getRootTimeBlock());
it != end_timer_tree();
++it)
{
- NamedTimer* timerp = (*it);
- F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
+ TimeBlock* timerp = (*it);
+ LLUnit<F64, LLUnits::Seconds> total_time = last_frame_recording.getSum(*timerp);
+ U32 num_calls = last_frame_recording.getSum(timerp->callCount());
+
// Don't bother with really brief times, keep output concise
- if (total_time_ms < 0.1) continue;
+ if (total_time < LLUnit<F32, LLUnits::Milliseconds>(0.1)) continue;
std::ostringstream out_str;
- for (S32 i = 0; i < timerp->getDepth(); i++)
+ TimeBlock* parent_timerp = timerp;
+ while(parent_timerp && parent_timerp != parent_timerp->getParent())
{
out_str << "\t";
+ parent_timerp = parent_timerp->getParent();
}
-
out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms << " ms, "
- << timerp->getHistoricalCalls(0) << " calls";
+ << std::setprecision(3) << total_time.getAs<LLUnits::Milliseconds>() << " ms, "
+ << num_calls << " calls";
llinfos << out_str.str() << llendl;
}
}
//static
-void LLFastTimer::reset()
-{
- NamedTimer::reset();
-}
-
-
-//static
-void LLFastTimer::writeLog(std::ostream& os)
+void TimeBlock::writeLog(std::ostream& os)
{
while (!sLogQueue.empty())
{
@@ -641,22 +416,62 @@ void LLFastTimer::writeLog(std::ostream& os)
}
}
-//static
-const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TimeBlockAccumulator
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TimeBlockAccumulator::TimeBlockAccumulator()
+: mTotalTimeCounter(0),
+ mSelfTimeCounter(0),
+ mStartTotalTimeCounter(0),
+ mCalls(0),
+ mLastCaller(NULL),
+ mActiveCount(0),
+ mMoveUpTree(false),
+ mParent(NULL)
+{}
+
+void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other, bool append )
{
- return NamedTimerFactory::instance().getTimerByName(name);
+ // we can't merge two unrelated time block samples, as that will screw with the nested timings
+ // due to the call hierarchy of each thread
+ llassert(append);
+ mTotalTimeCounter += other.mTotalTimeCounter - other.mStartTotalTimeCounter;
+ mSelfTimeCounter += other.mSelfTimeCounter;
+ mCalls += other.mCalls;
+ mLastCaller = other.mLastCaller;
+ mActiveCount = other.mActiveCount;
+ mMoveUpTree = other.mMoveUpTree;
+ mParent = other.mParent;
}
-LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
-: mFrameState(state)
+void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )
{
- U32 start_time = getCPUClockCount32();
- mStartTime = start_time;
- mFrameState->mActiveCount++;
- LLFastTimer::sCurTimerData.mCurTimer = this;
- LLFastTimer::sCurTimerData.mFrameState = mFrameState;
- LLFastTimer::sCurTimerData.mChildTime = 0;
- mLastTimerData = LLFastTimer::sCurTimerData;
+ mCalls = 0;
+ mSelfTimeCounter = 0;
+
+ if (other)
+ {
+ mStartTotalTimeCounter = other->mTotalTimeCounter;
+ mTotalTimeCounter = mStartTotalTimeCounter;
+
+ mLastCaller = other->mLastCaller;
+ mActiveCount = other->mActiveCount;
+ mMoveUpTree = other->mMoveUpTree;
+ mParent = other->mParent;
+ }
+ else
+{
+ mStartTotalTimeCounter = mTotalTimeCounter;
+ }
+}
+
+LLUnit<F64, LLUnits::Seconds> BlockTimer::getElapsedTime()
+{
+ U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime;
+
+ return (F64)total_time / (F64)TimeBlock::countsPerSecond();
}
+} // namespace LLTrace
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 81c4b78775..642c99ccce 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -28,216 +28,96 @@
#define LL_FASTTIMER_H
#include "llinstancetracker.h"
+#include "lltrace.h"
#define FAST_TIMER_ON 1
-#define DEBUG_FAST_TIMER_THREADS 1
+#define LL_FASTTIMER_USE_RDTSC 1
class LLMutex;
-#include <queue>
-#include "llsd.h"
-
-#define LL_FASTTIMER_USE_RDTSC 1
-
+namespace LLTrace
+{
-LL_COMMON_API void assert_main_thread();
+struct BlockTimerStackRecord
+{
+ class BlockTimer* mActiveTimer;
+ class TimeBlock* mTimeBlock;
+ U64 mChildTime;
+};
-class LL_COMMON_API LLFastTimer
+class ThreadTimerStack
+: public BlockTimerStackRecord,
+ public LLThreadLocalSingleton<ThreadTimerStack>
{
-public:
- class NamedTimer;
+ friend class LLThreadLocalSingleton<ThreadTimerStack>;
+ ThreadTimerStack()
+ {}
- struct LL_COMMON_API FrameState
- {
- FrameState();
- void setNamedTimer(NamedTimer* timerp) { mTimer = timerp; }
-
- U32 mSelfTimeCounter;
- U32 mCalls;
- FrameState* mParent; // info for caller timer
- FrameState* mLastCaller; // used to bootstrap tree construction
- NamedTimer* mTimer;
- U16 mActiveCount; // number of timers with this ID active on stack
- bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
- };
-
- // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
- class LL_COMMON_API NamedTimer
- : public LLInstanceTracker<NamedTimer>
+public:
+ ThreadTimerStack& operator=(const BlockTimerStackRecord& other)
{
- friend class DeclareTimer;
- public:
- ~NamedTimer();
-
- enum { HISTORY_NUM = 300 };
-
- const std::string& getName() const { return mName; }
- NamedTimer* getParent() const { return mParent; }
- void setParent(NamedTimer* parent);
- S32 getDepth();
- std::string getToolTip(S32 history_index = -1);
-
- typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
- child_const_iter beginChildren();
- child_const_iter endChildren();
- std::vector<NamedTimer*>& getChildren();
-
- void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
- bool getCollapsed() const { return mCollapsed; }
-
- U32 getCountAverage() const { return mCountAverage; }
- U32 getCallAverage() const { return mCallAverage; }
-
- U32 getHistoricalCount(S32 history_index = 0) const;
- U32 getHistoricalCalls(S32 history_index = 0) const;
-
- static NamedTimer& getRootNamedTimer();
-
- void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }
- FrameState& getFrameState() const;
-
- private:
- friend class LLFastTimer;
- friend class NamedTimerFactory;
-
- //
- // methods
- //
- NamedTimer(const std::string& name);
- // recursive call to gather total time from children
- static void accumulateTimings();
-
- // updates cumulative times and hierarchy,
- // can be called multiple times in a frame, at any point
- static void processTimes();
-
- static void buildHierarchy();
- static void resetFrame();
- static void reset();
-
- //
- // members
- //
- FrameState* mFrameState;
-
- std::string mName;
+ BlockTimerStackRecord::operator=(other);
+ return *this;
+ }
+};
- U32 mTotalTimeCounter;
+class BlockTimer
+{
+public:
+ friend class TimeBlock;
+ typedef BlockTimer self_t;
+ typedef class TimeBlock DeclareTimer;
- U32 mCountAverage;
- U32 mCallAverage;
+ BlockTimer(TimeBlock& timer);
+ ~BlockTimer();
- U32* mCountHistory;
- U32* mCallHistory;
+ LLUnit<F64, LLUnits::Seconds> getElapsedTime();
- // tree structure
- NamedTimer* mParent; // NamedTimer of caller(parent)
- std::vector<NamedTimer*> mChildren;
- bool mCollapsed; // don't show children
- bool mNeedsSorting; // sort children whenever child added
- };
+private:
- // used to statically declare a new named timer
- class LL_COMMON_API DeclareTimer
- : public LLInstanceTracker<DeclareTimer>
- {
- friend class LLFastTimer;
- public:
- DeclareTimer(const std::string& name, bool open);
- DeclareTimer(const std::string& name);
+ U64 mStartTime;
+ U64 mBlockStartTotalTimeCounter;
+ BlockTimerStackRecord mParentTimerData;
+};
- NamedTimer& getNamedTimer() { return mTimer; }
+// stores a "named" timer instance to be reused via multiple BlockTimer stack instances
+class TimeBlock
+: public TraceType<TimeBlockAccumulator>,
+ public LLInstanceTracker<TimeBlock>
+{
+public:
+ TimeBlock(const char* name, TimeBlock* parent = &getRootTimeBlock());
- private:
- FrameState mFrameState;
- NamedTimer& mTimer;
- };
+ TimeBlockTreeNode& getTreeNode() const;
+ TimeBlock* getParent() const { return getTreeNode().getParent(); }
+ void setParent(TimeBlock* parent) { getTreeNode().setParent(parent); }
-public:
- LLFastTimer(LLFastTimer::FrameState* state);
+ typedef std::vector<TimeBlock*>::iterator child_iter;
+ typedef std::vector<TimeBlock*>::const_iterator child_const_iter;
+ child_iter beginChildren();
+ child_iter endChildren();
+ std::vector<TimeBlock*>& getChildren();
- LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
- : mFrameState(&timer.mFrameState)
+ TraceType<TimeBlockAccumulator::CallCountFacet>& callCount()
{
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- mStartTime = getCPUClockCount32();
-
- frame_state->mActiveCount++;
- frame_state->mCalls++;
- // keep current parent as long as it is active when we are
- frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
-
- LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
- mLastTimerData = *cur_timer_data;
- cur_timer_data->mCurTimer = this;
- cur_timer_data->mFrameState = frame_state;
- cur_timer_data->mChildTime = 0;
-#endif
-#if DEBUG_FAST_TIMER_THREADS
-#if !LL_RELEASE
- assert_main_thread();
-#endif
-#endif
+ return static_cast<TraceType<TimeBlockAccumulator::CallCountFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);
}
- LL_FORCE_INLINE ~LLFastTimer()
+ TraceType<TimeBlockAccumulator::SelfTimeFacet>& selfTime()
{
-#if FAST_TIMER_ON
- LLFastTimer::FrameState* frame_state = mFrameState;
- U32 total_time = getCPUClockCount32() - mStartTime;
-
- frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
- frame_state->mActiveCount--;
-
- // store last caller to bootstrap tree creation
- // do this in the destructor in case of recursion to get topmost caller
- frame_state->mLastCaller = mLastTimerData.mFrameState;
-
- // we are only tracking self time, so subtract our total time delta from parents
- mLastTimerData.mChildTime += total_time;
-
- LLFastTimer::sCurTimerData = mLastTimerData;
-#endif
+ return static_cast<TraceType<TimeBlockAccumulator::SelfTimeFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);
}
-public:
- static LLMutex* sLogLock;
- static std::queue<LLSD> sLogQueue;
- static BOOL sLog;
- static BOOL sMetricLog;
- static std::string sLogName;
- static bool sPauseHistory;
- static bool sResetHistory;
-
- // call this once a frame to reset timers
- static void nextFrame();
+ static TimeBlock& getRootTimeBlock();
+ static void pushLog(LLSD sd);
+ static void setLogLock(LLMutex* mutex);
+ static void writeLog(std::ostream& os);
+ static void updateTimes();
// dumps current cumulative frame stats to log
// call nextFrame() to reset timers
static void dumpCurTimes();
- // call this to reset timer hierarchy, averages, etc.
- static void reset();
-
- static U64 countsPerSecond();
- static S32 getLastFrameIndex() { return sLastFrameIndex; }
- static S32 getCurFrameIndex() { return sCurFrameIndex; }
-
- static void writeLog(std::ostream& os);
- static const NamedTimer* getTimerByName(const std::string& name);
-
- struct CurTimerData
- {
- LLFastTimer* mCurTimer;
- FrameState* mFrameState;
- U32 mChildTime;
- };
- static CurTimerData sCurTimerData;
-
-private:
-
-
//////////////////////////////////////////////////////////////////////////////
//
// Important note: These implementations must be FAST!
@@ -260,14 +140,14 @@ private:
//#undef _interlockedbittestandset
//#undef _interlockedbittestandreset
- //inline U32 LLFastTimer::getCPUClockCount32()
+ //inline U32 TimeBlock::getCPUClockCount32()
//{
// U64 time_stamp = __rdtsc();
// return (U32)(time_stamp >> 8);
//}
//
//// return full timer value, *not* shifted by 8 bits
- //inline U64 LLFastTimer::getCPUClockCount64()
+ //inline U64 TimeBlock::getCPUClockCount64()
//{
// return __rdtsc();
//}
@@ -307,7 +187,7 @@ private:
}
#else
- //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
+ //U64 get_clock_count(); // in lltimer.cpp
// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.
static U32 getCPUClockCount32()
{
@@ -374,18 +254,74 @@ private:
#endif
- static U64 sClockResolution;
+ static U64 countsPerSecond();
+
+ // updates cumulative times and hierarchy,
+ // can be called multiple times in a frame, at any point
+ static void processTimes();
+
+ static void bootstrapTimerTree();
+ static void incrementalUpdateTimerTree();
- static S32 sCurFrameIndex;
- static S32 sLastFrameIndex;
- static U64 sLastFrameTime;
+ // call this once a frame to periodically log timers
+ static void logStats();
- U32 mStartTime;
- LLFastTimer::FrameState* mFrameState;
- LLFastTimer::CurTimerData mLastTimerData;
+ bool mCollapsed; // don't show children
+ // statics
+ static std::string sLogName;
+ static bool sMetricLog,
+ sLog;
+ static U64 sClockResolution;
};
-typedef class LLFastTimer LLFastTimer;
+LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
+{
+#if FAST_TIMER_ON
+ BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();
+ TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
+ accumulator->mActiveCount++;
+ mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
+ // keep current parent as long as it is active when we are
+ accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0);
+
+ // store top of stack
+ mParentTimerData = *cur_timer_data;
+ // push new information
+ cur_timer_data->mActiveTimer = this;
+ cur_timer_data->mTimeBlock = &timer;
+ cur_timer_data->mChildTime = 0;
+
+ mStartTime = TimeBlock::getCPUClockCount64();
+#endif
+}
+
+LL_FORCE_INLINE BlockTimer::~BlockTimer()
+{
+#if FAST_TIMER_ON
+ U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime;
+ BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();
+ TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator();
+
+ accumulator->mCalls++;
+ accumulator->mTotalTimeCounter += total_time - (accumulator->mTotalTimeCounter - mBlockStartTotalTimeCounter);
+ accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime;
+ accumulator->mActiveCount--;
+
+ // store last caller to bootstrap tree creation
+ // do this in the destructor in case of recursion to get topmost caller
+ accumulator->mLastCaller = mParentTimerData.mTimeBlock;
+
+ // we are only tracking self time, so subtract our total time delta from parents
+ mParentTimerData.mChildTime += total_time;
+
+ //pop stack
+ *cur_timer_data = mParentTimerData;
+#endif
+}
+
+}
+
+typedef LLTrace::BlockTimer LLFastTimer;
#endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c3a0f0bfe0..06bc931dea 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -28,7 +28,7 @@
*/
#if LL_WINDOWS
-#include <windows.h>
+#include "llwin32headerslean.h"
#include <stdlib.h> // Windows errno
#else
#include <errno.h>
@@ -438,7 +438,7 @@ llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __
_M_set_buffer(0);
__ret = traits_type::not_eof(__c);
}
- }
+ }
else if (_M_buf_size > 1)
{
// Overflow in 'uncommitted' mode: set _M_writing, set
@@ -496,11 +496,11 @@ bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
__blen = __bend - __buf;
else if (__r == codecvt_base::noconv)
- {
+ {
// Same as the always_noconv case above.
__buf = reinterpret_cast<char*>(__ibuf);
__blen = __ilen;
- }
+ }
else
__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
"conversion error"));
@@ -643,9 +643,9 @@ llstdio_filebuf::int_type llstdio_filebuf::underflow()
_M_ext_end, _M_ext_next,
this->eback(),
this->eback() + __buflen, __iend);
-}
+ }
if (__r == codecvt_base::noconv)
-{
+ {
size_t __avail = _M_ext_end - _M_ext_buf;
__ilen = std::min(__avail, __buflen);
traits_type::copy(this->eback(),
@@ -806,15 +806,15 @@ std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
__ret = fwrite(__buf, 1, __buffill, _M_file.file());
}
if (__ret == __buffill)
- {
+ {
__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
__n, _M_file.file());
- }
+ }
if (__ret == __buffill + __n)
{
_M_set_buffer(0);
_M_writing = true;
-}
+ }
if (__ret > __buffill)
__ret -= __buffill;
else
@@ -848,7 +848,7 @@ llifstream::llifstream() : _M_filebuf(),
#endif
// explicit
-llifstream::llifstream(const std::string& _Filename,
+llifstream::llifstream(const std::string& _Filename,
ios_base::openmode _Mode) : _M_filebuf(),
#if LL_WINDOWS
std::istream(&_M_filebuf)
@@ -877,7 +877,7 @@ llifstream::llifstream(const char* _Filename,
if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
-}
+ }
}
#else
std::istream()
@@ -951,8 +951,8 @@ void llifstream::close()
#else
this->setstate(ios_base::failbit);
#endif
- }
}
+}
/************** output file stream ********************************/
@@ -1042,7 +1042,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
#if LL_WINDOWS
llutf16string wideName = utf8str_to_utf16str( _Filename );
if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
-{
+ {
_Myios::setstate(ios_base::failbit);
}
else
diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp
index cd7c0c7c09..f019bd0c64 100755
--- a/indra/llcommon/llfindlocale.cpp
+++ b/indra/llcommon/llfindlocale.cpp
@@ -33,7 +33,7 @@
#include <ctype.h>
#ifdef WIN32
-#include <windows.h>
+#include "llwin32headers.h"
#include <winnt.h>
#endif
diff --git a/indra/llcommon/llindexedqueue.h b/indra/llcommon/llindexedqueue.h
deleted file mode 100755
index aa2675d87d..0000000000
--- a/indra/llcommon/llindexedqueue.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * @file llindexedqueue.h
- * @brief An indexed FIFO queue, where only one element with each key
- * can be in the queue.
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLINDEXEDQUEUE_H
-#define LL_LLINDEXEDQUEUE_H
-
-// An indexed FIFO queue, where only one element with each key can be in the queue.
-// This is ONLY used in the interest list, you'll probably want to review this code
-// carefully if you want to use it elsewhere - Doug
-
-template <typename Type>
-class LLIndexedQueue
-{
-protected:
- typedef std::deque<Type> type_deque;
- type_deque mQueue;
- std::set<Type> mKeySet;
-
-public:
- LLIndexedQueue() {}
-
- // move_if_there is an O(n) operation
- bool push_back(const Type &value, bool move_if_there = false)
- {
- if (mKeySet.find(value) != mKeySet.end())
- {
- // Already on the queue
- if (move_if_there)
- {
- // Remove the existing entry.
- typename type_deque::iterator it;
- for (it = mQueue.begin(); it != mQueue.end(); ++it)
- {
- if (*it == value)
- {
- break;
- }
- }
-
- // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
- // (although this isn't thread safe, at all)
-
- mQueue.erase(it);
- }
- else
- {
- // We're not moving it, leave it alone
- return false;
- }
- }
- else
- {
- // Doesn't exist, add it to the key set
- mKeySet.insert(value);
- }
-
- mQueue.push_back(value);
-
- // We succeeded in adding the new element.
- return true;
- }
-
- bool push_front(const Type &value, bool move_if_there = false)
- {
- if (mKeySet.find(value) != mKeySet.end())
- {
- // Already on the queue
- if (move_if_there)
- {
- // Remove the existing entry.
- typename type_deque::iterator it;
- for (it = mQueue.begin(); it != mQueue.end(); ++it)
- {
- if (*it == value)
- {
- break;
- }
- }
-
- // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
- // (although this isn't thread safe, at all)
-
- mQueue.erase(it);
- }
- else
- {
- // We're not moving it, leave it alone
- return false;
- }
- }
- else
- {
- // Doesn't exist, add it to the key set
- mKeySet.insert(value);
- }
-
- mQueue.push_front(value);
- return true;
- }
-
- void pop()
- {
- Type value = mQueue.front();
- mKeySet.erase(value);
- mQueue.pop_front();
- }
-
- Type &front()
- {
- return mQueue.front();
- }
-
- S32 size() const
- {
- return mQueue.size();
- }
-
- bool empty() const
- {
- return mQueue.empty();
- }
-
- void clear()
- {
- // Clear out all elements on the queue
- mQueue.clear();
- mKeySet.clear();
- }
-};
-
-#endif // LL_LLINDEXEDQUEUE_H
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index 89c831d296..dbd4eba7a0 100755
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -28,10 +28,17 @@
#include "linden_common.h"
#include "llinitparam.h"
+#include "llformat.h"
namespace LLInitParam
{
+
+ predicate_rule_t default_parse_rules()
+ {
+ return ll_make_predicate(PROVIDED) && !ll_make_predicate(EMPTY);
+ }
+
//
// Param
//
@@ -196,6 +203,9 @@ namespace LLInitParam
bool BaseBlock::validateBlock(bool emit_errors) const
{
+ // only validate block when it hasn't already passed validation with current data
+ if (!mValidated)
+ {
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
{
@@ -209,11 +219,18 @@ namespace LLInitParam
return false;
}
}
- return true;
+ mValidated = true;
+ }
+ return mValidated;
}
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
+ bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const LLInitParam::BaseBlock* diff_block) const
{
+ bool serialized = false;
+ if (!predicate_rule.check(ll_make_predicate(PROVIDED, isProvided())))
+ {
+ return false;
+ }
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
@@ -225,10 +242,10 @@ namespace LLInitParam
param_handle_t param_handle = (*it)->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
- if (serialize_func)
+ if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
{
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- serialize_func(*param, parser, name_stack, diff_param);
+ serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
}
}
@@ -239,7 +256,7 @@ namespace LLInitParam
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
- if (serialize_func && param->anyProvided())
+ if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
{
// Ensure this param has not already been serialized
// Prevents <rect> from being serialized as its own tag.
@@ -264,10 +281,17 @@ namespace LLInitParam
name_stack.push_back(std::make_pair(it->first, !duplicate));
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- serialize_func(*param, parser, name_stack, diff_param);
+ serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
name_stack.pop_back();
}
}
+
+ if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY)))
+ {
+ serialized |= parser.writeValue(Flag(), name_stack);
+ }
+ // was anything serialized in this block?
+ return serialized;
}
bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index ae836645b9..879ea4fe2a 100755
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -29,14 +29,15 @@
#define LL_LLPARAM_H
#include <vector>
+#include <list>
#include <boost/function.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/unordered_map.hpp>
-#include <boost/shared_ptr.hpp>
#include "llerror.h"
#include "llstl.h"
+#include "llpredicate.h"
namespace LLTypeTags
{
@@ -195,6 +196,8 @@ namespace LLInitParam
return mValue;
}
+ bool isValid() const { return true; }
+
protected:
T mValue;
};
@@ -209,13 +212,11 @@ namespace LLInitParam
typedef T value_t;
ParamValue()
- : T(),
- mValidated(false)
+ : T()
{}
ParamValue(const default_value_t& other)
- : T(other),
- mValidated(false)
+ : T(other)
{}
void setValue(const value_t& val)
@@ -232,9 +233,6 @@ namespace LLInitParam
{
return *this;
}
-
- protected:
- mutable bool mValidated; // lazy validation flag
};
@@ -497,25 +495,25 @@ namespace LLInitParam
virtual ~Parser();
template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)
- {
+ {
parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
if (found_it != mParserReadFuncs->end())
- {
+ {
return found_it->second(*this, (void*)&param);
- }
-
- return false;
}
+ return false;
+ }
+
template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)
- {
+ {
parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
if (found_it != mParserReadFuncs->end())
- {
+ {
return found_it->second(*this, (void*)&param);
- }
+ }
else
- {
+ {
found_it = mParserReadFuncs->find(&typeid(S32));
if (found_it != mParserReadFuncs->end())
{
@@ -579,6 +577,19 @@ namespace LLInitParam
class Param;
+ enum ESerializePredicates
+ {
+ PROVIDED,
+ REQUIRED,
+ VALID,
+ HAS_DEFAULT_VALUE,
+ EMPTY
+ };
+
+ typedef LLPredicate::Rule<ESerializePredicates> predicate_rule_t;
+
+ predicate_rule_t default_parse_rules();
+
// various callbacks and constraints associated with an individual param
struct LL_COMMON_API ParamDescriptor
{
@@ -589,7 +600,7 @@ namespace LLInitParam
typedef bool(*merge_func_t)(Param&, const Param&, bool);
typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
- typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
+ typedef bool(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const predicate_rule_t rules, const Param* diff_param);
typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
typedef bool(*validation_func_t)(const Param*);
@@ -617,7 +628,7 @@ namespace LLInitParam
UserData* mUserData;
};
- typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
+ typedef ParamDescriptor* ParamDescriptorPtr;
// each derived Block class keeps a static data structure maintaining offsets to various params
class LL_COMMON_API BlockDescriptor
@@ -829,12 +840,28 @@ namespace LLInitParam
LOG_CLASS(BaseBlock);
friend class Param;
+ BaseBlock()
+ : mValidated(false),
+ mParamProvided(false)
+ {}
+
virtual ~BaseBlock() {}
bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
param_handle_t getHandleFromParam(const Param* param) const;
bool validateBlock(bool emit_errors = true) const;
+ bool isProvided() const
+ {
+ return mParamProvided;
+ }
+
+ bool isValid() const
+ {
+ return validateBlock(false);
+ }
+
+
Param* getParamFromHandle(const param_handle_t param_handle)
{
if (param_handle == 0) return NULL;
@@ -852,10 +879,19 @@ namespace LLInitParam
void addSynonym(Param& param, const std::string& synonym);
// Blocks can override this to do custom tracking of changes
- virtual void paramChanged(const Param& changed_param, bool user_provided) {}
+ virtual void paramChanged(const Param& changed_param, bool user_provided)
+ {
+ if (user_provided)
+ {
+ // a child param has been explicitly changed
+ // so *some* aspect of this block is now provided
+ mValidated = false;
+ mParamProvided = true;
+ }
+ }
bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
@@ -893,6 +929,9 @@ namespace LLInitParam
return mergeBlock(block_data, source, overwrite);
}
+ mutable bool mValidated; // lazy validation flag
+ bool mParamProvided;
+
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
@@ -986,6 +1025,8 @@ namespace LLInitParam
bool isProvided() const { return Param::anyProvided(); }
+ bool isValid() const { return true; }
+
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
@@ -1014,10 +1055,23 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
+ bool serialized = false;
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+ const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
+
+ LLPredicate::Value<ESerializePredicates> predicate;
+ if (diff_typed_param && ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
+ {
+ predicate.set(HAS_DEFAULT_VALUE);
+ }
+
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
+ predicate.set(EMPTY, false);
+
+ if (!predicate_rule.check(predicate)) return false;
if (!name_stack.empty())
{
@@ -1030,25 +1084,27 @@ namespace LLInitParam
if (!key.empty())
{
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
+ if (!diff_typed_param || !ParamCompare<std::string>::equals(diff_typed_param->getValueName(), key))
{
- parser.writeValue(key, name_stack);
+ serialized = parser.writeValue(key, name_stack);
}
}
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
+ else if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
{
- if (!parser.writeValue(typed_param.getValue(), name_stack))
+ serialized = parser.writeValue(typed_param.getValue(), name_stack);
+ if (!serialized)
{
std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
if (calculated_key.size()
- && (!diff_param
+ && (!diff_typed_param
|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
{
- parser.writeValue(calculated_key, name_stack);
+ serialized = parser.writeValue(calculated_key, name_stack);
}
}
}
+ return serialized;
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
@@ -1113,19 +1169,19 @@ namespace LLInitParam
};
// parameter that is a block
- template <typename T, typename NAME_VALUE_LOOKUP>
- class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
+ template <typename BLOCK_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
: public Param,
public NAME_VALUE_LOOKUP::type_value_t
{
protected:
- typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
- typedef typename param_value_t::default_value_t default_value_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
- typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<BLOCK_T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
public:
using named_value_t::operator();
- typedef typename param_value_t::value_t value_t;
+ typedef typename param_value_t::value_t value_t;
TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr),
@@ -1148,11 +1204,11 @@ namespace LLInitParam
if(named_value_t::valueNamesExist()
&& parser.readValue(name)
&& named_value_t::getValueFromName(name, typed_param.getValue()))
- {
- typed_param.setValueName(name);
- typed_param.setProvided();
- return true;
- }
+ {
+ typed_param.setValueName(name);
+ typed_param.setProvided();
+ return true;
+ }
}
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
@@ -1166,10 +1222,16 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+
+ LLPredicate::Value<ESerializePredicates> predicate;
+
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
+
+ if (!predicate_rule.check(predicate)) return false;
if (!name_stack.empty())
{
@@ -1182,12 +1244,15 @@ namespace LLInitParam
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
{
parser.writeValue(key, name_stack);
+ return true;
}
}
else
{
- typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+ return typed_param.serializeBlock(parser, name_stack, predicate_rule, static_cast<const self_t*>(diff_param));
}
+
+ return false;
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
@@ -1209,13 +1274,12 @@ namespace LLInitParam
// *and* the block as a whole validates
bool isProvided() const
{
- // only validate block when it hasn't already passed validation with current data
- if (Param::anyProvided() && !param_value_t::mValidated)
- {
- // a sub-block is "provided" when it has been filled in enough to be valid
- param_value_t::mValidated = param_value_t::validateBlock(false);
- }
- return Param::anyProvided() && param_value_t::mValidated;
+ return Param::anyProvided() && isValid();
+ }
+
+ bool isValid() const
+ {
+ return param_value_t::isValid();
}
// assign block contents to this param-that-is-a-block
@@ -1223,9 +1287,6 @@ namespace LLInitParam
{
setValue(val);
named_value_t::clearValueName();
- // force revalidation of block
- // next call to isProvided() will update provision status based on validity
- param_value_t::mValidated = false;
setProvided(flag_as_provided);
}
@@ -1242,9 +1303,6 @@ namespace LLInitParam
if (user_provided)
{
- // a child param has been explicitly changed
- // so *some* aspect of this block is now provided
- param_value_t::mValidated = false;
setProvided();
named_value_t::clearValueName();
}
@@ -1296,13 +1354,13 @@ namespace LLInitParam
};
// list of non-block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
+ template <typename MULTI_VALUE_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
: public Param
{
protected:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
- typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<MULTI_VALUE_T>::value_t> param_value_t;
typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
typedef container_t default_value_t;
typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
@@ -1311,7 +1369,9 @@ namespace LLInitParam
typedef typename param_value_t::value_t value_t;
TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mMinCount(min_count),
+ mMaxCount(max_count)
{
std::copy(value.begin(), value.end(), std::back_inserter(mValues));
@@ -1322,7 +1382,13 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::anyProvided(); }
+ bool isProvided() const { return Param::anyProvided() && isValid(); }
+
+ bool isValid() const
+ {
+ size_t num_elements = numValidElements();
+ return mMinCount < num_elements && num_elements < mMaxCount;
+ }
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
@@ -1337,7 +1403,7 @@ namespace LLInitParam
}
// no further names in stack, attempt to parse value now
- if (name_stack_range.first == name_stack_range.second)
+ if (new_name_stack_range.first == new_name_stack_range.second)
{
std::string name;
@@ -1359,10 +1425,19 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
+ bool serialized = false;
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+
+ LLPredicate::Value<ESerializePredicates> predicate;
+
+ predicate.set(REQUIRED, typed_param.mMinCount > 0);
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
+ predicate.set(EMPTY, typed_param.mValues.empty());
+
+ if (!predicate_rule.check(predicate)) return false;
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
it != end_it;
@@ -1378,7 +1453,11 @@ namespace LLInitParam
if (!value_written)
{
std::string calculated_key = it->calcValueName(it->getValue());
- if (!parser.writeValue(calculated_key, name_stack))
+ if (parser.writeValue(calculated_key, name_stack))
+ {
+ serialized = true;
+ }
+ else
{
break;
}
@@ -1386,19 +1465,23 @@ namespace LLInitParam
}
else
{
- if(!parser.writeValue(key, name_stack))
+ if(parser.writeValue(key, name_stack))
+ {
+ serialized = true;
+ }
+ else
{
break;
}
}
-
- name_stack.pop_back();
}
+
+ return serialized;
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
+ parser.inspectValue<MULTI_VALUE_T>(name_stack, min_count, max_count, NULL);
if (named_value_t::getPossibleValues())
{
parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
@@ -1453,7 +1536,7 @@ namespace LLInitParam
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
- U32 numValidElements() const
+ size_t numValidElements() const
{
return mValues.size();
}
@@ -1483,6 +1566,8 @@ namespace LLInitParam
}
container_t mValues;
+ size_t mMinCount,
+ mMaxCount;
private:
void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
@@ -1500,13 +1585,13 @@ namespace LLInitParam
};
// list of block parameters
- template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
+ template <typename MULTI_BLOCK_T, typename NAME_VALUE_LOOKUP>
+ class TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
: public Param
{
protected:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
- typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<MULTI_BLOCK_T>::value_t> param_value_t;
typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
typedef container_t default_value_t;
@@ -1516,7 +1601,9 @@ namespace LLInitParam
typedef typename param_value_t::value_t value_t;
TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mMinCount(min_count),
+ mMaxCount(max_count)
{
std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1526,7 +1613,14 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::anyProvided(); }
+ bool isProvided() const { return Param::anyProvided() && isValid(); }
+
+ bool isValid() const
+ {
+ size_t num_elements = numValidElements();
+ return mMinCount < num_elements && num_elements < mMaxCount;
+ }
+
static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
{
@@ -1549,7 +1643,7 @@ namespace LLInitParam
}
param_value_t& value = typed_param.mValues.back();
- if (name_stack_range.first == name_stack_range.second)
+ if (new_name_stack_range.first == new_name_stack_range.second)
{ // try to parse a known named value
std::string name;
@@ -1559,6 +1653,10 @@ namespace LLInitParam
{
typed_param.mValues.back().setValueName(name);
typed_param.setProvided();
+ if (new_array_value)
+ {
+ name_stack_range.first->second = false;
+ }
return true;
}
}
@@ -1583,10 +1681,18 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
+ bool serialized = false;
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+ LLPredicate::Value<ESerializePredicates> predicate;
+
+ predicate.set(REQUIRED, typed_param.mMinCount > 0);
+ predicate.set(VALID, typed_param.isValid());
+ predicate.set(PROVIDED, typed_param.anyProvided());
+ predicate.set(EMPTY, typed_param.mValues.empty());
+
+ if (!predicate_rule.check(predicate)) return false;
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
it != end_it;
@@ -1597,17 +1703,24 @@ namespace LLInitParam
std::string key = it->getValueName();
if (!key.empty())
{
- parser.writeValue(key, name_stack);
+ serialized |= parser.writeValue(key, name_stack);
}
// Not parsed via named values, write out value directly
- // NOTE: currently we don't worry about removing default values in Multiple
+ // NOTE: currently we don't do diffing of Multiples
else
{
- it->serializeBlock(parser, name_stack, NULL);
+ serialized = it->serializeBlock(parser, name_stack, predicate_rule, NULL);
}
name_stack.pop_back();
}
+
+ if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY)))
+ {
+ serialized |= parser.writeValue(Flag(), name_stack);
+ }
+
+ return serialized;
}
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
@@ -1670,14 +1783,14 @@ namespace LLInitParam
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
- U32 numValidElements() const
+ size_t numValidElements() const
{
- U32 count = 0;
+ size_t count = 0;
for (const_iterator it = mValues.begin(), end_it = mValues.end();
it != end_it;
++it)
{
- if(it->validateBlock(false)) count++;
+ if(it->isValid()) count++;
}
return count;
}
@@ -1709,6 +1822,8 @@ namespace LLInitParam
}
container_t mValues;
+ size_t mMinCount,
+ mMaxCount;
private:
void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
@@ -2015,7 +2130,7 @@ namespace LLInitParam
static bool validate(const Param* paramp)
{
- U32 num_valid = ((super_t*)paramp)->numValidElements();
+ size_t num_valid = ((super_t*)paramp)->numValidElements();
return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
}
};
@@ -2158,13 +2273,11 @@ namespace LLInitParam
typedef T default_value_t;
ParamValue()
- : mValue(),
- mValidated(false)
+ : mValue()
{}
ParamValue(const default_value_t& value)
- : mValue(value),
- mValidated(false)
+ : mValue(value)
{}
void setValue(const value_t& val)
@@ -2191,18 +2304,18 @@ namespace LLInitParam
return mValue.deserializeBlock(p, name_stack_range, new_name);
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
{
const BaseBlock* base_block = diff_block
? &(diff_block->mValue)
: NULL;
- mValue.serializeBlock(p, name_stack, base_block);
+ return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);
}
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
+ {
return mValue.inspectBlock(p, name_stack, min_count, max_count);
- }
+ }
bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
{
@@ -2212,9 +2325,7 @@ namespace LLInitParam
// clear away what is there and take the new stuff as a whole
resetToDefault();
return mValue.mergeBlock(block_data, source.getValue(), overwrite);
- }
-
-
+ }
return mValue.mergeBlock(block_data, source.getValue(), overwrite);
}
@@ -2223,14 +2334,17 @@ namespace LLInitParam
return mValue.validateBlock(emit_errors);
}
+ bool isValid() const
+ {
+ return validateBlock(false);
+ }
+
static BlockDescriptor& getBlockDescriptor()
{
return value_t::getBlockDescriptor();
}
- mutable bool mValidated; // lazy validation flag
-
private:
void resetToDefault()
{
@@ -2251,15 +2365,13 @@ namespace LLInitParam
typedef T default_value_t;
ParamValue()
- : mValue(),
- mValidated(false)
+ : mValue()
{
mCurParam = getBlockDescriptor().mAllParams.begin();
}
ParamValue(const default_value_t& value)
- : mValue(value),
- mValidated(false)
+ : mValue(value)
{
mCurParam = getBlockDescriptor().mAllParams.begin();
}
@@ -2284,7 +2396,7 @@ namespace LLInitParam
if (new_name)
{
mCurParam = getBlockDescriptor().mAllParams.begin();
- }
+ }
if (name_stack_range.first == name_stack_range.second
&& mCurParam != getBlockDescriptor().mAllParams.end())
{
@@ -2296,7 +2408,7 @@ namespace LLInitParam
if (deserialize_func
&& paramp
&& deserialize_func(*paramp, p, name_stack_range, new_name))
- {
+ {
++mCurParam;
return true;
}
@@ -2304,19 +2416,19 @@ namespace LLInitParam
{
return false;
}
- }
+ }
else
{
return mValue.deserializeBlock(p, name_stack_range, new_name);
}
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
{
const BaseBlock* base_block = diff_block
? &(diff_block->mValue)
: NULL;
- mValue.serializeBlock(p, name_stack, base_block);
+ return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);
}
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
@@ -2334,13 +2446,16 @@ namespace LLInitParam
return mValue.validateBlock(emit_errors);
}
+ bool isValid() const
+ {
+ return validateBlock(false);
+ }
+
static BlockDescriptor& getBlockDescriptor()
{
return value_t::getBlockDescriptor();
}
- mutable bool mValidated; // lazy validation flag
-
private:
BlockDescriptor::all_params_list_t::iterator mCurParam;
@@ -2358,16 +2473,14 @@ namespace LLInitParam
typedef T default_value_t;
ParamValue()
- : T(),
- mValidated(false)
+ : T()
{}
ParamValue(const default_value_t& value)
- : T(value.getValue()),
- mValidated(false)
+ : T(value.getValue())
{}
- mutable bool mValidated; // lazy validation flag
+ bool isValid() const { return true; }
};
template<typename T, typename BLOCK_T>
@@ -2380,18 +2493,15 @@ namespace LLInitParam
typedef LazyValue<T> default_value_t;
ParamValue()
- : mValue(),
- mValidated(false)
+ : mValue()
{}
ParamValue(const default_value_t& other)
- : mValue(other),
- mValidated(false)
+ : mValue(other)
{}
ParamValue(const T& value)
- : mValue(value),
- mValidated(false)
+ : mValue(value)
{}
void setValue(const value_t& val)
@@ -2414,14 +2524,14 @@ namespace LLInitParam
return mValue.get().deserializeBlock(p, name_stack_range, new_name);
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const
{
- if (mValue.empty()) return;
+ if (mValue.empty()) return false;
const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
? &(diff_block->mValue.get().getValue())
: NULL;
- mValue.get().serializeBlock(p, name_stack, base_block);
+ return mValue.get().serializeBlock(p, name_stack, predicate_rule, base_block);
}
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
@@ -2433,26 +2543,29 @@ namespace LLInitParam
{
return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
}
-
+
bool validateBlock(bool emit_errors = true) const
{
return mValue.empty() || mValue.get().validateBlock(emit_errors);
}
+ bool isValid() const
+ {
+ return validateBlock(false);
+ }
+
static BlockDescriptor& getBlockDescriptor()
{
return value_t::getBlockDescriptor();
}
- mutable bool mValidated; // lazy validation flag
-
private:
LazyValue<T> mValue;
};
template<typename T, typename BLOCK_T>
class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
- {
+ {
typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
public:
@@ -2460,18 +2573,15 @@ namespace LLInitParam
typedef LazyValue<T> default_value_t;
ParamValue()
- : mValue(),
- mValidated(false)
+ : mValue()
{}
ParamValue(const default_value_t& other)
- : mValue(other),
- mValidated(false)
+ : mValue(other)
{}
ParamValue(const T& value)
- : mValue(value),
- mValidated(false)
+ : mValue(value)
{}
void setValue(const value_t& val)
@@ -2489,7 +2599,10 @@ namespace LLInitParam
return mValue.get().getValue();
}
- mutable bool mValidated; // lazy validation flag
+ bool isValid() const
+ {
+ return true;
+ }
private:
LazyValue<T> mValue;
@@ -2504,12 +2617,10 @@ namespace LLInitParam
typedef LLSD default_value_t;
ParamValue()
- : mValidated(false)
{}
ParamValue(const default_value_t& other)
- : mValue(other),
- mValidated(false)
+ : mValue(other)
{}
void setValue(const value_t& val) { mValue = val; }
@@ -2519,16 +2630,13 @@ namespace LLInitParam
// block param interface
LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
- LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ LL_COMMON_API bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
//TODO: implement LLSD params as schema type Any
return true;
}
- protected:
- mutable bool mValidated; // lazy validation flag
-
private:
static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
@@ -2547,18 +2655,17 @@ namespace LLInitParam
BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
} EValueAge;
- typedef ParamValue<T> derived_t;
- typedef CustomParamValue<T> self_t;
- typedef Block<derived_t> block_t;
+ typedef TypeValues<T> derived_t;
+ typedef CustomParamValue<T> self_t;
+ typedef Block<ParamValue<T> > block_t;
typedef T default_value_t;
- typedef T value_t;
+ typedef T value_t;
typedef void baseblock_base_class_t;
CustomParamValue(const default_value_t& value = T())
: mValue(value),
- mValueAge(VALUE_AUTHORITATIVE),
- mValidated(false)
+ mValueAge(VALUE_AUTHORITATIVE)
{}
bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
@@ -2580,16 +2687,30 @@ namespace LLInitParam
return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
}
- void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ bool serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const
{
const derived_t& typed_param = static_cast<const derived_t&>(*this);
const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
+ //std::string key = typed_param.getValueName();
+
+ //// first try to write out name of name/value pair
+ //if (!key.empty())
+ //{
+ // if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
+ // {
+ // return parser.writeValue(key, name_stack);
+ // }
+ //}
// then try to serialize value directly
if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
{
- if (!parser.writeValue(typed_param.getValue(), name_stack))
+ if (parser.writeValue(typed_param.getValue(), name_stack))
+ {
+ return true;
+ }
+ else
{
//RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
// since these tend to be viewed as the constructor arguments for the value T. It seems
@@ -2606,14 +2727,15 @@ namespace LLInitParam
// and serialize those params
derived_t copy(typed_param);
copy.updateBlockFromValue(true);
- copy.block_t::serializeBlock(parser, name_stack, NULL);
+ return copy.block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
}
else
{
- block_t::serializeBlock(parser, name_stack, NULL);
+ return block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
}
}
}
+ return false;
}
bool validateBlock(bool emit_errors = true) const
@@ -2705,8 +2827,6 @@ namespace LLInitParam
return block_t::mergeBlock(block_data, source, overwrite);
}
- mutable bool mValidated; // lazy validation flag
-
private:
mutable T mValue;
mutable EValueAge mValueAge;
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 5dc3ea5d7b..7ff8324fe3 100755
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -27,23 +27,25 @@
#include "linden_common.h"
// associated header
#include "llinstancetracker.h"
+#include "llapr.h"
+
// STL headers
// std headers
// external library headers
// other Linden headers
-//static
-void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
+void LLInstanceTrackerBase::StaticBase::incrementDepth()
+{
+ apr_atomic_inc32(&sIterationNestDepth);
+}
+
+void LLInstanceTrackerBase::StaticBase::decrementDepth()
{
- typedef std::map<std::string, void *> InstancesMap;
- static InstancesMap instances;
+ apr_atomic_dec32(&sIterationNestDepth);
+}
- // std::map::insert() is just what we want here. You attempt to insert a
- // (key, value) pair. If the specified key doesn't yet exist, it inserts
- // the pair and returns a std::pair of (iterator, true). If the specified
- // key DOES exist, insert() simply returns (iterator, false). One lookup
- // handles both cases.
- return instances.insert(InstancesMap::value_type(info.name(),
- InstancesMap::mapped_type()))
- .first->second;
+U32 LLInstanceTrackerBase::StaticBase::getDepth()
+{
+ apr_uint32_t data = apr_atomic_read32(&sIterationNestDepth);
+ return data;
}
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 1eab270e3c..c8e1d9cd84 100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -46,22 +46,6 @@
class LL_COMMON_API LLInstanceTrackerBase
{
protected:
- /// Get a process-unique void* pointer slot for the specified type_info
- static void * & getInstances(std::type_info const & info);
-
- /// Find or create a STATICDATA instance for the specified TRACKED class.
- /// STATICDATA must be default-constructible.
- template<typename STATICDATA, class TRACKED>
- static STATICDATA& getStatic()
- {
- void *& instances = getInstances(typeid(TRACKED));
- if (! instances)
- {
- instances = new STATICDATA;
- }
- return *static_cast<STATICDATA*>(instances);
- }
-
/// It's not essential to derive your STATICDATA (for use with
/// getStatic()) from StaticBase; it's just that both known
/// implementations do.
@@ -70,15 +54,21 @@ protected:
StaticBase():
sIterationNestDepth(0)
{}
- S32 sIterationNestDepth;
+
+ void incrementDepth();
+ void decrementDepth();
+ U32 getDepth();
+ private:
+ U32 sIterationNestDepth;
};
};
/// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// If KEY is not provided, then instances are stored in a simple set
-/// @NOTE: see explicit specialization below for default KEY==T* case
-template<typename T, typename KEY = T*>
+/// @NOTE: see explicit specialization below for default KEY==void case
+/// @NOTE: this class is not thread-safe unless used as read-only
+template<typename T, typename KEY = void>
class LLInstanceTracker : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, KEY> MyT;
@@ -87,7 +77,7 @@ class LLInstanceTracker : public LLInstanceTrackerBase
{
InstanceMap sMap;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static StaticData& getStatic() { static StaticData sData; return sData;}
static InstanceMap& getMap_() { return getStatic().sMap; }
public:
@@ -99,12 +89,12 @@ public:
instance_iter(const typename InstanceMap::iterator& it)
: mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~instance_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
@@ -131,20 +121,20 @@ public:
typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;
key_iter(typename InstanceMap::iterator it)
- : mIterator(it)
+ : mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
key_iter(const key_iter& other)
- : mIterator(other.mIterator)
+ : mIterator(other.mIterator)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~key_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
@@ -182,7 +172,10 @@ public:
return instance_iter(getMap_().end());
}
- static S32 instanceCount() { return getMap_().size(); }
+ static S32 instanceCount()
+ {
+ return getMap_().size();
+ }
static key_iter beginKeys()
{
@@ -203,7 +196,7 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert_always(getStatic().sIterationNestDepth == 0);
+ llassert_always(getStatic().getDepth() == 0);
remove_();
}
virtual void setKey(KEY key) { remove_(); add_(key); }
@@ -227,18 +220,18 @@ private:
KEY mInstanceKey;
};
-/// explicit specialization for default case where KEY is T*
+/// explicit specialization for default case where KEY is void
/// use a simple std::set<T*>
template<typename T>
-class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
+class LLInstanceTracker<T, void> : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, T*> MyT;
+ typedef LLInstanceTracker<T, void> MyT;
typedef typename std::set<T*> InstanceSet;
struct StaticData: public StaticBase
{
InstanceSet sSet;
};
- static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+ static StaticData& getStatic() { static StaticData sData; return sData; }
static InstanceSet& getSet_() { return getStatic().sSet; }
public:
@@ -265,18 +258,18 @@ public:
instance_iter(const typename InstanceSet::iterator& it)
: mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~instance_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
private:
@@ -309,7 +302,7 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert_always(getStatic().sIterationNestDepth == 0);
+ llassert_always(getStatic().getDepth() == 0);
getSet_().erase(static_cast<T*>(this));
}
diff --git a/indra/llcommon/lllazy.cpp b/indra/llcommon/lllazy.cpp
deleted file mode 100755
index 29fa040387..0000000000
--- a/indra/llcommon/lllazy.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file lllazy.cpp
- * @author Nat Goodspeed
- * @date 2009-01-28
- * @brief Implementation for lllazy.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Precompiled header
-#include "linden_common.h"
-// associated header
-#include "lllazy.h"
-// STL headers
-// std headers
-// external library headers
-// other Linden headers
-
-// lllazy.h is presently header-only. This file exists only because our CMake
-// test macro ADD_BUILD_TEST requires it.
-int dummy = 0;
diff --git a/indra/llcommon/lllazy.h b/indra/llcommon/lllazy.h
deleted file mode 100755
index 5f3bbce79e..0000000000
--- a/indra/llcommon/lllazy.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
- * @file lllazy.h
- * @author Nat Goodspeed
- * @date 2009-01-22
- * @brief Lazy instantiation of specified type. Useful in conjunction with
- * Michael Feathers's "Extract and Override Getter" ("Working
- * Effectively with Legacy Code", p. 352).
- *
- * Quoting his synopsis of steps on p.355:
- *
- * 1. Identify the object you need a getter for.
- * 2. Extract all of the logic needed to create the object into a getter.
- * 3. Replace all uses of the object with calls to the getter, and initialize
- * the reference that holds the object to null in all constructors.
- * 4. Add the first-time logic to the getter so that the object is constructed
- * and assigned to the reference whenever the reference is null.
- * 5. Subclass the class and override the getter to provide an alternative
- * object for testing.
- *
- * It's the second half of bullet 3 (3b, as it were) that bothers me. I find
- * it all too easy to imagine adding pointer initializers to all but one
- * constructor... the one not exercised by my tests. That suggested using
- * (e.g.) boost::scoped_ptr<MyObject> so you don't have to worry about
- * destroying it either.
- *
- * However, introducing additional machinery allows us to encapsulate bullet 4
- * as well.
- *
- * $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$
- */
-
-#if ! defined(LL_LLLAZY_H)
-#define LL_LLLAZY_H
-
-#include <boost/function.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/lambda/construct.hpp>
-#include <stdexcept>
-
-/// LLLazyCommon simply factors out of LLLazy<T> things that don't depend on
-/// its template parameter.
-class LLLazyCommon
-{
-public:
- /**
- * This exception is thrown if you try to replace an LLLazy<T>'s factory
- * (or T* instance) after it already has an instance in hand. Since T
- * might well be stateful, we can't know the effect of silently discarding
- * and replacing an existing instance, so we disallow it. This facility is
- * intended for testing, and in a test scenario we can definitely control
- * that.
- */
- struct InstanceChange: public std::runtime_error
- {
- InstanceChange(const std::string& what): std::runtime_error(what) {}
- };
-
-protected:
- /**
- * InstanceChange might be appropriate in a couple of different LLLazy<T>
- * methods. Factor out the common logic.
- */
- template <typename PTR>
- static void ensureNoInstance(const PTR& ptr)
- {
- if (ptr)
- {
- // Too late: we've already instantiated the lazy object. We don't
- // know whether it's stateful or not, so it's not safe to discard
- // the existing instance in favor of a replacement.
- throw InstanceChange("Too late to replace LLLazy instance");
- }
- }
-};
-
-/**
- * LLLazy<T> is useful when you have an outer class Outer that you're trying
- * to bring under unit test, that contains a data member difficult to
- * instantiate in a test harness. Typically the data member's class Inner has
- * many thorny dependencies. Feathers generally advocates "Extract and
- * Override Factory Method" (p. 350). But in C++, you can't call a derived
- * class override of a virtual method from the derived class constructor,
- * which limits applicability of "Extract and Override Factory Method." For
- * such cases Feathers presents "Extract and Override Getter" (p. 352).
- *
- * So we'll assume that your class Outer contains a member like this:
- * @code
- * Inner mInner;
- * @endcode
- *
- * LLLazy<Inner> can be used to replace this member. You can directly declare:
- * @code
- * LLLazy<Inner> mInner;
- * @endcode
- * and change references to mInner accordingly.
- *
- * (Alternatively, you can add a base class of the form
- * <tt>LLLazyBase<Inner></tt>. This is discussed further in the LLLazyBase<T>
- * documentation.)
- *
- * LLLazy<T> binds a <tt>boost::scoped_ptr<T></tt> and a factory functor
- * returning T*. You can either bind that functor explicitly or let it default
- * to the expression <tt>new T()</tt>.
- *
- * As long as LLLazy<T> remains unreferenced, its T remains uninstantiated.
- * The first time you use get(), <tt>operator*()</tt> or <tt>operator->()</tt>
- * it will instantiate its T and thereafter behave like a pointer to it.
- *
- * Thus, any existing reference to <tt>mInner.member</tt> should be replaced
- * with <tt>mInner->member</tt>. Any simple reference to @c mInner should be
- * replaced by <tt>*mInner</tt>.
- *
- * (If the original declaration was a pointer initialized in Outer's
- * constructor, e.g. <tt>Inner* mInner</tt>, so much the better. In that case
- * you should be able to drop in <tt>LLLazy<Inner></tt> without much change.)
- *
- * The support for "Extract and Override Getter" lies in the fact that you can
- * replace the factory functor -- or provide an explicit T*. Presumably this
- * is most useful from a test subclass -- which suggests that your @c mInner
- * member should be @c protected.
- *
- * Note that <tt>boost::lambda::new_ptr<T>()</tt> makes a dandy factory
- * functor, for either the set() method or LLLazy<T>'s constructor. If your T
- * requires constructor arguments, use an expression more like
- * <tt>boost::lambda::bind(boost::lambda::new_ptr<T>(), arg1, arg2, ...)</tt>.
- *
- * Of course the point of replacing the functor is to substitute a class that,
- * though referenced as Inner*, is not an Inner; presumably this is a testing
- * subclass of Inner (e.g. TestInner). Thus your test subclass TestOuter for
- * the containing class Outer will contain something like this:
- * @code
- * class TestOuter: public Outer
- * {
- * public:
- * TestOuter()
- * {
- * // mInner must be 'protected' rather than 'private'
- * mInner.set(boost::lambda::new_ptr<TestInner>());
- * }
- * ...
- * };
- * @endcode
- */
-template <typename T>
-class LLLazy: public LLLazyCommon
-{
-public:
- /// Any nullary functor returning T* will work as a Factory
- typedef boost::function<T* ()> Factory;
-
- /// The default LLLazy constructor uses <tt>new T()</tt> as its Factory
- LLLazy():
- mFactory(boost::lambda::new_ptr<T>())
- {}
-
- /// Bind an explicit Factory functor
- LLLazy(const Factory& factory):
- mFactory(factory)
- {}
-
- /// Reference T, instantiating it if this is the first access
- const T& get() const
- {
- if (! mInstance)
- {
- // use the bound Factory functor
- mInstance.reset(mFactory());
- }
- return *mInstance;
- }
-
- /// non-const get()
- T& get()
- {
- return const_cast<T&>(const_cast<const LLLazy<T>*>(this)->get());
- }
-
- /// operator*() is equivalent to get()
- const T& operator*() const { return get(); }
- /// operator*() is equivalent to get()
- T& operator*() { return get(); }
-
- /**
- * operator->() must return (something resembling) T*. It's tempting to
- * return the underlying boost::scoped_ptr<T>, but that would require
- * breaking out the lazy-instantiation logic from get() into a common
- * private method. Assume the pointer used for operator->() access is very
- * short-lived.
- */
- const T* operator->() const { return &get(); }
- /// non-const operator->()
- T* operator->() { return &get(); }
-
- /// set(Factory). This will throw InstanceChange if mInstance has already
- /// been set.
- void set(const Factory& factory)
- {
- ensureNoInstance(mInstance);
- mFactory = factory;
- }
-
- /// set(T*). This will throw InstanceChange if mInstance has already been
- /// set.
- void set(T* instance)
- {
- ensureNoInstance(mInstance);
- mInstance.reset(instance);
- }
-
-private:
- Factory mFactory;
- // Consider an LLLazy<T> member of a class we're accessing by const
- // reference. We want to allow even const methods to touch the LLLazy<T>
- // member. Hence the actual pointer must be mutable because such access
- // might assign it.
- mutable boost::scoped_ptr<T> mInstance;
-};
-
-#if (! defined(__GNUC__)) || (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
-// Not gcc at all, or a gcc more recent than gcc 3.3
-#define GCC33 0
-#else
-#define GCC33 1
-#endif
-
-/**
- * LLLazyBase<T> wraps LLLazy<T>, giving you an alternative way to replace
- * <tt>Inner mInner;</tt>. Instead of coding <tt>LLLazy<Inner> mInner</tt>,
- * you can add LLLazyBase<Inner> to your Outer class's bases, e.g.:
- * @code
- * class Outer: public LLLazyBase<Inner>
- * {
- * ...
- * };
- * @endcode
- *
- * This gives you @c public get() and @c protected set() methods without
- * having to make your LLLazy<Inner> member @c protected. The tradeoff is that
- * you must access the wrapped LLLazy<Inner> using get() and set() rather than
- * with <tt>operator*()</tt> or <tt>operator->()</tt>.
- *
- * This mechanism can be used for more than one member, but only if they're of
- * different types. That is, you can replace:
- * @code
- * DifficultClass mDifficult;
- * AwkwardType mAwkward;
- * @endcode
- * with:
- * @code
- * class Outer: public LLLazyBase<DifficultClass>, public LLLazyBase<AwkwardType>
- * {
- * ...
- * };
- * @endcode
- * but for a situation like this:
- * @code
- * DifficultClass mMainDifficult, mAuxDifficult;
- * @endcode
- * you should directly embed LLLazy<DifficultClass> (q.v.).
- *
- * For multiple LLLazyBase bases, e.g. the <tt>LLLazyBase<DifficultClass>,
- * LLLazyBase<AwkwardType></tt> example above, access the relevant get()/set()
- * as (e.g.) <tt>LLLazyBase<DifficultClass>::get()</tt>. (This is why you
- * can't have multiple LLLazyBase<T> of the same T.) For a bit of syntactic
- * sugar, please see getLazy()/setLazy().
- */
-template <typename T>
-class LLLazyBase
-{
-public:
- /// invoke default LLLazy constructor
- LLLazyBase() {}
- /// make wrapped LLLazy bind an explicit Factory
- LLLazyBase(const typename LLLazy<T>::Factory& factory):
- mInstance(factory)
- {}
-
- /// access to LLLazy::get()
- T& get() { return *mInstance; }
- /// access to LLLazy::get()
- const T& get() const { return *mInstance; }
-
-protected:
- // see getLazy()/setLazy()
- #if (! GCC33)
- template <typename T2, class MYCLASS> friend T2& getLazy(MYCLASS* this_);
- template <typename T2, class MYCLASS> friend const T2& getLazy(const MYCLASS* this_);
- #else // gcc 3.3
- template <typename T2, class MYCLASS> friend T2& getLazy(const MYCLASS* this_);
- #endif // gcc 3.3
- template <typename T2, class MYCLASS> friend void setLazy(MYCLASS* this_, T2* instance);
- template <typename T2, class MYCLASS>
- friend void setLazy(MYCLASS* this_, const typename LLLazy<T2>::Factory& factory);
-
- /// access to LLLazy::set(Factory)
- void set(const typename LLLazy<T>::Factory& factory)
- {
- mInstance.set(factory);
- }
-
- /// access to LLLazy::set(T*)
- void set(T* instance)
- {
- mInstance.set(instance);
- }
-
-private:
- LLLazy<T> mInstance;
-};
-
-/**
- * @name getLazy()/setLazy()
- * Suppose you have something like the following:
- * @code
- * class Outer: public LLLazyBase<DifficultClass>, public LLLazyBase<AwkwardType>
- * {
- * ...
- * };
- * @endcode
- *
- * Your methods can reference the @c DifficultClass instance using
- * <tt>LLLazyBase<DifficultClass>::get()</tt>, which is admittedly a bit ugly.
- * Alternatively, you can write <tt>getLazy<DifficultClass>(this)</tt>, which
- * is somewhat more straightforward to read.
- *
- * Similarly,
- * @code
- * LLLazyBase<DifficultClass>::set(new TestDifficultClass());
- * @endcode
- * could instead be written:
- * @code
- * setLazy<DifficultClass>(this, new TestDifficultClass());
- * @endcode
- *
- * @note
- * I wanted to provide getLazy() and setLazy() without explicitly passing @c
- * this. That would imply making them methods on a base class rather than free
- * functions. But if <tt>LLLazyBase<T></tt> derives normally from (say) @c
- * LLLazyGrandBase providing those methods, then unqualified getLazy() would
- * be ambiguous: you'd have to write <tt>LLLazyBase<T>::getLazy<T>()</tt>,
- * which is even uglier than <tt>LLLazyBase<T>::get()</tt>, and therefore
- * pointless. You can make the compiler not care which @c LLLazyGrandBase
- * instance you're talking about by making @c LLLazyGrandBase a @c virtual
- * base class of @c LLLazyBase. But in that case,
- * <tt>LLLazyGrandBase::getLazy<T>()</tt> can't access
- * <tt>LLLazyBase<T>::get()</tt>!
- *
- * We want <tt>getLazy<T>()</tt> to access <tt>LLLazyBase<T>::get()</tt> as if
- * in the lexical context of some subclass method. Ironically, free functions
- * let us do that better than methods on a @c virtual base class -- but that
- * implies passing @c this explicitly. So be it.
- */
-//@{
-#if (! GCC33)
-template <typename T, class MYCLASS>
-T& getLazy(MYCLASS* this_) { return this_->LLLazyBase<T>::get(); }
-template <typename T, class MYCLASS>
-const T& getLazy(const MYCLASS* this_) { return this_->LLLazyBase<T>::get(); }
-#else // gcc 3.3
-// For const-correctness, we really should have two getLazy() variants: one
-// accepting const MYCLASS* and returning const T&, the other accepting
-// non-const MYCLASS* and returning non-const T&. This works fine on the Mac
-// (gcc 4.0.1) and Windows (MSVC 8.0), but fails on our Linux 32-bit Debian
-// Sarge stations (gcc 3.3.5). Since I really don't know how to beat that aging
-// compiler over the head to make it do the right thing, I'm going to have to
-// move forward with the wrong thing: a single getLazy() function that accepts
-// const MYCLASS* and returns non-const T&.
-template <typename T, class MYCLASS>
-T& getLazy(const MYCLASS* this_) { return const_cast<MYCLASS*>(this_)->LLLazyBase<T>::get(); }
-#endif // gcc 3.3
-template <typename T, class MYCLASS>
-void setLazy(MYCLASS* this_, T* instance) { this_->LLLazyBase<T>::set(instance); }
-template <typename T, class MYCLASS>
-void setLazy(MYCLASS* this_, const typename LLLazy<T>::Factory& factory)
-{
- this_->LLLazyBase<T>::set(factory);
-}
-//@}
-
-#endif /* ! defined(LL_LLLAZY_H) */
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index 0a57ef1c48..84d2a12f65 100755
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -394,7 +394,7 @@ public:
LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD nop;
- F64 until(LLTimer::getElapsedSeconds() + 2);
+ F64 until = (LLTimer::getElapsedSeconds() + 2).value();
while (childin.size() && LLTimer::getElapsedSeconds() < until)
{
mainloop.post(nop);
diff --git a/indra/llcommon/lllocalidhashmap.h b/indra/llcommon/lllocalidhashmap.h
deleted file mode 100755
index 8f4f91a560..0000000000
--- a/indra/llcommon/lllocalidhashmap.h
+++ /dev/null
@@ -1,895 +0,0 @@
-/**
- * @file lllocalidhashmap.h
- * @brief Map specialized for dealing with local ids
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLLOCALIDHASHMAP_H
-#define LL_LLLOCALIDHASHMAP_H
-
-#include "stdtypes.h"
-#include "llerror.h"
-
-const S32 MAX_ITERS = 4;
-// LocalID hash map
-
-//
-// LLLocalIDHashNode
-//
-
-template <class DATA, int SIZE>
-class LLLocalIDHashNode
-{
-public:
- LLLocalIDHashNode();
-
-public:
- S32 mCount;
- U32 mKey[SIZE];
- DATA mData[SIZE];
- LLLocalIDHashNode<DATA, SIZE> *mNextNodep;
-};
-
-
-//
-// LLLocalIDHashNode implementation
-//
-template <class DATA, int SIZE>
-LLLocalIDHashNode<DATA, SIZE>::LLLocalIDHashNode()
-{
- mCount = 0;
- mNextNodep = NULL;
-}
-
-//
-// LLLocalIDHashMapIter
-//
-template <class DATA_TYPE, int SIZE>
-class LLLocalIDHashMap;
-
-template <class DATA_TYPE, int SIZE>
-class LLLocalIDHashMapIter
-{
-public:
- LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp);
- ~LLLocalIDHashMapIter();
-
- void setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp);
- inline void first();
- inline void next();
- inline DATA_TYPE& current(); // *NOTE: Deprecate? Phoenix 2005-04-15
- inline BOOL done() const;
- inline S32 currentBin() const;
- inline void setBin(S32 bin);
-
- DATA_TYPE& operator*() const
- {
- return mCurHashNodep->mData[mCurHashNodeKey];
- }
- DATA_TYPE* operator->() const
- {
- return &(operator*());
- }
-
- LLLocalIDHashMap<DATA_TYPE, SIZE> *mHashMapp;
- LLLocalIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep;
-
- S32 mCurHashMapNodeNum;
- S32 mCurHashNodeKey;
-
- DATA_TYPE mNull;
-
- S32 mIterID;
-};
-
-
-
-template <class DATA_TYPE, int SIZE>
-class LLLocalIDHashMap
-{
-public:
- friend class LLLocalIDHashMapIter<DATA_TYPE, SIZE>;
-
- LLLocalIDHashMap(); // DO NOT use this unless you explicitly setNull, or the data type constructs a "null"
- // object by default
- // basic constructor including sorter
- LLLocalIDHashMap(const DATA_TYPE &null_data);
- // Hack, this should really be a const ref, but I'm not doing it that way because the sim
- // usually uses pointers.
- ~LLLocalIDHashMap();
-
- inline DATA_TYPE &get(const U32 local_id);
- inline BOOL check(const U32 local_id) const;
- inline DATA_TYPE &set(const U32 local_id, const DATA_TYPE data);
- inline BOOL remove(const U32 local_id);
- void removeAll();
-
- void setNull(const DATA_TYPE data) { mNull = data; }
-
- inline S32 getLength() const; // Warning, NOT O(1!)
-
- void dumpIter();
- void dumpBin(U32 bin);
-
-protected:
- // Only used by the iterator.
- void addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter);
- void removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter);
-
- // Remove the item and shift all items afterward down the list,
- // fixing up iterators as we go.
- BOOL removeWithShift(const U32 local_id);
-
-protected:
- LLLocalIDHashNode<DATA_TYPE, SIZE> mNodes[256];
-
- S32 mIterCount;
- LLLocalIDHashMapIter<DATA_TYPE, SIZE> *mIters[MAX_ITERS];
-
- DATA_TYPE mNull;
-};
-
-
-//
-// LLLocalIDHashMap implementation
-//
-
-template <class DATA_TYPE, int SIZE>
-LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap()
-: mIterCount(0),
- mNull()
-{
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- mIters[i] = NULL;
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap(const DATA_TYPE &null_data)
-: mIterCount(0),
- mNull(null_data)
-{
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- mIters[i] = NULL;
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-LLLocalIDHashMap<DATA_TYPE, SIZE>::~LLLocalIDHashMap()
-{
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- if (mIters[i])
- {
- mIters[i]->mHashMapp = NULL;
- mIterCount--;
- }
- }
- removeAll();
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeAll()
-{
- S32 bin;
- for (bin = 0; bin < 256; bin++)
- {
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
-
- BOOL first = TRUE;
- do // First node guaranteed to be there
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- nodep->mData[i] = mNull;
- }
-
- nodep->mCount = 0;
- // Done with all objects in this node, go to the next.
-
- LLLocalIDHashNode<DATA_TYPE, SIZE>* curp = nodep;
- nodep = nodep->mNextNodep;
-
- // Delete the node if it's not the first node
- if (first)
- {
- first = FALSE;
- curp->mNextNodep = NULL;
- }
- else
- {
- delete curp;
- }
- } while (nodep);
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpIter()
-{
- std::cout << "Hash map with " << mIterCount << " iterators" << std::endl;
-
- std::cout << "Hash Map Iterators:" << std::endl;
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- if (mIters[i])
- {
- llinfos << i << " " << mIters[i]->mCurHashNodep << " " << mIters[i]->mCurHashNodeKey << llendl;
- }
- else
- {
- llinfos << i << "null" << llendl;
- }
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpBin(U32 bin)
-{
- std::cout << "Dump bin " << bin << std::endl;
-
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
- S32 node = 0;
- do // First node guaranteed to be there.
- {
- std::cout << "Bin " << bin
- << " node " << node
- << " count " << nodep->mCount
- << " contains " << std::flush;
-
- S32 i;
- for (i = 0; i < nodep->mCount; i++)
- {
- std::cout << nodep->mData[i] << " " << std::flush;
- }
-
- std::cout << std::endl;
-
- nodep = nodep->mNextNodep;
- node++;
- } while (nodep);
-}
-
-template <class DATA_TYPE, int SIZE>
-inline S32 LLLocalIDHashMap<DATA_TYPE, SIZE>::getLength() const
-{
- S32 count = 0;
- S32 bin;
- for (bin = 0; bin < 256; bin++)
- {
- const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
- while (nodep)
- {
- count += nodep->mCount;
- nodep = nodep->mNextNodep;
- }
- }
- return count;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::get(const U32 local_id)
-{
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
-
- do // First node guaranteed to be there
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- if (nodep->mKey[i] == local_id)
- {
- // We found it.
- return nodep->mData[i];
- }
- }
-
- // Done with all objects in this node, go to the next.
- nodep = nodep->mNextNodep;
- } while (nodep);
-
- return mNull;
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::check(const U32 local_id) const
-{
- const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
-
- do // First node guaranteed to be there
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- if (nodep->mKey[i] == local_id)
- {
- // We found it.
- return TRUE;
- }
- }
-
- // Done with all objects in this node, go to the next.
- nodep = nodep->mNextNodep;
- } while (nodep);
-
- // Didn't find anything
- return FALSE;
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::set(const U32 local_id, const DATA_TYPE data)
-{
- // Set is just like a normal find, except that if we find a match
- // we replace it with the input value.
- // If we don't find a match, we append to the end of the list.
-
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff];
-
- while (1)
- {
- const S32 count = nodep->mCount;
-
- S32 i;
- for (i = 0; i < count; i++)
- {
- if (nodep->mKey[i] == local_id)
- {
- // We found a match for this key, replace the data with
- // the incoming data.
- nodep->mData[i] = data;
- return nodep->mData[i];
- }
- }
- if (!nodep->mNextNodep)
- {
- // We've iterated through all of the keys without finding a match
- if (i < SIZE)
- {
- // There's still some space on this node, append
- // the key and data to it.
- nodep->mKey[i] = local_id;
- nodep->mData[i] = data;
- nodep->mCount++;
-
- return nodep->mData[i];
- }
- else
- {
- // This node is full, append a new node to the end.
- nodep->mNextNodep = new LLLocalIDHashNode<DATA_TYPE, SIZE>;
- nodep->mNextNodep->mKey[0] = local_id;
- nodep->mNextNodep->mData[0] = data;
- nodep->mNextNodep->mCount = 1;
-
- return nodep->mNextNodep->mData[0];
- }
- }
-
- // No match on this node, go to the next
- nodep = nodep->mNextNodep;
- }
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::remove(const U32 local_id)
-{
- // Remove is the trickiest operation.
- // What we want to do is swap the last element of the last
- // node if we find the one that we want to remove, but we have
- // to deal with deleting the node from the tail if it's empty, but
- // NOT if it's the only node left.
-
- const S32 node_index = local_id & 0xff;
-
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index];
-
- // A modification of the standard search algorithm.
- do // First node guaranteed to be there
- {
- const S32 count = nodep->mCount;
-
- S32 i;
- for (i = 0; i < count; i++)
- {
- if (nodep->mKey[i] == local_id)
- {
- // If we're removing the item currently pointed to by one
- // or more iterators, we can just swap in the last item
- // and back the iterator(s) up by one.
- // Otherwise, we need to do a slow and safe shift of all
- // items back to one position to fill the hole and fix up
- // all iterators we find.
- BOOL need_shift = FALSE;
- S32 cur_iter;
- if (mIterCount)
- {
- for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++)
- {
- if (mIters[cur_iter])
- {
- // We only care if the hash map node is on the one
- // that we're working on. If it's before, we've already
- // traversed it, if it's after, changing the order doesn't
- // matter.
- if (mIters[cur_iter]->mCurHashMapNodeNum == node_index)
- {
- if ((mIters[cur_iter]->mCurHashNodep == nodep)
- && (mIters[cur_iter]->mCurHashNodeKey == i))
- {
- // it's on the one we're deleting, we'll
- // fix the iterator quickly below.
- }
- else
- {
- // We're trying to remove an item on this
- // iterator's chain that this
- // iterator doesn't point to! We need to do
- // the slow remove-and-shift-down case.
- need_shift = TRUE;
- }
- }
- }
- }
- }
-
- // Removing an item that isn't pointed to by all iterators
- if (need_shift)
- {
- return removeWithShift(local_id);
- }
-
- // Fix the iterators that point to this node/i pair, the
- // one we're deleting
- for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++)
- {
- if (mIters[cur_iter])
- {
- // We only care if the hash map node is on the one
- // that we're working on. If it's before, we've already
- // traversed it, if it's after, changing the order doesn't
- // matter.
- if (mIters[cur_iter]->mCurHashMapNodeNum == node_index)
- {
- if ((mIters[cur_iter]->mCurHashNodep == nodep)
- && (mIters[cur_iter]->mCurHashNodeKey == i))
- {
- // We can handle the case where we're deleting
- // the element we're on trivially (sort of).
- if (nodep->mCount > 1)
- {
- // If we're not going to delete this node,
- // it's OK.
- mIters[cur_iter]->mCurHashNodeKey--;
- }
- else
- {
- // We're going to delete this node, because this
- // is the last element on it.
-
- // Find the next node, and then back up one.
- mIters[cur_iter]->next();
- mIters[cur_iter]->mCurHashNodeKey--;
- }
- }
- }
- }
- }
-
- // We found the node that we want to remove.
- // Find the last (and next-to-last) node, and the index of the last
- // element. We could conceviably start from the node we're on,
- // but that makes it more complicated, this is easier.
-
- LLLocalIDHashNode<DATA_TYPE, SIZE> *prevp = &mNodes[node_index];
- LLLocalIDHashNode<DATA_TYPE, SIZE> *lastp = prevp;
-
- // Find the last and next-to-last
- while (lastp->mNextNodep)
- {
- prevp = lastp;
- lastp = lastp->mNextNodep;
- }
-
- // First, swap in the last to the current location.
- nodep->mKey[i] = lastp->mKey[lastp->mCount - 1];
- nodep->mData[i] = lastp->mData[lastp->mCount - 1];
-
- // Now, we delete the entry
- lastp->mCount--;
- lastp->mData[lastp->mCount] = mNull;
-
- if (!lastp->mCount)
- {
- // We deleted the last element!
- if (lastp != &mNodes[local_id & 0xff])
- {
- // Only blitz the node if it's not the head
- // Set the previous node to point to NULL, then
- // blitz the empty last node
- prevp->mNextNodep = NULL;
- delete lastp;
- }
- }
-
- return TRUE;
- }
- }
-
- // Iterate to the next node, we've scanned all the entries in this one.
- nodep = nodep->mNextNodep;
- } while (nodep);
-
- return FALSE;
-}
-
-template <class DATA_TYPE, int SIZE>
-BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::removeWithShift(const U32 local_id)
-{
- const S32 node_index = local_id & 0xFF;
- LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index];
- LLLocalIDHashNode<DATA_TYPE, SIZE>* prevp = NULL;
- BOOL found = FALSE;
-
- do // First node guaranteed to be there
- {
- const S32 count = nodep->mCount;
- S32 i;
- for (i = 0; i < count; i++)
- {
- if (nodep->mKey[i] == local_id)
- {
- // Found the item. Start shifting items from later
- // in the list over this item.
- found = TRUE;
- }
-
- if (found)
- {
- // If there is an iterator on this node, we need to
- // back it up.
- S32 cur_iter;
- for (cur_iter = 0; cur_iter <MAX_ITERS; cur_iter++)
- {
- LLLocalIDHashMapIter<DATA_TYPE, SIZE>* iter;
- iter = mIters[cur_iter];
- // If an iterator is on this node,i pair, then back it up.
- if (iter
- && iter->mCurHashMapNodeNum == node_index
- && iter->mCurHashNodep == nodep
- && iter->mCurHashNodeKey == i)
- {
- if (i > 0)
- {
- // Don't need to move iterator nodep, since
- // we're in the same node.
- iter->mCurHashNodeKey--;
- }
- else if (prevp)
- {
- // need to go the previous node, last item
- iter->mCurHashNodep = prevp;
- iter->mCurHashNodeKey = prevp->mCount - 1;
- }
- else
- {
- // we're on the first item in the list, but
- // need to go back anyhow.
-
- // BUG: If this deletion empties the list,
- // iter->done() will be wrong until
- // iter->next() is called.
- iter->mCurHashNodeKey = -1;
- }
- }
- }
-
- // Copy data from the next position into this position.
- if (i < count-1)
- {
- // we're not on the last item in the node,
- // so we can copy within the node
- nodep->mKey[i] = nodep->mKey[i+1];
- nodep->mData[i] = nodep->mData[i+1];
- }
- else if (nodep->mNextNodep)
- {
- // we're on the last item in the node,
- // but there's a next node we can copy from
- nodep->mKey[i] = nodep->mNextNodep->mKey[0];
- nodep->mData[i] = nodep->mNextNodep->mData[0];
- }
- else
- {
- // We're on the last position in the list.
- // No one to copy from. Replace with nothing.
- nodep->mKey[i] = 0;
- nodep->mData[i] = mNull;
- }
- }
- }
-
- // Last node in chain, so delete the last node
- if (found
- && !nodep->mNextNodep)
- {
- // delete the last item off the last node
- nodep->mCount--;
-
- if (nodep->mCount == 0)
- {
- // We deleted the last element!
- if (nodep != &mNodes[node_index])
- {
- // Always have a prevp if we're not the head.
- llassert(prevp);
-
- // Only blitz the node if it's not the head
- // Set the previous node to point to NULL, then
- // blitz the empty last node
- prevp->mNextNodep = NULL;
- delete nodep;
- nodep = NULL;
- }
- }
-
- // Deleted last item in chain, so we're done.
- return found;
- }
-
- prevp = nodep;
- nodep = nodep->mNextNodep;
- } while (nodep);
-
- return found;
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter)
-{
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- if (mIters[i] == iter)
- {
- mIters[i] = NULL;
- mIterCount--;
- return;
- }
- }
- llerrs << "Iterator " << iter << " not found for removal in hash map!" << llendl;
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMap<DATA_TYPE, SIZE>::addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter)
-{
- S32 i;
- for (i = 0; i < MAX_ITERS; i++)
- {
- if (mIters[i] == NULL)
- {
- mIters[i] = iter;
- mIterCount++;
- return;
- }
- }
- llerrs << "More than " << MAX_ITERS << " iterating over a map simultaneously!" << llendl;
-}
-
-
-
-//
-// LLLocalIDHashMapIter Implementation
-//
-template <class DATA_TYPE, int SIZE>
-LLLocalIDHashMapIter<DATA_TYPE, SIZE>::LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
-{
- mHashMapp = NULL;
- setMap(hash_mapp);
-}
-
-template <class DATA_TYPE, int SIZE>
-LLLocalIDHashMapIter<DATA_TYPE, SIZE>::~LLLocalIDHashMapIter()
-{
- if (mHashMapp)
- {
- mHashMapp->removeIter(this);
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
-{
- if (mHashMapp)
- {
- mHashMapp->removeIter(this);
- }
- mHashMapp = hash_mapp;
- if (mHashMapp)
- {
- mHashMapp->addIter(this);
- }
-
- mCurHashNodep = NULL;
- mCurHashMapNodeNum = -1;
- mCurHashNodeKey = 0;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::first()
-{
- // Iterate through until we find the first non-empty node;
- S32 i;
- for (i = 0; i < 256; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
-
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
- }
-
- // Completely empty!
- mCurHashNodep = NULL;
- //return mNull;
- return;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLLocalIDHashMapIter<DATA_TYPE, SIZE>::done() const
-{
- return mCurHashNodep ? FALSE : TRUE;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline S32 LLLocalIDHashMapIter<DATA_TYPE, SIZE>::currentBin() const
-{
- if ( (mCurHashMapNodeNum > 255)
- ||(mCurHashMapNodeNum < 0))
- {
- return 0;
- }
- else
- {
- return mCurHashMapNodeNum;
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setBin(S32 bin)
-{
- // Iterate through until we find the first non-empty node;
- S32 i;
- bin = llclamp(bin, 0, 255);
- for (i = bin; i < 256; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
-
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- return;
- }
- }
- for (i = 0; i < bin; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
-
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- return;
- }
- }
- // Completely empty!
- mCurHashNodep = NULL;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline DATA_TYPE &LLLocalIDHashMapIter<DATA_TYPE, SIZE>::current()
-{
- if (!mCurHashNodep)
- {
- return mNull;
- }
- return mCurHashNodep->mData[mCurHashNodeKey];
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::next()
-{
- // No current entry, this iterator is done
- if (!mCurHashNodep)
- {
- //return mNull;
- return;
- }
-
- // Go to the next element
- mCurHashNodeKey++;
- if (mCurHashNodeKey < mCurHashNodep->mCount)
- {
- // We're not done with this node, return the current element
- //return mCurHashNodep->mData[mCurHashNodeKey];
- return;
- }
-
- // Done with this node, move to the next
- mCurHashNodep = mCurHashNodep->mNextNodep;
- if (mCurHashNodep)
- {
- // Return the first element
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
-
- // Find the next non-empty node (keyed on the first byte)
- mCurHashMapNodeNum++;
-
- S32 i;
- for (i = mCurHashMapNodeNum; i < 256; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
- // We found one that wasn't empty
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
- }
-
- // OK, we're done, nothing else to iterate
- mCurHashNodep = NULL;
- mHashMapp->mIterCount--; // Decrement since we're safe to do removes now
- //return mNull;
- return;
-}
-
-#endif // LL_LLLOCALIDHASHMAP_H
diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp
index 1409c55d1c..ed80af36d8 100755
--- a/indra/llcommon/llmd5.cpp
+++ b/indra/llcommon/llmd5.cpp
@@ -76,7 +76,6 @@ documentation and/or software.
#include "llmd5.h"
-#include <cassert>
#include <iostream> // cerr
// how many bytes to grab at a time when checking files
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 70ad10ad55..c6b02df939 100755
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -32,7 +32,6 @@
//#endif
#if defined(LL_WINDOWS)
-//# include <windows.h>
# include <psapi.h>
#elif defined(LL_DARWIN)
# include <sys/types.h>
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index e725bdd9fa..95500753e4 100755
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -27,6 +27,9 @@
#define LLMEMORY_H
#include "linden_common.h"
+#if !LL_WINDOWS
+#include <stdint.h>
+#endif
class LLMutex ;
@@ -36,6 +39,20 @@ class LLMutex ;
#define LL_CHECK_MEMORY
#endif
+#if LL_WINDOWS
+#define LL_ALIGN_OF __alignof
+#else
+#define LL_ALIGN_OF __align_of__
+#endif
+
+#if LL_WINDOWS
+#define LL_DEFAULT_HEAP_ALIGN 8
+#elif LL_DARWIN
+#define LL_DEFAULT_HEAP_ALIGN 16
+#elif LL_LINUX
+#define LL_DEFAULT_HEAP_ALIGN 8
+#endif
+
inline void* ll_aligned_malloc( size_t size, int align )
{
void* mem = malloc( size + (align - 1) + sizeof(void*) );
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 731e58bd20..fd89cb818a 100755
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -29,9 +29,9 @@
#include "indra_constants.h"
#include "llerror.h"
#include "llsdserialize.h"
-#include "llstat.h"
#include "lltreeiterators.h"
#include "llmetricperformancetester.h"
+#include "llfasttimer.h"
//----------------------------------------------------------------------------------------------
// LLMetricPerformanceTesterBasic : static methods and testers management
@@ -91,7 +91,7 @@ LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::s
// Return TRUE if this metric is requested or if the general default "catch all" metric is requested
BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)
{
- return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));
+ return (LLTrace::TimeBlock::sMetricLog && ((LLTrace::TimeBlock::sLogName == name) || (LLTrace::TimeBlock::sLogName == DEFAULT_METRIC_NAME)));
}
/*static*/
@@ -194,8 +194,7 @@ void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)
void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd)
{
- LLMutexLock lock(LLFastTimer::sLogLock);
- LLFastTimer::sLogQueue.push((*sd));
+ LLTrace::TimeBlock::pushLog(*sd);
}
void LLMetricPerformanceTesterBasic::outputTestResults()
diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h
index 319955ef93..9517e2db5e 100755
--- a/indra/llcommon/llmortician.h
+++ b/indra/llcommon/llmortician.h
@@ -28,6 +28,7 @@
#define LLMORTICIAN_H
#include "stdtypes.h"
+#include <list>
class LL_COMMON_API LLMortician
{
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
new file mode 100644
index 0000000000..ad0287c6d5
--- /dev/null
+++ b/indra/llcommon/llmutex.cpp
@@ -0,0 +1,179 @@
+/**
+ * @file llmutex.cpp
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llapr.h"
+
+#include "apr_portable.h"
+
+#include "llmutex.h"
+#include "llthread.h"
+
+//============================================================================
+
+LLMutex::LLMutex(apr_pool_t *poolp) :
+ mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
+{
+ //if (poolp)
+ //{
+ // mIsLocalPool = FALSE;
+ // mAPRPoolp = poolp;
+ //}
+ //else
+ {
+ mIsLocalPool = TRUE;
+ apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
+ }
+ apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
+}
+
+
+LLMutex::~LLMutex()
+{
+#if MUTEX_DEBUG
+ //bad assertion, the subclass LLSignal might be "locked", and that's OK
+ //llassert_always(!isLocked()); // better not be locked!
+#endif
+ if (ll_apr_is_initialized())
+ {
+ apr_thread_mutex_destroy(mAPRMutexp);
+ if (mIsLocalPool)
+ {
+ apr_pool_destroy(mAPRPoolp);
+ }
+ }
+ mAPRMutexp = NULL;
+}
+
+
+void LLMutex::lock()
+{
+ if(isSelfLocked())
+ { //redundant lock
+ mCount++;
+ return;
+ }
+
+ apr_thread_mutex_lock(mAPRMutexp);
+
+#if MUTEX_DEBUG
+ // Have to have the lock before we can access the debug info
+ U32 id = LLThread::currentID();
+ if (mIsLocked[id] != FALSE)
+ llerrs << "Already locked in Thread: " << id << llendl;
+ mIsLocked[id] = TRUE;
+#endif
+
+ mLockingThread = LLThread::currentID();
+}
+
+void LLMutex::unlock()
+{
+ if (mCount > 0)
+ { //not the root unlock
+ mCount--;
+ return;
+ }
+
+#if MUTEX_DEBUG
+ // Access the debug info while we have the lock
+ U32 id = LLThread::currentID();
+ if (mIsLocked[id] != TRUE)
+ llerrs << "Not locked in Thread: " << id << llendl;
+ mIsLocked[id] = FALSE;
+#endif
+
+ mLockingThread = NO_THREAD;
+ apr_thread_mutex_unlock(mAPRMutexp);
+}
+
+bool LLMutex::isLocked()
+{
+ apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
+ if (APR_STATUS_IS_EBUSY(status))
+ {
+ return true;
+ }
+ else
+ {
+ apr_thread_mutex_unlock(mAPRMutexp);
+ return false;
+ }
+}
+
+bool LLMutex::isSelfLocked()
+{
+ return mLockingThread == LLThread::currentID();
+}
+
+U32 LLMutex::lockingThread() const
+{
+ return mLockingThread;
+}
+
+//============================================================================
+
+LLCondition::LLCondition(apr_pool_t *poolp) :
+ LLMutex(poolp)
+{
+ // base class (LLMutex) has already ensured that mAPRPoolp is set up.
+
+ apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
+}
+
+
+LLCondition::~LLCondition()
+{
+ apr_thread_cond_destroy(mAPRCondp);
+ mAPRCondp = NULL;
+}
+
+
+void LLCondition::wait()
+{
+ if (!isLocked())
+ { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
+ apr_thread_mutex_lock(mAPRMutexp);
+#if MUTEX_DEBUG
+ // avoid asserts on destruction in non-release builds
+ U32 id = LLThread::currentID();
+ mIsLocked[id] = TRUE;
+#endif
+ }
+ apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
+}
+
+void LLCondition::signal()
+{
+ apr_thread_cond_signal(mAPRCondp);
+}
+
+void LLCondition::broadcast()
+{
+ apr_thread_cond_broadcast(mAPRCondp);
+}
+
+
+//============================================================================
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
new file mode 100644
index 0000000000..cbde4c47a9
--- /dev/null
+++ b/indra/llcommon/llmutex.h
@@ -0,0 +1,101 @@
+/**
+ * @file llmutex.h
+ * @brief Base classes for mutex and condition handling.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMUTEX_H
+#define LL_LLMUTEX_H
+
+#include "llapr.h"
+#include "apr_thread_cond.h"
+
+//============================================================================
+
+#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
+
+class LL_COMMON_API LLMutex
+{
+public:
+ typedef enum
+ {
+ NO_THREAD = 0xFFFFFFFF
+ } e_locking_thread;
+
+ LLMutex(apr_pool_t *apr_poolp = NULL); // NULL pool constructs a new pool for the mutex
+ virtual ~LLMutex();
+
+ void lock(); // blocks
+ void unlock();
+ bool isLocked(); // non-blocking, but does do a lock/unlock so not free
+ bool isSelfLocked(); //return true if locked in a same thread
+ U32 lockingThread() const; //get ID of locking thread
+
+protected:
+ apr_thread_mutex_t *mAPRMutexp;
+ mutable U32 mCount;
+ mutable U32 mLockingThread;
+
+ apr_pool_t *mAPRPoolp;
+ BOOL mIsLocalPool;
+
+#if MUTEX_DEBUG
+ std::map<U32, BOOL> mIsLocked;
+#endif
+};
+
+// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
+class LL_COMMON_API LLCondition : public LLMutex
+{
+public:
+ LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
+ ~LLCondition();
+
+ void wait(); // blocks
+ void signal();
+ void broadcast();
+
+protected:
+ apr_thread_cond_t *mAPRCondp;
+};
+
+class LLMutexLock
+{
+public:
+ LLMutexLock(LLMutex* mutex)
+ {
+ mMutex = mutex;
+
+ if(mMutex)
+ mMutex->lock();
+ }
+ ~LLMutexLock()
+ {
+ if(mMutex)
+ mMutex->unlock();
+ }
+private:
+ LLMutex* mMutex;
+};
+
+#endif // LL_LLTHREAD_H
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 88c09c8dca..6a0a8fcb0d 100755
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -97,24 +97,13 @@ public:
LLPointer<Type>& operator =(Type* ptr)
{
- if( mPointer != ptr )
- {
- unref();
- mPointer = ptr;
- ref();
- }
-
+ assign(ptr);
return *this;
}
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
{
- if( mPointer != ptr.mPointer )
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
+ assign(ptr);
return *this;
}
@@ -122,12 +111,7 @@ public:
template<typename Subclass>
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
{
- if( mPointer != ptr.get() )
- {
- unref();
- mPointer = ptr.get();
- ref();
- }
+ assign(ptr.get());
return *this;
}
@@ -144,6 +128,16 @@ protected:
void ref();
void unref();
#else
+
+ void assign(const LLPointer<Type>& ptr)
+ {
+ if( mPointer != ptr.mPointer )
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ref();
+ }
+ }
void ref()
{
if (mPointer)
@@ -156,9 +150,9 @@ protected:
{
if (mPointer)
{
- Type *tempp = mPointer;
+ Type *temp = mPointer;
mPointer = NULL;
- tempp->unref();
+ temp->unref();
if (mPointer != NULL)
{
llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
@@ -171,4 +165,40 @@ protected:
Type* mPointer;
};
+template<typename Type>
+class LLCopyOnWritePointer : public LLPointer<Type>
+{
+public:
+ typedef LLCopyOnWritePointer<Type> self_t;
+ typedef LLPointer<Type> pointer_t;
+
+ LLCopyOnWritePointer()
+ {}
+
+ LLCopyOnWritePointer(Type* ptr)
+ : LLPointer<Type>(ptr)
+ {}
+
+ LLCopyOnWritePointer(LLPointer<Type>& ptr)
+ : LLPointer<Type>(ptr)
+ {}
+
+ Type* write()
+ {
+ makeUnique();
+ return pointer_t::mPointer;
+ }
+
+ void makeUnique()
+ {
+ if (pointer_t::notNull() && pointer_t::mPointer->getNumRefs() > 1)
+ {
+ *(pointer_t* )(this) = new Type(*pointer_t::mPointer);
+ }
+ }
+
+ const Type* operator->() const { return pointer_t::mPointer; }
+ const Type& operator*() const { return *pointer_t::mPointer; }
+};
+
#endif
diff --git a/indra/llui/llfunctorregistry.cpp b/indra/llcommon/llpredicate.cpp
index 8003324973..1278948e24 100755..100644
--- a/indra/llui/llfunctorregistry.cpp
+++ b/indra/llcommon/llpredicate.cpp
@@ -1,7 +1,6 @@
-/**
- * @file llfunctorregistry.cpp
- * @author Kent Quirk
- * @brief Maintains a registry of named callback functors taking a single LLSD parameter
+/**
+ * @file llpredicate.cpp
+ * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,11 +22,20 @@
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
- **/
-
+ */
#include "linden_common.h"
-#include "llfunctorregistry.h"
-// This is a default functor always resident in the system.
-// It's used whenever a functor isn't found in the registry, so that
-// we at least log the data relating to the user response.
+#include "llpredicate.h"
+
+namespace LLPredicate
+{
+ const U32 cPredicateFlagsFromEnum[5] =
+ {
+ 0xAAAAaaaa, // 10101010101010101010101010101010
+ 0xCCCCcccc, // 11001100110011001100110011001100
+ 0xF0F0F0F0, // 11110000111100001111000011110000
+ 0xFF00FF00, // 11111111000000001111111100000000
+ 0xFFFF0000 // 11111111111111110000000000000000
+ };
+}
+
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
new file mode 100644
index 0000000000..a0e970a799
--- /dev/null
+++ b/indra/llcommon/llpredicate.h
@@ -0,0 +1,210 @@
+/**
+ * @file llpredicate.h
+ * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPREDICATE_H
+#define LL_LLPREDICATE_H
+
+#include "llerror.h"
+
+namespace LLPredicate
+{
+ template<typename ENUM> class Rule;
+
+ extern const U32 cPredicateFlagsFromEnum[5];
+
+ template<typename ENUM>
+ class Value
+ {
+ public:
+ typedef U32 predicate_flag_t;
+ static const S32 cMaxEnum = 5;
+
+ Value(ENUM e, bool predicate_value = true)
+ : mPredicateFlags(predicate_value ? cPredicateFlagsFromEnum[e] : ~cPredicateFlagsFromEnum[e])
+ {
+ llassert(0 <= e && e < cMaxEnum);
+ }
+
+ Value()
+ : mPredicateFlags(0xFFFFffff)
+ {}
+
+ Value operator!() const
+ {
+ Value new_value;
+ new_value.mPredicateFlags = ~mPredicateFlags;
+ return new_value;
+ }
+
+ Value operator &&(const Value other) const
+ {
+ Value new_value;
+ new_value.mPredicateFlags = mPredicateFlags & other.mPredicateFlags;
+ return new_value;
+ }
+
+ Value operator ||(const Value other) const
+ {
+ Value new_value;
+ new_value.mPredicateFlags = mPredicateFlags | other.mPredicateFlags;
+ return new_value;
+ }
+
+ void set(ENUM e, bool value = true)
+ {
+ llassert(0 <= e && e < cMaxEnum);
+ predicate_flag_t flags_to_modify;
+ predicate_flag_t mask = cPredicateFlagsFromEnum[e];
+ if (value)
+ { // add predicate "e" to flags that don't contain it already
+ flags_to_modify = (mPredicateFlags & ~mask);
+ // clear flags not containing e
+ mPredicateFlags &= mask;
+ // add back flags shifted to contain e
+ mPredicateFlags |= flags_to_modify << (0x1 << e);
+ }
+ else
+ { // remove predicate "e" from flags that contain it
+ flags_to_modify = (mPredicateFlags & mask);
+ // clear flags containing e
+ mPredicateFlags &= ~mask;
+ // add back flags shifted to not contain e
+ mPredicateFlags |= flags_to_modify >> (0x1 << e);
+ }
+ }
+
+ void forget(ENUM e)
+ {
+ set(e, true);
+ U32 flags_with_predicate = mPredicateFlags;
+ set(e, false);
+ // ambiguous value is result of adding and removing predicate at the same time!
+ mPredicateFlags |= flags_with_predicate;
+ }
+
+ bool allSet() const
+ {
+ return mPredicateFlags == ~0;
+ }
+
+ bool noneSet() const
+ {
+ return mPredicateFlags == 0;
+ }
+
+ bool someSet() const
+ {
+ return mPredicateFlags != 0;
+ }
+
+ private:
+ predicate_flag_t mPredicateFlags;
+ };
+
+ template<typename ENUM>
+ class Rule
+ {
+ public:
+ Rule(ENUM value)
+ : mRule(value)
+ {}
+
+ Rule(const Value<ENUM> other)
+ : mRule(other)
+ {}
+
+ Rule()
+ {}
+
+ void require(ENUM e)
+ {
+ mRule.set(e, require);
+ }
+
+ void allow(ENUM e)
+ {
+ mRule.forget(e);
+ }
+
+ bool check(const Value<ENUM> value) const
+ {
+ return (mRule && value).someSet();
+ }
+
+ bool requires(const Value<ENUM> value) const
+ {
+ return (mRule && value).someSet() && (!mRule && value).noneSet();
+ }
+
+ bool isAmbivalent(const Value<ENUM> value) const
+ {
+ return (mRule && value).someSet() && (!mRule && value).someSet();
+ }
+
+ bool acceptsAll() const
+ {
+ return mRule.allSet();
+ }
+
+ bool acceptsNone() const
+ {
+ return mRule.noneSet();
+ }
+
+ Rule operator!() const
+ {
+ Rule new_rule;
+ new_rule.mRule = !mRule;
+ return new_rule;
+ }
+
+ Rule operator &&(const Rule other) const
+ {
+ Rule new_rule;
+ new_rule.mRule = mRule && other.mRule;
+ return new_rule;
+ }
+
+ Rule operator ||(const Rule other) const
+ {
+ Rule new_rule;
+ new_rule.mRule = mRule || other.mRule;
+ return new_rule;
+ }
+
+ private:
+ Value<ENUM> mRule;
+ };
+}
+
+template<typename ENUM>
+LLPredicate::Value<ENUM> ll_make_predicate(ENUM e, bool predicate_value = true)
+{
+ return LLPredicate::Value<ENUM>(e, predicate_value);
+}
+
+
+#endif // LL_LLPREDICATE_H
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
index d711ce2f74..43ccadc412 100755
--- a/indra/llcommon/llprocess.h
+++ b/indra/llcommon/llprocess.h
@@ -29,6 +29,7 @@
#include "llinitparam.h"
#include "llsdparam.h"
+#include "llwin32headerslean.h"
#include "apr_thread_proc.h"
#include <boost/shared_ptr.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
@@ -38,8 +39,7 @@
#include <stdexcept>
#if LL_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> // HANDLE (eye roll)
+#include "llwin32headerslean.h" // for HANDLE
#elif LL_LINUX
#if defined(Status)
#undef Status
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index fd8f603d21..b80e813d84 100755
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -32,9 +32,7 @@
//#include <memory>
#if LL_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
+# include "llwin32headerslean.h"
# define _interlockedbittestandset _renamed_interlockedbittestandset
# define _interlockedbittestandreset _renamed_interlockedbittestandreset
# include <intrin.h>
@@ -877,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
LLProcessorInfo::~LLProcessorInfo() {}
-F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
+LLUnitImplicit<F64, LLUnits::Megahertz> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }
bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }
bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }
bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); }
diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h
index 6364d3c8bb..7f220467b0 100755
--- a/indra/llcommon/llprocessor.h
+++ b/indra/llcommon/llprocessor.h
@@ -27,6 +27,8 @@
#ifndef LLPROCESSOR_H
#define LLPROCESSOR_H
+#include "llunit.h"
+
class LLProcessorInfoImpl;
class LL_COMMON_API LLProcessorInfo
@@ -35,7 +37,7 @@ public:
LLProcessorInfo();
~LLProcessorInfo();
- F64 getCPUFrequency() const;
+ LLUnitImplicit<F64, LLUnits::Megahertz> getCPUFrequency() const;
bool hasSSE() const;
bool hasSSE2() const;
bool hasAltivec() const;
diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h
deleted file mode 100755
index 67c7cde352..0000000000
--- a/indra/llcommon/llptrskiplist.h
+++ /dev/null
@@ -1,724 +0,0 @@
-/**
- * @file llptrskiplist.h
- * @brief Skip list 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$
- */
-
-#ifndef LL_LLPTRSKIPLIST_H
-#define LL_LLPTRSKIPLIST_H
-
-#include "llerror.h"
-#include "llrand.h"
-//#include "vmath.h"
-#include "llrand.h"
-
-/////////////////////////////////////////////
-//
-// LLPtrSkipList implementation - skip list for pointers to objects
-//
-
-template <class DATA_TYPE, S32 BINARY_DEPTH = 8>
-class LLPtrSkipList
-{
-public:
- friend class LLPtrSkipNode;
-
- // basic constructor
- LLPtrSkipList();
- // basic constructor including sorter
- LLPtrSkipList(BOOL (*insert_first)(DATA_TYPE *first, DATA_TYPE *second),
- BOOL (*equals)(DATA_TYPE *first, DATA_TYPE *second));
- ~LLPtrSkipList();
-
- inline void setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second));
- inline void setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second));
-
- inline BOOL addData(DATA_TYPE *data);
-
- inline BOOL checkData(const DATA_TYPE *data);
-
- inline S32 getLength(); // returns number of items in the list - NOT constant time!
-
- inline BOOL removeData(const DATA_TYPE *data);
-
- // note that b_sort is ignored
- inline BOOL moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort);
-
- inline BOOL moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort);
-
- // resort -- use when the value we're sorting by changes
- /* IW 12/6/02 - This doesn't work!
- Instead, remove the data BEFORE you change it
- Then re-insert it after you change it
- BOOL resortData(DATA_TYPE *data)
- */
-
- // remove all nodes from the list but do not delete data
- inline void removeAllNodes();
-
- inline BOOL deleteData(const DATA_TYPE *data);
-
- // remove all nodes from the list and delete data
- inline void deleteAllData();
-
- // place mCurrentp on first node
- inline void resetList();
-
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- inline DATA_TYPE *getCurrentData();
-
- // same as getCurrentData() but a more intuitive name for the operation
- inline DATA_TYPE *getNextData();
-
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- inline void removeCurrentData();
-
- // delete the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- inline void deleteCurrentData();
-
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- inline DATA_TYPE *getFirstData();
-
- // TRUE if nodes are not in sorted order
- inline BOOL corrupt();
-
-protected:
- class LLPtrSkipNode
- {
- public:
- LLPtrSkipNode()
- : mData(NULL)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- }
-
- LLPtrSkipNode(DATA_TYPE *data)
- : mData(data)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- }
-
- ~LLPtrSkipNode()
- {
- if (mData)
- {
- llerror("Attempting to call LLPtrSkipNode destructor with a non-null mDatap!", 1);
- }
- }
-
- // delete associated data and NULLs out pointer
- void deleteData()
- {
- delete mData;
- mData = NULL;
- }
-
- // NULLs out pointer
- void removeData()
- {
- mData = NULL;
- }
-
- DATA_TYPE *mData;
- LLPtrSkipNode *mForward[BINARY_DEPTH];
- };
-
- static BOOL defaultEquals(const DATA_TYPE *first, const DATA_TYPE *second)
- {
- return first == second;
- }
-
-
- LLPtrSkipNode mHead;
- LLPtrSkipNode *mUpdate[BINARY_DEPTH];
- LLPtrSkipNode *mCurrentp;
- LLPtrSkipNode *mCurrentOperatingp;
- S32 mLevel;
- BOOL (*mInsertFirst)(const DATA_TYPE *first, const DATA_TYPE *second);
- BOOL (*mEquals)(const DATA_TYPE *first, const DATA_TYPE *second);
-};
-
-
-// basic constructor
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList()
- : mInsertFirst(NULL), mEquals(defaultEquals)
-{
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mUpdate[i] = NULL;
- }
- mLevel = 1;
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// basic constructor including sorter
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList(BOOL (*insert_first)(DATA_TYPE *first, DATA_TYPE *second),
- BOOL (*equals)(DATA_TYPE *first, DATA_TYPE *second))
- :mInsertFirst(insert_first), mEquals(equals)
-{
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- mLevel = 1;
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::~LLPtrSkipList()
-{
- removeAllNodes();
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second))
-{
- mInsertFirst = insert_first;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second))
-{
- mEquals = equals;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::addData(DATA_TYPE *data)
-{
- S32 level;
- LLPtrSkipNode *current = &mHead;
- LLPtrSkipNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
-
- LLPtrSkipNode *snode = new LLPtrSkipNode(data);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return TRUE;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE *data)
-{
- S32 level;
- LLPtrSkipNode *current = &mHead;
- LLPtrSkipNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (current)
- {
- return mEquals(current->mData, data);
- }
- else
- {
- return FALSE;
- }
-}
-
-// returns number of items in the list
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline S32 LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getLength()
-{
- U32 length = 0;
- for (LLPtrSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
- {
- length++;
- }
- return length;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE *data)
-{
- S32 level;
- LLPtrSkipNode *current = &mHead;
- LLPtrSkipNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (!current)
- {
- // empty list or beyond the end!
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mData, data))
- {
- // nope!
- return FALSE;
- }
- else
- {
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (mUpdate[level]->mForward[level] != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- mUpdate[level]->mForward[level] = current->mForward[level];
- }
-
- // clean up cuurent
- current->removeData();
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!mHead.mForward[mLevel - 1]))
- {
- mLevel--;
- }
- }
- return TRUE;
-}
-
-// note that b_sort is ignored
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort)
-{
- BOOL removed = removeData(data);
- BOOL added = newlist->addData(data);
- return removed && added;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort)
-{
- if (mCurrentOperatingp)
- {
- mCurrentp = mCurrentOperatingp->mForward[0];
- BOOL removed = removeData(mCurrentOperatingp);
- BOOL added = newlist->addData(mCurrentOperatingp);
- mCurrentOperatingp = mCurrentp;
- return removed && added;
- }
- return FALSE;
-}
-
-// resort -- use when the value we're sorting by changes
-/* IW 12/6/02 - This doesn't work!
- Instead, remove the data BEFORE you change it
- Then re-insert it after you change it
-BOOL resortData(DATA_TYPE *data)
-{
- removeData(data);
- addData(data);
-}
-*/
-
-// remove all nodes from the list but do not delete data
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes()
-{
- LLPtrSkipNode *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->removeData();
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteData(const DATA_TYPE *data)
-{
- S32 level;
- LLPtrSkipNode *current = &mHead;
- LLPtrSkipNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (!current)
- {
- // empty list or beyond the end!
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mData, data))
- {
- // nope!
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = current->mForward[0];
- }
-
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = current->mForward[0];
- }
-
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (mUpdate[level]->mForward[level] != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- mUpdate[level]->mForward[level] = current->mForward[level];
- }
-
- // clean up cuurent
- current->deleteData();
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!mHead.mForward[mLevel - 1]))
- {
- mLevel--;
- }
- }
- return TRUE;
-}
-
-// remove all nodes from the list and delete data
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteAllData()
-{
- LLPtrSkipNode *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->deleteData();
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// place mCurrentp on first node
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::resetList()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = *mCurrentp->mForward;
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return 0; // equivalent, but no warning
- }
-}
-
-// same as getCurrentData() but a more intuitive name for the operation
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = *mCurrentp->mForward;
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return 0; // equivalent, but no warning
- }
-}
-
-// remove the Node at mCurentOperatingp
-// leave mCurrentp and mCurentOperatingp on the next entry
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
-{
- if (mCurrentOperatingp)
- {
- removeData(mCurrentOperatingp->mData);
- }
-}
-
-// delete the Node at mCurentOperatingp
-// leave mCurrentp and mCurentOperatingp on the next entry
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteCurrentData()
-{
- if (mCurrentOperatingp)
- {
- deleteData(mCurrentOperatingp->mData);
- }
-}
-
-// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return 0; // equivalent, but no warning
- }
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::corrupt()
-{
- LLPtrSkipNode *previous = mHead.mForward[0];
-
- // Empty lists are not corrupt.
- if (!previous) return FALSE;
-
- LLPtrSkipNode *current = previous->mForward[0];
- while(current)
- {
- if (!mInsertFirst(previous->mData, current->mData))
- {
- // prev shouldn't be in front of cur!
- return TRUE;
- }
- current = current->mForward[0];
- }
- return FALSE;
-}
-
-#endif
diff --git a/indra/llcommon/llptrskipmap.h b/indra/llcommon/llptrskipmap.h
deleted file mode 100755
index 94bc71ec55..0000000000
--- a/indra/llcommon/llptrskipmap.h
+++ /dev/null
@@ -1,1239 +0,0 @@
-/**
- * @file llptrskipmap.h
- * @brief Just like a LLSkipMap, but since it's pointers, you can call
- * deleteAllData
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#ifndef LL_LLPTRSKIPMAP_H
-#define LL_LLPTRSKIPMAP_H
-
-#include "llerror.h"
-#include "llrand.h"
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>
-class LLPtrSkipMapNode
-{
-public:
- LLPtrSkipMapNode()
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- U8 *zero = (U8 *)&mIndex;
-
- for (i = 0; i < (S32)sizeof(INDEX_T); i++)
- {
- *(zero + i) = 0;
- }
-
- zero = (U8 *)&mData;
-
- for (i = 0; i < (S32)sizeof(DATA_T); i++)
- {
- *(zero + i) = 0;
- }
- }
-
- LLPtrSkipMapNode(const INDEX_T &index)
- : mIndex(index)
- {
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- U8 *zero = (U8 *)&mData;
-
- for (i = 0; i < (S32)sizeof(DATA_T); i++)
- {
- *(zero + i) = 0;
- }
- }
-
- LLPtrSkipMapNode(const INDEX_T &index, DATA_T datap)
- : mIndex(index)
- {
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- mData = datap;
- }
-
- ~LLPtrSkipMapNode()
- {
- }
-
- // delete associated data and NULLs out pointer
- void deleteData()
- {
- delete mData;
- mData = 0;
- }
-
- // NULLs out pointer
- void removeData()
- {
- mData = 0;
- }
-
- INDEX_T mIndex;
- DATA_T mData;
- LLPtrSkipMapNode *mForward[BINARY_DEPTH];
-
-private:
- // Disallow copying of LLPtrSkipMapNodes by not implementing these methods.
- LLPtrSkipMapNode(const LLPtrSkipMapNode &);
- LLPtrSkipMapNode &operator=(const LLPtrSkipMapNode &rhs);
-};
-
-//---------------------------------------------------------------------------
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>
-class LLPtrSkipMap
-{
-public:
- typedef BOOL (*compare)(const DATA_T& first, const DATA_T& second);
- typedef compare insert_func;
- typedef compare equals_func;
-
- void init();
-
- // basic constructor
- LLPtrSkipMap();
-
- // basic constructor including sorter
- LLPtrSkipMap(insert_func insert_first, equals_func equals);
-
- ~LLPtrSkipMap();
-
- void setInsertFirst(insert_func insert_first);
- void setEquals(equals_func equals);
-
- DATA_T &addData(const INDEX_T &index, DATA_T datap);
- DATA_T &addData(const INDEX_T &index);
- DATA_T &getData(const INDEX_T &index);
- DATA_T &operator[](const INDEX_T &index);
-
- // If index present, returns data.
- // If index not present, adds <index,NULL> and returns NULL.
- DATA_T &getData(const INDEX_T &index, BOOL &b_new_entry);
-
- // returns data entry before and after index
- BOOL getInterval(const INDEX_T &index, INDEX_T &index_before, INDEX_T &index_after,
- DATA_T &data_before, DATA_T &data_after );
-
- // Returns TRUE if data present in map.
- BOOL checkData(const INDEX_T &index);
-
- // Returns TRUE if key is present in map. This is useful if you
- // are potentially storing NULL pointers in the map
- BOOL checkKey(const INDEX_T &index);
-
- // If there, returns the data.
- // If not, returns NULL.
- // Never adds entries to the map.
- DATA_T getIfThere(const INDEX_T &index);
-
- INDEX_T reverseLookup(const DATA_T datap);
-
- // returns number of items in the list
- S32 getLength(); // WARNING! getLength is O(n), not O(1)!
-
- BOOL removeData(const INDEX_T &index);
- BOOL deleteData(const INDEX_T &index);
-
- // remove all nodes from the list but do not delete data
- void removeAllData();
- void deleteAllData();
-
- // place mCurrentp on first node
- void resetList();
-
- // return the data currently pointed to
- DATA_T getCurrentDataWithoutIncrement();
-
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_T getCurrentData();
-
- // same as getCurrentData() but a more intuitive name for the operation
- DATA_T getNextData();
-
- INDEX_T getNextKey();
-
- // return the key currently pointed to
- INDEX_T getCurrentKeyWithoutIncrement();
-
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- void removeCurrentData();
-
- void deleteCurrentData();
-
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_T getFirstData();
-
- INDEX_T getFirstKey();
-
- static BOOL defaultEquals(const INDEX_T &first, const INDEX_T &second)
- {
- return first == second;
- }
-
-private:
- // don't generate implicit copy constructor or copy assignment
- LLPtrSkipMap(const LLPtrSkipMap &);
- LLPtrSkipMap &operator=(const LLPtrSkipMap &);
-
-private:
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mUpdate[BINARY_DEPTH];
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentp;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *mCurrentOperatingp;
- S32 mLevel;
- BOOL (*mInsertFirst)(const INDEX_T &first, const INDEX_T &second);
- BOOL (*mEquals)(const INDEX_T &first, const INDEX_T &second);
- S32 mNumberOfSteps;
-};
-
-//////////////////////////////////////////////////
-//
-// LLPtrSkipMap implementation
-//
-//
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap()
- : mInsertFirst(NULL),
- mEquals(defaultEquals),
- mNumberOfSteps(0)
-{
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mUpdate[i] = NULL;
- }
- mLevel = 1;
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap(insert_func insert_first,
- equals_func equals)
-: mInsertFirst(insert_first),
- mEquals(equals),
- mNumberOfSteps(0)
-{
- if (BINARY_DEPTH < 2)
- {
- llerrs << "Trying to create skip list with too little depth, "
- "must be 2 or greater" << llendl;
- }
- mLevel = 1;
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::~LLPtrSkipMap()
-{
- removeAllData();
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setInsertFirst(insert_func insert_first)
-{
- mInsertFirst = insert_first;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setEquals(equals_func equals)
-{
- mEquals = equals;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index, DATA_T datap)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // replace the existing data if a node is already there
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
- current->mData = datap;
- return current->mData;
- }
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- {
- break;
- }
- }
-
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index, datap);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
-
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- mNumberOfSteps++;
-
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
-
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode
- = new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
-
- return snode->mData;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getInterval(const INDEX_T &index,
- INDEX_T &index_before,
- INDEX_T &index_after,
- DATA_T &data_before,
- DATA_T &data_after)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- BOOL both_found = TRUE;
-
- if (current != &mHead)
- {
- index_before = current->mIndex;
- data_before = current->mData;
- }
- else
- {
- data_before = 0;
- index_before = 0;
- both_found = FALSE;
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
-
- if (current)
- {
- data_after = current->mData;
- index_after = current->mIndex;
- }
- else
- {
- data_after = 0;
- index_after = 0;
- both_found = FALSE;
- }
-
- return both_found;
-}
-
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::operator[](const INDEX_T &index)
-{
-
- return getData(index);
-}
-
-// If index present, returns data.
-// If index not present, adds <index,NULL> and returns NULL.
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index, BOOL &b_new_entry)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
-
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
- b_new_entry = TRUE;
- addData(index);
-
- return current->mData;
-}
-
-// Returns TRUE if data present in map.
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkData(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (current)
- {
- // Gets rid of some compiler ambiguity for the LLPointer<> templated class.
- if (current->mData)
- {
- return mEquals(current->mIndex, index);
- }
- }
-
- return FALSE;
-}
-
-// Returns TRUE if key is present in map. This is useful if you
-// are potentially storing NULL pointers in the map
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkKey(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (current)
- {
- return mEquals(current->mIndex, index);
- }
-
- return FALSE;
-}
-
-// If there, returns the data.
-// If not, returns NULL.
-// Never adds entries to the map.
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getIfThere(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
-
- if (current)
- {
- if (mEquals(current->mIndex, index))
- {
- return current->mData;
- }
- }
-
- // Avoid Linux compiler warning on returning NULL.
- return (DATA_T)0;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::reverseLookup(const DATA_T datap)
-{
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
-
- while (current)
- {
- if (datap == current->mData)
- {
-
- return current->mIndex;
- }
- current = *current->mForward;
- }
-
- // not found! return NULL
- return INDEX_T();
-}
-
-// returns number of items in the list
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline S32 LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getLength()
-{
- U32 length = 0;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>* temp;
- for (temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
- {
- length++;
- }
-
- return length;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeData(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (!current)
- {
- // empty list or beyond the end!
-
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mIndex, index))
- {
- // nope!
-
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = *current->mForward;
- }
-
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = *current->mForward;
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (*((*(mUpdate + level))->mForward + level) != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
- }
-
- // clean up cuurent
- current->removeData();
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!*(mHead.mForward + mLevel - 1)))
- {
- mLevel--;
- }
- }
-
- return TRUE;
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteData(const INDEX_T &index)
-{
- S32 level;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *current = &mHead;
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (!current)
- {
- // empty list or beyond the end!
-
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mIndex, index))
- {
- // nope!
-
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = *current->mForward;
- }
-
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = *current->mForward;
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (*((*(mUpdate + level))->mForward + level) != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
- }
-
- // clean up cuurent
- current->deleteData();
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!*(mHead.mForward + mLevel - 1)))
- {
- mLevel--;
- }
- }
-
- return TRUE;
-}
-
-// remove all nodes from the list but do not delete data
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeAllData()
-{
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->removeData();
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteAllData()
-{
- LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- mCurrentp->deleteData();
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// place mCurrentp on first node
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::resetList()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-
-// return the data currently pointed to
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentDataWithoutIncrement()
-{
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes warning
- return (DATA_T)0; // equivalent, but no warning
- }
-}
-
-// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes warning
- return (DATA_T)0; // equivalent, but no warning
- }
-}
-
-// same as getCurrentData() but a more intuitive name for the operation
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_T)0; // equivalent, but removes warning
- }
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextKey()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
-}
-
-// return the key currently pointed to
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentKeyWithoutIncrement()
-{
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- //return NULL; // causes compile warning
- return (INDEX_T)0; // equivalent, but removes warning
- }
-}
-
-
-// remove the Node at mCurentOperatingp
-// leave mCurrentp and mCurentOperatingp on the next entry
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeCurrentData()
-{
- if (mCurrentOperatingp)
- {
- removeData(mCurrentOperatingp->mIndex);
- }
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteCurrentData()
-{
- if (mCurrentOperatingp)
- {
- deleteData(mCurrentOperatingp->mIndex);
- }
-}
-
-// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstData()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_T)0; // equivalent, but removes warning
- }
-}
-
-template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH>
-inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstKey()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
-}
-
-#endif
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index abf47a0f57..4339f203db 100755
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -28,6 +28,7 @@
#include "llstl.h"
#include "lltimer.h" // ms_sleep()
+#include "lltracethreadrecorder.h"
//============================================================================
@@ -134,8 +135,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)
pending = getPending();
if(pending > 0)
{
- unpause();
- }
+ unpause();
+ }
}
else
{
@@ -403,6 +404,7 @@ S32 LLQueuedThread::processNextRequest()
QueuedRequest *req;
// Get next request from pool
lockData();
+
while(1)
{
req = NULL;
@@ -467,10 +469,11 @@ S32 LLQueuedThread::processNextRequest()
ms_sleep(1); // sleep the thread a little
}
}
+
+ LLTrace::get_thread_recorder()->pushToMaster();
}
S32 pending = getPending();
-
return pending;
}
@@ -499,6 +502,7 @@ void LLQueuedThread::run()
if (isQuitting())
{
+ LLTrace::get_thread_recorder()->pushToMaster();
endThread();
break;
}
@@ -507,8 +511,9 @@ void LLQueuedThread::run()
threadedUpdate();
- int res = processNextRequest();
- if (res == 0)
+ int pending_work = processNextRequest();
+
+ if (pending_work == 0)
{
mIdleThread = TRUE;
ms_sleep(1);
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index bb0d60247e..c8ec0a0bc0 100755
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -29,7 +29,6 @@
#include <list>
-#include <boost/type_traits.hpp>
#include "llsingleton.h"
#include "llstl.h"
@@ -47,12 +46,11 @@ template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultC
class LLRegistry
{
public:
- typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
- typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
- typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type ref_const_value_t;
- typedef typename boost::add_reference<VALUE>::type ref_value_t;
- typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type ptr_const_value_t;
- typedef typename boost::add_pointer<VALUE>::type ptr_value_t;
+ typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
+ typedef const KEY& ref_const_key_t;
+ typedef const VALUE& ref_const_value_t;
+ typedef const VALUE* ptr_const_value_t;
+ typedef VALUE* ptr_value_t;
class Registrar
{
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 9f4460a988..50815b2cc6 100755
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -102,13 +102,13 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
//readSDValues(sd, block);
}
-void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
+void LLParamSDParser::writeSDImpl(LLSD& sd, const LLInitParam::BaseBlock& block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)
{
mNameStack.clear();
mWriteRootSD = &sd;
name_stack_t name_stack;
- block.serializeBlock(*this, name_stack);
+ block.serializeBlock(*this, name_stack, rules, diff_block);
}
/*virtual*/ std::string LLParamSDParser::getCurrentElementName()
@@ -299,6 +299,7 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd)
LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t();
readSDValues(cb, sd, stack);
}
+
namespace LLInitParam
{
// LLSD specialization
@@ -329,13 +330,14 @@ namespace LLInitParam
p.writeValue<LLSD::String>(sd.asString(), name_stack);
}
- void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+ bool ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack_range, const predicate_rule_t predicate_rule, const BaseBlock* diff_block) const
{
// attempt to write LLSD out directly
- if (!p.writeValue<LLSD>(mValue, name_stack))
+ if (!p.writeValue<LLSD>(mValue, name_stack_range))
{
// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
- LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+ LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack_range);
}
+ return true;
}
}
diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h
index 6ef5debd7b..7cfc265c62 100755
--- a/indra/llcommon/llsdparam.h
+++ b/indra/llcommon/llsdparam.h
@@ -30,6 +30,7 @@
#include "llinitparam.h"
#include "boost/function.hpp"
+#include "llfasttimer.h"
struct LL_COMMON_API LLParamSDParserUtilities
{
@@ -50,11 +51,28 @@ typedef LLInitParam::Parser parser_t;
public:
LLParamSDParser();
void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
- void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
+ template<typename BLOCK>
+ void writeSD(LLSD& sd,
+ const BLOCK& block,
+ const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(),
+ const LLInitParam::BaseBlock* diff_block = NULL)
+ {
+ if (!diff_block
+ && !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE))
+ {
+ diff_block = &LLInitParam::defaultValue<BLOCK>();
+ }
+ writeSDImpl(sd, block, rules, diff_block);
+ }
/*virtual*/ std::string getCurrentElementName();
private:
+ void writeSDImpl(LLSD& sd,
+ const LLInitParam::BaseBlock& block,
+ const LLInitParam::predicate_rule_t,
+ const LLInitParam::BaseBlock* diff_block);
+
void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);
template<typename T>
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index eb8e2c9456..9b49e52377 100755
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,5 +28,4 @@
#include "llsingleton.h"
-std::map<std::string, void *> * LLSingletonRegistry::sSingletonMap = NULL;
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 49d99f2cd0..b9cb8e3d41 100755
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -30,38 +30,6 @@
#include <typeinfo>
#include <boost/noncopyable.hpp>
-/// @brief A global registry of all singletons to prevent duplicate allocations
-/// across shared library boundaries
-class LL_COMMON_API LLSingletonRegistry {
- private:
- typedef std::map<std::string, void *> TypeMap;
- static TypeMap * sSingletonMap;
-
- static void checkInit()
- {
- if(sSingletonMap == NULL)
- {
- sSingletonMap = new TypeMap();
- }
- }
-
- public:
- template<typename T> static void * & get()
- {
- std::string name(typeid(T).name());
-
- checkInit();
-
- // the first entry of the pair returned by insert will be either the existing
- // iterator matching our key, or the newly inserted NULL initialized entry
- // see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
- TypeMap::iterator result =
- sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
-
- return result->second;
- }
-};
-
// LLSingleton implements the getInstance() method part of the Singleton
// pattern. It can't make the derived class constructors protected, though, so
// you have to do that yourself.
@@ -99,22 +67,30 @@ private:
INITIALIZED,
DELETED
} EInitState;
+
+ static DERIVED_TYPE* constructSingleton()
+ {
+ return new DERIVED_TYPE();
+ }
// stores pointer to singleton instance
- // and tracks initialization state of singleton
- struct SingletonInstanceData
+ struct SingletonLifetimeManager
{
- EInitState mInitState;
- DERIVED_TYPE* mSingletonInstance;
-
- SingletonInstanceData()
- : mSingletonInstance(NULL),
- mInitState(UNINITIALIZED)
- {}
-
- ~SingletonInstanceData()
+ SingletonLifetimeManager()
+ {
+ construct();
+ }
+
+ static void construct()
{
- if (mInitState != DELETED)
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = constructSingleton();
+ sData.mInitState = INITIALIZING;
+ }
+
+ ~SingletonLifetimeManager()
+ {
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
@@ -124,9 +100,8 @@ private:
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -151,50 +126,49 @@ public:
*/
static void deleteSingleton()
{
- delete getData().mSingletonInstance;
- getData().mSingletonInstance = NULL;
- getData().mInitState = DELETED;
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
- static SingletonInstanceData& getData()
- {
- // this is static to cache the lookup results
- static void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>();
-
- // *TODO - look into making this threadsafe
- if(NULL == registry)
- {
- static SingletonInstanceData data;
- registry = &data;
- }
-
- return *static_cast<SingletonInstanceData *>(registry);
- }
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getData();
+ static SingletonLifetimeManager sLifeTimeMgr;
- if (data.mInitState == CONSTRUCTING)
+ switch (sData.mInitState)
{
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ return NULL;
+ case CONSTRUCTING:
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
- }
-
- if (data.mInitState == DELETED)
- {
+ return NULL;
+ case INITIALIZING:
+ // go ahead and flag ourselves as initialized so we can be reentrant during initialization
+ sData.mInitState = INITIALIZED;
+ // initialize singleton after constructing it so that it can reference other singletons which in turn depend on it,
+ // thus breaking cyclic dependencies
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ SingletonLifetimeManager::construct();
+ // same as first time construction
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
}
-
- if (!data.mSingletonInstance)
- {
- data.mInitState = CONSTRUCTING;
- data.mSingletonInstance = new DERIVED_TYPE();
- data.mInitState = INITIALIZING;
- data.mSingletonInstance->initSingleton();
- data.mInitState = INITIALIZED;
- }
-
- return data.mSingletonInstance;
+
+ return NULL;
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -208,18 +182,31 @@ public:
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return getData().mInitState == INITIALIZED;
+ return sData.mInitState == INITIALIZED;
}
// Has this singleton already been deleted?
// Use this to avoid accessing singletons from a static object's destructor
static bool destroyed()
{
- return getData().mInitState == DELETED;
+ return sData.mInitState == DELETED;
}
private:
+
virtual void initSingleton() {}
+
+ struct SingletonData
+ {
+ // explicitly has a default constructor so that member variables are zero initialized in BSS
+ // and only changed by singleton logic, not constructor running during startup
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
+ static SingletonData sData;
};
+template<typename T>
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
+
#endif
diff --git a/indra/llcommon/llskiplist.h b/indra/llcommon/llskiplist.h
deleted file mode 100755
index ed132381f9..0000000000
--- a/indra/llcommon/llskiplist.h
+++ /dev/null
@@ -1,517 +0,0 @@
-/**
- * @file llskiplist.h
- * @brief skip list 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$
- */
-#ifndef LL_LLSKIPLIST_H
-#define LL_LLSKIPLIST_H
-
-#include "llrand.h"
-#include "llrand.h"
-
-// NOTA BENE: Insert first needs to be < NOT <=
-// Binary depth must be >= 2
-template <class DATA_TYPE, S32 BINARY_DEPTH = 10>
-class LLSkipList
-{
-public:
- typedef BOOL (*compare)(const DATA_TYPE& first, const DATA_TYPE& second);
- typedef compare insert_func;
- typedef compare equals_func;
-
- void init();
-
- // basic constructor
- LLSkipList();
-
- // basic constructor including sorter
- LLSkipList(insert_func insert_first, equals_func equals);
- ~LLSkipList();
-
- inline void setInsertFirst(insert_func insert_first);
- inline void setEquals(equals_func equals);
-
- inline BOOL addData(const DATA_TYPE& data);
- inline BOOL checkData(const DATA_TYPE& data);
-
- // returns number of items in the list
- inline S32 getLength() const; // NOT a constant time operation, traverses entire list!
-
- inline BOOL moveData(const DATA_TYPE& data, LLSkipList *newlist);
-
- inline BOOL removeData(const DATA_TYPE& data);
-
- // remove all nodes from the list but do not delete data
- inline void removeAllNodes();
-
- // place mCurrentp on first node
- inline void resetList();
-
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- inline DATA_TYPE getCurrentData();
-
- // same as getCurrentData() but a more intuitive name for the operation
- inline DATA_TYPE getNextData();
-
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- inline void removeCurrentData();
-
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- inline DATA_TYPE getFirstData();
-
- class LLSkipNode
- {
- public:
- LLSkipNode()
- : mData(0)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- }
-
- LLSkipNode(DATA_TYPE data)
- : mData(data)
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
- }
-
- ~LLSkipNode()
- {
- }
-
- DATA_TYPE mData;
- LLSkipNode *mForward[BINARY_DEPTH];
-
- private:
- // Disallow copying of LLSkipNodes by not implementing these methods.
- LLSkipNode(const LLSkipNode &);
- LLSkipNode &operator=(const LLSkipNode &);
- };
-
- static BOOL defaultEquals(const DATA_TYPE& first, const DATA_TYPE& second)
- {
- return first == second;
- }
-
-private:
- LLSkipNode mHead;
- LLSkipNode *mUpdate[BINARY_DEPTH];
- LLSkipNode *mCurrentp;
- LLSkipNode *mCurrentOperatingp;
- S32 mLevel;
- insert_func mInsertFirst;
- equals_func mEquals;
-
-private:
- // Disallow copying of LLSkipNodes by not implementing these methods.
- LLSkipList(const LLSkipList &);
- LLSkipList &operator=(const LLSkipList &);
-};
-
-
-///////////////////////
-//
-// Implementation
-//
-
-
-// Binary depth must be >= 2
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::init()
-{
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mLevel = 1;
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-
-// basic constructor
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList()
-: mInsertFirst(NULL),
- mEquals(defaultEquals)
-{
- init();
-}
-
-// basic constructor including sorter
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList(insert_func insert,
- equals_func equals)
-: mInsertFirst(insert),
- mEquals(equals)
-{
- init();
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::~LLSkipList()
-{
- removeAllNodes();
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(insert_func insert_first)
-{
- mInsertFirst = insert_first;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(equals_func equals)
-{
- mEquals = equals;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::addData(const DATA_TYPE& data)
-{
- S32 level;
- LLSkipNode *current = &mHead;
- LLSkipNode *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (ll_frand() < 0.5f)
- break;
- }
-
- LLSkipNode *snode = new LLSkipNode(data);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return TRUE;
-}
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE& data)
-{
- S32 level;
- LLSkipNode *current = &mHead;
- LLSkipNode *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
-
- if (current)
- {
- return mEquals(current->mData, data);
- }
-
- return FALSE;
-}
-
-// returns number of items in the list
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline S32 LLSkipList<DATA_TYPE, BINARY_DEPTH>::getLength() const
-{
- U32 length = 0;
- for (LLSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
- {
- length++;
- }
- return length;
-}
-
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE& data, LLSkipList *newlist)
-{
- BOOL removed = removeData(data);
- BOOL added = newlist->addData(data);
- return removed && added;
-}
-
-
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE& data)
-{
- S32 level;
- LLSkipNode *current = &mHead;
- LLSkipNode *temp;
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mData, data)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mData < data))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
-
- if (!current)
- {
- // empty list or beyond the end!
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mData, data))
- {
- // nope!
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = current->mForward[0];
- }
-
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = current->mForward[0];
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (mUpdate[level]->mForward[level] != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- mUpdate[level]->mForward[level] = current->mForward[level];
- }
-
- // clean up cuurent
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!mHead.mForward[mLevel - 1]))
- {
- mLevel--;
- }
- }
- return TRUE;
-}
-
-// remove all nodes from the list but do not delete data
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes()
-{
- LLSkipNode *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// place mCurrentp on first node
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::resetList()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_TYPE)0; // equivalent, but no warning
- }
-}
-
-// same as getCurrentData() but a more intuitive name for the operation
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_TYPE)0; // equivalent, but no warning
- }
-}
-
-// remove the Node at mCurentOperatingp
-// leave mCurrentp and mCurentOperatingp on the next entry
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
-{
- if (mCurrentOperatingp)
- {
- removeData(mCurrentOperatingp->mData);
- }
-}
-
-// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- //return NULL; // causes compile warning
- return (DATA_TYPE)0; // equivalent, but no warning
- }
-}
-
-
-#endif
diff --git a/indra/llcommon/llskipmap.h b/indra/llcommon/llskipmap.h
deleted file mode 100755
index 49ff2928d1..0000000000
--- a/indra/llcommon/llskipmap.h
+++ /dev/null
@@ -1,1022 +0,0 @@
-/**
- * @file llskipmap.h
- * @brief Associative container based on the skiplist algorithm.
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSKIPMAP_H
-#define LL_LLSKIPMAP_H
-
-#include "llerror.h"
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH = 8>
-class LLSkipMap
-{
-public:
- // basic constructor
- LLSkipMap();
-
- // basic constructor including sorter
- LLSkipMap(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second),
- BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second));
-
- ~LLSkipMap();
-
- void setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second));
- void setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second));
-
- DATA_TYPE &addData(const INDEX_TYPE &index, DATA_TYPE datap);
- DATA_TYPE &addData(const INDEX_TYPE &index);
- DATA_TYPE &getData(const INDEX_TYPE &index);
- DATA_TYPE &operator[](const INDEX_TYPE &index);
-
- // If index present, returns data.
- // If index not present, adds <index,NULL> and returns NULL.
- DATA_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry);
-
- // Returns TRUE if data present in map.
- BOOL checkData(const INDEX_TYPE &index);
-
- // Returns TRUE if key is present in map. This is useful if you
- // are potentially storing NULL pointers in the map
- BOOL checkKey(const INDEX_TYPE &index);
-
- // If there, returns the data.
- // If not, returns NULL.
- // Never adds entries to the map.
- DATA_TYPE getIfThere(const INDEX_TYPE &index);
-
- INDEX_TYPE reverseLookup(const DATA_TYPE datap);
-
- // returns number of items in the list
- S32 getLength(); // WARNING! getLength is O(n), not O(1)!
-
- BOOL removeData(const INDEX_TYPE &index);
-
- // remove all nodes from the list but do not delete data
- void removeAllData();
-
- // place mCurrentp on first node
- void resetList();
-
- // return the data currently pointed to
- DATA_TYPE getCurrentDataWithoutIncrement();
-
- // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_TYPE getCurrentData();
-
- // same as getCurrentData() but a more intuitive name for the operation
- DATA_TYPE getNextData();
-
- INDEX_TYPE getNextKey();
-
- // return the key currently pointed to
- INDEX_TYPE getCurrentKeyWithoutIncrement();
-
- // The internal iterator is at the end of the list.
- BOOL notDone() const;
-
- // remove the Node at mCurentOperatingp
- // leave mCurrentp and mCurentOperatingp on the next entry
- void removeCurrentData();
-
- void deleteCurrentData();
-
- // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
- DATA_TYPE getFirstData();
-
- INDEX_TYPE getFirstKey();
-
- class LLSkipMapNode
- {
- public:
- LLSkipMapNode()
- {
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- U8 *zero = (U8 *)&mIndex;
-
- for (i = 0; i < (S32)sizeof(INDEX_TYPE); i++)
- {
- *(zero + i) = 0;
- }
-
- zero = (U8 *)&mData;
-
- for (i = 0; i < (S32)sizeof(DATA_TYPE); i++)
- {
- *(zero + i) = 0;
- }
- }
-
- LLSkipMapNode(const INDEX_TYPE &index)
- : mIndex(index)
- {
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- U8 *zero = (U8 *)&mData;
-
- for (i = 0; i < (S32)sizeof(DATA_TYPE); i++)
- {
- *(zero + i) = 0;
- }
- }
-
- LLSkipMapNode(const INDEX_TYPE &index, DATA_TYPE datap)
- : mIndex(index)
- {
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mForward[i] = NULL;
- }
-
- mData = datap;
- }
-
- ~LLSkipMapNode()
- {
- }
-
-
- INDEX_TYPE mIndex;
- DATA_TYPE mData;
- LLSkipMapNode *mForward[BINARY_DEPTH];
-
- private:
- // Disallow copying of LLSkipMapNodes by not implementing these methods.
- LLSkipMapNode(const LLSkipMapNode &);
- LLSkipMapNode &operator=(const LLSkipMapNode &rhs);
- };
-
- static BOOL defaultEquals(const INDEX_TYPE &first, const INDEX_TYPE &second)
- {
- return first == second;
- }
-
-private:
- // don't generate implicit copy constructor or copy assignment
- LLSkipMap(const LLSkipMap &);
- LLSkipMap &operator=(const LLSkipMap &);
-
-private:
- LLSkipMapNode mHead;
- LLSkipMapNode *mUpdate[BINARY_DEPTH];
- LLSkipMapNode *mCurrentp;
- LLSkipMapNode *mCurrentOperatingp;
- S32 mLevel;
- BOOL (*mInsertFirst)(const INDEX_TYPE &first, const INDEX_TYPE &second);
- BOOL (*mEquals)(const INDEX_TYPE &first, const INDEX_TYPE &second);
- S32 mNumberOfSteps;
-};
-
-//////////////////////////////////////////////////
-//
-// LLSkipMap implementation
-//
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap()
- : mInsertFirst(NULL),
- mEquals(defaultEquals)
-{
- // Skipmaps must have binary depth of at least 2
- cassert(BINARY_DEPTH >= 2);
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mUpdate[i] = NULL;
- }
- mLevel = 1;
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second),
- BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second))
- : mInsertFirst(insert_first),
- mEquals(equals)
-{
- // Skipmaps must have binary depth of at least 2
- cassert(BINARY_DEPTH >= 2);
-
- mLevel = 1;
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::~LLSkipMap()
-{
- removeAllData();
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second))
-{
- mInsertFirst = insert_first;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second))
-{
- mEquals = equals;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index, DATA_TYPE datap)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // replace the existing data if a node is already there
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
- current->mData = datap;
- return current->mData;
- }
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (rand() & 1)
- {
- break;
- }
- }
-
- LLSkipMapNode *snode = new LLSkipMapNode(index, datap);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (rand() & 1)
- break;
- }
-
- LLSkipMapNode *snode = new LLSkipMapNode(index);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
- return snode->mData;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
- mNumberOfSteps++;
-
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
-
- // now add the new node
- S32 newlevel;
- for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
- {
- if (rand() & 1)
- break;
- }
-
- LLSkipMapNode *snode = new LLSkipMapNode(index);
-
- if (newlevel > mLevel)
- {
- mHead.mForward[mLevel] = NULL;
- mUpdate[mLevel] = &mHead;
- mLevel = newlevel;
- }
-
- for (level = 0; level < newlevel; level++)
- {
- snode->mForward[level] = mUpdate[level]->mForward[level];
- mUpdate[level]->mForward[level] = snode;
- }
-
- return snode->mData;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::operator[](const INDEX_TYPE &index)
-{
-
- return getData(index);
-}
-
-// If index present, returns data.
-// If index not present, adds <index,NULL> and returns NULL.
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index, BOOL &b_new_entry)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
-
- if ( (current)
- &&(mEquals(current->mIndex, index)))
- {
-
- return current->mData;
- }
- b_new_entry = TRUE;
- addData(index);
-
- return current->mData;
-}
-
-// Returns TRUE if data present in map.
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkData(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (current)
- {
- // Gets rid of some compiler ambiguity for the LLPointer<> templated class.
- if (current->mData)
- {
- return mEquals(current->mIndex, index);
- }
- }
-
- return FALSE;
-}
-
-// Returns TRUE if key is present in map. This is useful if you
-// are potentially storing NULL pointers in the map
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkKey(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (current)
- {
- return mEquals(current->mIndex, index);
- }
-
- return FALSE;
-}
-
-// If there, returns the data.
-// If not, returns NULL.
-// Never adds entries to the map.
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getIfThere(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- mNumberOfSteps = 0;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- mNumberOfSteps++;
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- mNumberOfSteps++;
- current = *current->mForward;
-
- if (current)
- {
- if (mEquals(current->mIndex, index))
- {
- return current->mData;
- }
- }
-
- // Avoid Linux compiler warning on returning NULL.
- return DATA_TYPE();
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::reverseLookup(const DATA_TYPE datap)
-{
- LLSkipMapNode *current = &mHead;
-
- while (current)
- {
- if (datap == current->mData)
- {
-
- return current->mIndex;
- }
- current = *current->mForward;
- }
-
- // not found! return NULL
- return INDEX_TYPE();
-}
-
-// returns number of items in the list
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline S32 LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getLength()
-{
- U32 length = 0;
- for (LLSkipMapNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0])
- {
- length++;
- }
-
- return length;
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeData(const INDEX_TYPE &index)
-{
- S32 level;
- LLSkipMapNode *current = &mHead;
- LLSkipMapNode *temp;
-
- // find the pointer one in front of the one we want
- if (mInsertFirst)
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(mInsertFirst(temp->mIndex, index)))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
- else
- {
- for (level = mLevel - 1; level >= 0; level--)
- {
- temp = *(current->mForward + level);
- while ( (temp)
- &&(temp->mIndex < index))
- {
- current = temp;
- temp = *(current->mForward + level);
- }
- *(mUpdate + level) = current;
- }
- }
-
- // we're now just in front of where we want to be . . . take one step forward
- current = *current->mForward;
-
- if (!current)
- {
- // empty list or beyond the end!
-
- return FALSE;
- }
-
- // is this the one we want?
- if (!mEquals(current->mIndex, index))
- {
- // nope!
-
- return FALSE;
- }
- else
- {
- // do we need to fix current or currentop?
- if (current == mCurrentp)
- {
- mCurrentp = *current->mForward;
- }
-
- if (current == mCurrentOperatingp)
- {
- mCurrentOperatingp = *current->mForward;
- }
- // yes it is! change pointers as required
- for (level = 0; level < mLevel; level++)
- {
- if (*((*(mUpdate + level))->mForward + level) != current)
- {
- // cool, we've fixed all the pointers!
- break;
- }
- *((*(mUpdate + level))->mForward + level) = *(current->mForward + level);
- }
-
- delete current;
-
- // clean up mHead
- while ( (mLevel > 1)
- &&(!*(mHead.mForward + mLevel - 1)))
- {
- mLevel--;
- }
- }
-
- return TRUE;
-}
-
-
-// remove all nodes from the list but do not delete data
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeAllData()
-{
- LLSkipMapNode *temp;
- // reset mCurrentp
- mCurrentp = *(mHead.mForward);
-
- while (mCurrentp)
- {
- temp = mCurrentp->mForward[0];
- delete mCurrentp;
- mCurrentp = temp;
- }
-
- S32 i;
- for (i = 0; i < BINARY_DEPTH; i++)
- {
- mHead.mForward[i] = NULL;
- mUpdate[i] = NULL;
- }
-
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-
-// place mCurrentp on first node
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::resetList()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
-}
-
-
-// return the data currently pointed to
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentDataWithoutIncrement()
-{
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mData;
- }
- else
- {
- return DATA_TYPE();
- }
-}
-
-// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- // Basic types, like int, have default constructors that initialize
- // them to zero. g++ 2.95 supports this. "int()" is zero.
- // This also is nice for LLUUID()
- return DATA_TYPE();
- }
-}
-
-// same as getCurrentData() but a more intuitive name for the operation
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextData()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- // Basic types, like int, have default constructors that initialize
- // them to zero. g++ 2.95 supports this. "int()" is zero.
- // This also is nice for LLUUID()
- return DATA_TYPE();
- }
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextKey()
-{
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
-}
-
-// return the key currently pointed to
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentKeyWithoutIncrement()
-{
- if (mCurrentOperatingp)
- {
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- // See comment for getNextData()
- return INDEX_TYPE();
- }
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::notDone() const
-{
- if (mCurrentOperatingp)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-
-// remove the Node at mCurentOperatingp
-// leave mCurrentp and mCurentOperatingp on the next entry
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeCurrentData()
-{
- if (mCurrentOperatingp)
- {
- removeData(mCurrentOperatingp->mIndex);
- }
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::deleteCurrentData()
-{
- if (mCurrentOperatingp)
- {
- deleteData(mCurrentOperatingp->mIndex);
- }
-}
-
-// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstData()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mData;
- }
- else
- {
- // See comment for getNextData()
- return DATA_TYPE();
- }
-}
-
-template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH>
-inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstKey()
-{
- mCurrentp = *(mHead.mForward);
- mCurrentOperatingp = *(mHead.mForward);
- if (mCurrentp)
- {
- mCurrentOperatingp = mCurrentp;
- mCurrentp = mCurrentp->mForward[0];
- return mCurrentOperatingp->mIndex;
- }
- else
- {
- return mHead.mIndex;
- }
-}
-
-#endif
diff --git a/indra/llcommon/llsortedvector.h b/indra/llcommon/llsortedvector.h
deleted file mode 100755
index 391b82ee44..0000000000
--- a/indra/llcommon/llsortedvector.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * @file llsortedvector.h
- * @author Nat Goodspeed
- * @date 2012-04-08
- * @brief LLSortedVector class wraps a vector that we maintain in sorted
- * order so we can perform binary-search lookups.
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLSORTEDVECTOR_H)
-#define LL_LLSORTEDVECTOR_H
-
-#include <vector>
-#include <algorithm>
-
-/**
- * LLSortedVector contains a std::vector<std::pair> that we keep sorted on the
- * first of the pair. This makes insertion somewhat more expensive than simple
- * std::vector::push_back(), but allows us to use binary search for lookups.
- * It's intended for small aggregates where lookup is far more performance-
- * critical than insertion; in such cases a binary search on a small, sorted
- * std::vector can be more performant than a std::map lookup.
- */
-template <typename KEY, typename VALUE>
-class LLSortedVector
-{
-public:
- typedef LLSortedVector<KEY, VALUE> self;
- typedef KEY key_type;
- typedef VALUE mapped_type;
- typedef std::pair<key_type, mapped_type> value_type;
- typedef std::vector<value_type> PairVector;
- typedef typename PairVector::iterator iterator;
- typedef typename PairVector::const_iterator const_iterator;
-
- /// Empty
- LLSortedVector() {}
-
- /// Fixed initial size
- LLSortedVector(std::size_t size):
- mVector(size)
- {}
-
- /// Bulk load
- template <typename ITER>
- LLSortedVector(ITER begin, ITER end):
- mVector(begin, end)
- {
- // Allow caller to dump in a bunch of (pairs convertible to)
- // value_type if desired, but make sure we sort afterwards.
- std::sort(mVector.begin(), mVector.end());
- }
-
- /// insert(key, value)
- std::pair<iterator, bool> insert(const key_type& key, const mapped_type& value)
- {
- return insert(value_type(key, value));
- }
-
- /// insert(value_type)
- std::pair<iterator, bool> insert(const value_type& pair)
- {
- typedef std::pair<iterator, bool> iterbool;
- iterator found = std::lower_bound(mVector.begin(), mVector.end(), pair,
- less<value_type>());
- // have to check for end() before it's even valid to dereference
- if (found == mVector.end())
- {
- std::size_t index(mVector.size());
- mVector.push_back(pair);
- // don't forget that push_back() invalidates 'found'
- return iterbool(mVector.begin() + index, true);
- }
- if (found->first == pair.first)
- {
- return iterbool(found, false);
- }
- // remember that insert() invalidates 'found' -- save index
- std::size_t index(found - mVector.begin());
- mVector.insert(found, pair);
- // okay, convert from index back to iterator
- return iterbool(mVector.begin() + index, true);
- }
-
- iterator begin() { return mVector.begin(); }
- iterator end() { return mVector.end(); }
- const_iterator begin() const { return mVector.begin(); }
- const_iterator end() const { return mVector.end(); }
-
- bool empty() const { return mVector.empty(); }
- std::size_t size() const { return mVector.size(); }
-
- /// find
- iterator find(const key_type& key)
- {
- iterator found = std::lower_bound(mVector.begin(), mVector.end(),
- value_type(key, mapped_type()),
- less<value_type>());
- if (found == mVector.end() || found->first != key)
- return mVector.end();
- return found;
- }
-
- const_iterator find(const key_type& key) const
- {
- return const_cast<self*>(this)->find(key);
- }
-
-private:
- // Define our own 'less' comparator so we can specialize without messing
- // with std::less.
- template <typename T>
- struct less: public std::less<T> {};
-
- // Specialize 'less' for an LLSortedVector::value_type involving
- // std::type_info*. This is one of LLSortedVector's foremost use cases. We
- // specialize 'less' rather than just defining a specific comparator
- // because LLSortedVector should be usable for other key_types as well.
- template <typename T>
- struct less< std::pair<std::type_info*, T> >:
- public std::binary_function<std::pair<std::type_info*, T>,
- std::pair<std::type_info*, T>,
- bool>
- {
- bool operator()(const std::pair<std::type_info*, T>& lhs,
- const std::pair<std::type_info*, T>& rhs) const
- {
- return lhs.first->before(*rhs.first);
- }
- };
-
- // Same as above, but with const std::type_info*.
- template <typename T>
- struct less< std::pair<const std::type_info*, T> >:
- public std::binary_function<std::pair<const std::type_info*, T>,
- std::pair<const std::type_info*, T>,
- bool>
- {
- bool operator()(const std::pair<const std::type_info*, T>& lhs,
- const std::pair<const std::type_info*, T>& rhs) const
- {
- return lhs.first->before(*rhs.first);
- }
- };
-
- PairVector mVector;
-};
-
-#endif /* ! defined(LL_LLSORTEDVECTOR_H) */
diff --git a/indra/llcommon/llstack.h b/indra/llcommon/llstack.h
deleted file mode 100755
index 315de6ba2d..0000000000
--- a/indra/llcommon/llstack.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file llstack.h
- * @brief LLStack template class
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSTACK_H
-#define LL_LLSTACK_H
-
-#include "linked_lists.h"
-
-template <class DATA_TYPE> class LLStack
-{
-private:
- LLLinkedList<DATA_TYPE> mStack;
-
-public:
- LLStack() {}
- ~LLStack() {}
-
- void push(DATA_TYPE *data) { mStack.addData(data); }
- DATA_TYPE *pop() { DATA_TYPE *tempp = mStack.getFirstData(); mStack.removeCurrentData(); return tempp; }
- void deleteAllData() { mStack.deleteAllData(); }
- void removeAllNodes() { mStack.removeAllNodes(); }
-};
-
-#endif
-
diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp
index ccd7ef91c2..e0e9056380 100755
--- a/indra/llcommon/llstacktrace.cpp
+++ b/indra/llcommon/llstacktrace.cpp
@@ -32,7 +32,7 @@
#include <iostream>
#include <sstream>
-#include "windows.h"
+#include "llwin32headerslean.h"
#include "Dbghelp.h"
typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp
deleted file mode 100755
index 3678c8e1c1..0000000000
--- a/indra/llcommon/llstat.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/**
- * @file llstat.cpp
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llstat.h"
-#include "lllivefile.h"
-#include "llerrorcontrol.h"
-#include "llframetimer.h"
-#include "timing.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "llstl.h"
-#include "u64.h"
-
-
-// statics
-//------------------------------------------------------------------------
-LLTimer LLStat::sTimer;
-LLFrameTimer LLStat::sFrameTimer;
-
-void LLStat::reset()
-{
- mNumValues = 0;
- mLastValue = 0.f;
- delete[] mBins;
- mBins = new ValueEntry[mNumBins];
- mCurBin = mNumBins-1;
- mNextBin = 0;
-}
-
-LLStat::LLStat(std::string name, S32 num_bins, BOOL use_frame_timer)
-: mUseFrameTimer(use_frame_timer),
- mNumBins(num_bins),
- mName(name),
- mBins(NULL)
-{
- llassert(mNumBins > 0);
- mLastTime = 0.f;
-
- reset();
-
- if (!mName.empty())
- {
- stat_map_t::iterator iter = getStatList().find(mName);
- if (iter != getStatList().end())
- llwarns << "LLStat with duplicate name: " << mName << llendl;
- getStatList().insert(std::make_pair(mName, this));
- }
-}
-
-LLStat::stat_map_t& LLStat::getStatList()
-{
- static LLStat::stat_map_t stat_list;
- return stat_list;
-}
-
-
-LLStat::~LLStat()
-{
- delete[] mBins;
-
- if (!mName.empty())
- {
- // handle multiple entries with the same name
- stat_map_t::iterator iter = getStatList().find(mName);
- while (iter != getStatList().end() && iter->second != this)
- ++iter;
- getStatList().erase(iter);
- }
-}
-
-void LLStat::start()
-{
- if (mUseFrameTimer)
- {
- mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds();
- }
- else
- {
- mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64();
- }
-}
-
-void LLStat::addValue(const F32 value)
-{
- if (mNumValues < mNumBins)
- {
- mNumValues++;
- }
-
- // Increment the bin counters.
- mCurBin++;
- if (mCurBin >= mNumBins)
- {
- mCurBin = 0;
- }
- mNextBin++;
- if (mNextBin >= mNumBins)
- {
- mNextBin = 0;
- }
-
- mBins[mCurBin].mValue = value;
- if (mUseFrameTimer)
- {
- mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds();
- }
- else
- {
- mBins[mCurBin].mTime = sTimer.getElapsedTimeF64();
- }
- mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime);
-
- //this value is used to prime the min/max calls
- mLastTime = mBins[mCurBin].mTime;
- mLastValue = value;
-
- // Set the begin time for the next stat segment.
- mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime;
- mBins[mNextBin].mTime = mBins[mCurBin].mTime;
- mBins[mNextBin].mDT = 0.f;
-}
-
-
-F32 LLStat::getMax() const
-{
- S32 i;
- F32 current_max = mLastValue;
- if (mNumBins == 0)
- {
- current_max = 0.f;
- }
- else
- {
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- if (mBins[i].mValue > current_max)
- {
- current_max = mBins[i].mValue;
- }
- }
- }
- return current_max;
-}
-
-F32 LLStat::getMean() const
-{
- S32 i;
- F32 current_mean = 0.f;
- S32 samples = 0;
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- current_mean += mBins[i].mValue;
- samples++;
- }
-
- // There will be a wrap error at 2^32. :)
- if (samples != 0)
- {
- current_mean /= samples;
- }
- else
- {
- current_mean = 0.f;
- }
- return current_mean;
-}
-
-F32 LLStat::getMin() const
-{
- S32 i;
- F32 current_min = mLastValue;
-
- if (mNumBins == 0)
- {
- current_min = 0.f;
- }
- else
- {
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- if (mBins[i].mValue < current_min)
- {
- current_min = mBins[i].mValue;
- }
- }
- }
- return current_min;
-}
-
-F32 LLStat::getPrev(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
- return mBins[bin].mValue;
-}
-
-F32 LLStat::getPrevPerSec(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
- return mBins[bin].mValue / mBins[bin].mDT;
-}
-
-F32 LLStat::getCurrent() const
-{
- return mBins[mCurBin].mValue;
-}
-
-F32 LLStat::getCurrentPerSec() const
-{
- return mBins[mCurBin].mValue / mBins[mCurBin].mDT;
-}
-
-F32 LLStat::getMeanPerSec() const
-{
- S32 i;
- F32 value = 0.f;
- F32 dt = 0.f;
-
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value += mBins[i].mValue;
- dt += mBins[i].mDT;
- }
-
- if (dt > 0.f)
- {
- return value/dt;
- }
- else
- {
- return 0.f;
- }
-}
-
-F32 LLStat::getMeanDuration() const
-{
- F32 dur = 0.0f;
- S32 count = 0;
- for (S32 i=0; (i < mNumBins) && (i < mNumValues); i++)
- {
- if (i == mNextBin)
- {
- continue;
- }
- dur += mBins[i].mDT;
- count++;
- }
-
- if (count > 0)
- {
- dur /= F32(count);
- return dur;
- }
- else
- {
- return 0.f;
- }
-}
-
-F32 LLStat::getMaxPerSec() const
-{
- F32 value;
-
- if (mNextBin != 0)
- {
- value = mBins[0].mValue/mBins[0].mDT;
- }
- else if (mNumValues > 0)
- {
- value = mBins[1].mValue/mBins[1].mDT;
- }
- else
- {
- value = 0.f;
- }
-
- for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value = llmax(value, mBins[i].mValue/mBins[i].mDT);
- }
- return value;
-}
-
-F32 LLStat::getMinPerSec() const
-{
- S32 i;
- F32 value;
-
- if (mNextBin != 0)
- {
- value = mBins[0].mValue/mBins[0].mDT;
- }
- else if (mNumValues > 0)
- {
- value = mBins[1].mValue/mBins[0].mDT;
- }
- else
- {
- value = 0.f;
- }
-
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value = llmin(value, mBins[i].mValue/mBins[i].mDT);
- }
- return value;
-}
-
-U32 LLStat::getNumValues() const
-{
- return mNumValues;
-}
-
-S32 LLStat::getNumBins() const
-{
- return mNumBins;
-}
-
-S32 LLStat::getNextBin() const
-{
- return mNextBin;
-}
-
-F64 LLStat::getLastTime() const
-{
- return mLastTime;
-}
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
deleted file mode 100755
index 38377a010b..0000000000
--- a/indra/llcommon/llstat.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * @file llstat.h
- * @brief Runtime statistics accumulation.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSTAT_H
-#define LL_LLSTAT_H
-
-#include <map>
-
-#include "lltimer.h"
-#include "llframetimer.h"
-
-class LLSD;
-
-// ----------------------------------------------------------------------------
-class LL_COMMON_API LLStat
-{
-private:
- typedef std::multimap<std::string, LLStat*> stat_map_t;
-
- static stat_map_t& getStatList();
-
-public:
- LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE);
- ~LLStat();
-
- void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
- // the last addValue
- void reset();
- void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
- void addValue(const S32 value) { addValue((F32)value); }
- void addValue(const U32 value) { addValue((F32)value); }
-
- S32 getNextBin() const;
-
- F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
- F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
- F32 getCurrent() const;
- F32 getCurrentPerSec() const;
-
- F32 getMin() const;
- F32 getMinPerSec() const;
- F32 getMean() const;
- F32 getMeanPerSec() const;
- F32 getMeanDuration() const;
- F32 getMax() const;
- F32 getMaxPerSec() const;
-
- U32 getNumValues() const;
- S32 getNumBins() const;
-
- F64 getLastTime() const;
-private:
- BOOL mUseFrameTimer;
- U32 mNumValues;
- U32 mNumBins;
- F32 mLastValue;
- F64 mLastTime;
-
- struct ValueEntry
- {
- ValueEntry()
- : mValue(0.f),
- mBeginTime(0.0),
- mTime(0.0),
- mDT(0.f)
- {}
- F32 mValue;
- F64 mBeginTime;
- F64 mTime;
- F32 mDT;
- };
- ValueEntry* mBins;
- S32 mCurBin;
- S32 mNextBin;
-
- std::string mName;
-
- static LLTimer sTimer;
- static LLFrameTimer sFrameTimer;
-
-public:
- static LLStat* getStat(const std::string& name)
- {
- // return the first stat that matches 'name'
- stat_map_t::iterator iter = getStatList().find(name);
- if (iter != getStatList().end())
- return iter->second;
- else
- return NULL;
- }
-};
-
-#endif // LL_STAT_
diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h
index 81c4085d16..ab9b6709e8 100755
--- a/indra/llcommon/llstatenums.h
+++ b/indra/llcommon/llstatenums.h
@@ -26,7 +26,7 @@
#ifndef LL_LLSTATENUMS_H
#define LL_LLSTATENUMS_H
-enum
+enum ESimStatID
{
LL_SIM_STAT_TIME_DILATION = 0,
LL_SIM_STAT_FPS = 1,
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index d3941e1bc9..424138dad1 100755
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -31,6 +31,7 @@
#include <algorithm>
#include <map>
#include <vector>
+#include <list>
#include <set>
#include <deque>
#include <typeinfo>
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 22c8681983..66c416bfdd 100755
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -28,11 +28,10 @@
#include "llstring.h"
#include "llerror.h"
+#include "llfasttimer.h"
#if LL_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <winsock2.h>
-#include <windows.h>
+#include "llwin32headerslean.h"
#include <winnls.h> // for WideCharToMultiByte
#endif
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index f9702868c8..17893c1910 100755
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -31,8 +31,9 @@
#include <cstdio>
#include <locale>
#include <iomanip>
+#include <algorithm>
#include "llsd.h"
-#include "llfasttimer.h"
+#include "llformat.h"
#if LL_LINUX || LL_SOLARIS
#include <wctype.h>
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 57a6de9060..95bbcbc816 100755
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -42,6 +42,7 @@
#include "llprocessor.h"
#include "llerrorcontrol.h"
#include "llevents.h"
+#include "llformat.h"
#include "lltimer.h"
#include "llsdserialize.h"
#include "llsdutil.h"
@@ -58,9 +59,7 @@
using namespace llsd;
#if LL_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
+# include "llwin32headerslean.h"
# include <psapi.h> // GetPerformanceInfo() et al.
#elif LL_DARWIN
# include <errno.h>
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 1d56a52c32..118568d5ef 100755
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -29,8 +29,11 @@
#include "apr_portable.h"
#include "llthread.h"
+#include "llmutex.h"
#include "lltimer.h"
+#include "lltrace.h"
+#include "lltracethreadrecorder.h"
#if LL_LINUX || LL_SOLARIS
#include <sched.h>
@@ -56,12 +59,17 @@
//
//----------------------------------------------------------------------------
-#if !LL_DARWIN
-U32 ll_thread_local sThreadID = 0;
+#if LL_DARWIN
+// statically allocated thread local storage not supported in Darwin executable formats
+#elif LL_WINDOWS
+U32 __declspec(thread) sThreadID = 0;
+#elif LL_LINUX
+U32 __thread sThreadID = 0;
#endif
U32 LLThread::sIDIter = 0;
+
LL_COMMON_API void assert_main_thread()
{
static U32 s_thread_id = LLThread::currentID();
@@ -85,6 +93,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
{
LLThread *threadp = (LLThread *)datap;
+ LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(LLTrace::getUIThreadRecorder());
+
#if !LL_DARWIN
sThreadID = threadp->mID;
#endif
@@ -97,16 +107,18 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
// We're done with the run function, this thread is done executing now.
threadp->mStatus = STOPPED;
+ delete thread_recorder;
+
return NULL;
}
-
LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
mPaused(FALSE),
mName(name),
mAPRThreadp(NULL),
mStatus(STOPPED)
{
+
mID = ++sIDIter;
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
@@ -152,7 +164,7 @@ void LLThread::shutdown()
//llinfos << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << llendl;
// Now wait a bit for the thread to exit
// It's unclear whether I should even bother doing this - this destructor
- // should netver get called unless we're already stopped, really...
+ // should never get called unless we're already stopped, really...
S32 counter = 0;
const S32 MAX_WAIT = 600;
while (counter < MAX_WAIT)
@@ -282,7 +294,13 @@ void LLThread::setQuitting()
// static
U32 LLThread::currentID()
{
+#if LL_DARWIN
+ // statically allocated thread local storage not supported in Darwin executable formats
return (U32)apr_os_thread_current();
+#else
+ return sThreadID;
+#endif
+
}
// static
@@ -315,155 +333,6 @@ void LLThread::wakeLocked()
//============================================================================
-LLMutex::LLMutex(apr_pool_t *poolp) :
- mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD)
-{
- //if (poolp)
- //{
- // mIsLocalPool = FALSE;
- // mAPRPoolp = poolp;
- //}
- //else
- {
- mIsLocalPool = TRUE;
- apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
- }
- apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
-}
-
-
-LLMutex::~LLMutex()
-{
-#if MUTEX_DEBUG
- //bad assertion, the subclass LLSignal might be "locked", and that's OK
- //llassert_always(!isLocked()); // better not be locked!
-#endif
- apr_thread_mutex_destroy(mAPRMutexp);
- mAPRMutexp = NULL;
- if (mIsLocalPool)
- {
- apr_pool_destroy(mAPRPoolp);
- }
-}
-
-
-void LLMutex::lock()
-{
- if(isSelfLocked())
- { //redundant lock
- mCount++;
- return;
- }
-
- apr_thread_mutex_lock(mAPRMutexp);
-
-#if MUTEX_DEBUG
- // Have to have the lock before we can access the debug info
- U32 id = LLThread::currentID();
- if (mIsLocked[id] != FALSE)
- llerrs << "Already locked in Thread: " << id << llendl;
- mIsLocked[id] = TRUE;
-#endif
-
-#if LL_DARWIN
- mLockingThread = LLThread::currentID();
-#else
- mLockingThread = sThreadID;
-#endif
-}
-
-void LLMutex::unlock()
-{
- if (mCount > 0)
- { //not the root unlock
- mCount--;
- return;
- }
-
-#if MUTEX_DEBUG
- // Access the debug info while we have the lock
- U32 id = LLThread::currentID();
- if (mIsLocked[id] != TRUE)
- llerrs << "Not locked in Thread: " << id << llendl;
- mIsLocked[id] = FALSE;
-#endif
-
- mLockingThread = NO_THREAD;
- apr_thread_mutex_unlock(mAPRMutexp);
-}
-
-bool LLMutex::isLocked()
-{
- apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp);
- if (APR_STATUS_IS_EBUSY(status))
- {
- return true;
- }
- else
- {
- apr_thread_mutex_unlock(mAPRMutexp);
- return false;
- }
-}
-
-bool LLMutex::isSelfLocked()
-{
-#if LL_DARWIN
- return mLockingThread == LLThread::currentID();
-#else
- return mLockingThread == sThreadID;
-#endif
-}
-
-U32 LLMutex::lockingThread() const
-{
- return mLockingThread;
-}
-
-//============================================================================
-
-LLCondition::LLCondition(apr_pool_t *poolp) :
- LLMutex(poolp)
-{
- // base class (LLMutex) has already ensured that mAPRPoolp is set up.
-
- apr_thread_cond_create(&mAPRCondp, mAPRPoolp);
-}
-
-
-LLCondition::~LLCondition()
-{
- apr_thread_cond_destroy(mAPRCondp);
- mAPRCondp = NULL;
-}
-
-
-void LLCondition::wait()
-{
- if (!isLocked())
- { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait
- apr_thread_mutex_lock(mAPRMutexp);
-#if MUTEX_DEBUG
- // avoid asserts on destruction in non-release builds
- U32 id = LLThread::currentID();
- mIsLocked[id] = TRUE;
-#endif
- }
- apr_thread_cond_wait(mAPRCondp, mAPRMutexp);
-}
-
-void LLCondition::signal()
-{
- apr_thread_cond_signal(mAPRCondp);
-}
-
-void LLCondition::broadcast()
-{
- apr_thread_cond_broadcast(mAPRCondp);
-}
-
-//============================================================================
-
//----------------------------------------------------------------------------
//static
@@ -514,7 +383,6 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount()
}
}
-
//============================================================================
LLResponder::~LLResponder()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 0fb89c5613..4a84a14a65 100755
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -31,20 +31,14 @@
#include "llapr.h"
#include "apr_thread_cond.h"
#include "boost/intrusive_ptr.hpp"
+#include "llmutex.h"
-class LLThread;
-class LLMutex;
-class LLCondition;
-
-#if LL_WINDOWS
-#define ll_thread_local __declspec(thread)
-#else
-#define ll_thread_local __thread
-#endif
+LL_COMMON_API void assert_main_thread();
class LL_COMMON_API LLThread
{
private:
+ friend class LLMutex;
static U32 sIDIter;
public:
@@ -98,15 +92,15 @@ private:
BOOL mPaused;
// static function passed to APR thread creation routine
- static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap);
+ static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap);
protected:
std::string mName;
- LLCondition* mRunCondition;
+ class LLCondition* mRunCondition;
LLMutex* mDataLock;
- apr_thread_t *mAPRThreadp;
- apr_pool_t *mAPRPoolp;
+ apr_thread_t* mAPRThreadp;
+ apr_pool_t* mAPRPoolp;
BOOL mIsLocalPool;
EThreadStatus mStatus;
U32 mID;
@@ -114,7 +108,7 @@ protected:
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
// otherwise it will cause severe memory leaking!!! --bao
- LLVolatileAPRPool *mLocalAPRFilePoolp ;
+ LLVolatileAPRPool* mLocalAPRFilePoolp ;
void setQuitting();
@@ -140,75 +134,6 @@ protected:
// mDataLock->unlock();
};
-//============================================================================
-
-#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
-
-class LL_COMMON_API LLMutex
-{
-public:
- typedef enum
- {
- NO_THREAD = 0xFFFFFFFF
- } e_locking_thread;
-
- LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex
- virtual ~LLMutex();
-
- void lock(); // blocks
- void unlock();
- bool isLocked(); // non-blocking, but does do a lock/unlock so not free
- bool isSelfLocked(); //return true if locked in a same thread
- U32 lockingThread() const; //get ID of locking thread
-
-protected:
- apr_thread_mutex_t *mAPRMutexp;
- mutable U32 mCount;
- mutable U32 mLockingThread;
-
- apr_pool_t *mAPRPoolp;
- BOOL mIsLocalPool;
-
-#if MUTEX_DEBUG
- std::map<U32, BOOL> mIsLocked;
-#endif
-};
-
-// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
-class LL_COMMON_API LLCondition : public LLMutex
-{
-public:
- LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well.
- ~LLCondition();
-
- void wait(); // blocks
- void signal();
- void broadcast();
-
-protected:
- apr_thread_cond_t *mAPRCondp;
-};
-
-class LLMutexLock
-{
-public:
- LLMutexLock(LLMutex* mutex)
- {
- mMutex = mutex;
-
- if(mMutex)
- mMutex->lock();
- }
- ~LLMutexLock()
- {
- if(mMutex)
- mMutex->unlock();
- }
-private:
- LLMutex* mMutex;
-};
-
-//============================================================================
void LLThread::lockData()
{
diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp
new file mode 100644
index 0000000000..32d94331a6
--- /dev/null
+++ b/indra/llcommon/llthreadlocalstorage.cpp
@@ -0,0 +1,117 @@
+/**
+ * @file llthreadlocalstorage.cpp
+ * @author Richard
+ * @date 2013-1-11
+ * @brief implementation of thread local storage utility classes
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llthreadlocalstorage.h"
+#include "llapr.h"
+
+//
+//LLThreadLocalPointerBase
+//
+bool LLThreadLocalPointerBase::sInitialized = false;
+
+void LLThreadLocalPointerBase::set( void* value )
+{
+ llassert(sInitialized && mThreadKey);
+
+ apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to set thread local data" << llendl;
+ }
+}
+
+void* LLThreadLocalPointerBase::get() const
+{
+ // llassert(sInitialized);
+ void* ptr;
+ apr_status_t result =
+ apr_threadkey_private_get(&ptr, mThreadKey);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to get thread local data" << llendl;
+ }
+ return ptr;
+}
+
+
+void LLThreadLocalPointerBase::initStorage( )
+{
+ apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to allocate thread local data" << llendl;
+ }
+}
+
+void LLThreadLocalPointerBase::destroyStorage()
+{
+ if (sInitialized)
+ {
+ if (mThreadKey)
+ {
+ apr_status_t result = apr_threadkey_private_delete(mThreadKey);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to delete thread local data" << llendl;
+ }
+ }
+ }
+}
+
+void LLThreadLocalPointerBase::initAllThreadLocalStorage()
+{
+ if (!sInitialized)
+ {
+ for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances();
+ it != end_it;
+ ++it)
+ {
+ (*it).initStorage();
+ }
+ sInitialized = true;
+ }
+}
+
+void LLThreadLocalPointerBase::destroyAllThreadLocalStorage()
+{
+ if (sInitialized)
+ {
+ //for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances();
+ // it != end_it;
+ // ++it)
+ //{
+ // (*it).destroyStorage();
+ //}
+ sInitialized = false;
+ }
+}
diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h
new file mode 100644
index 0000000000..a15f9185b1
--- /dev/null
+++ b/indra/llcommon/llthreadlocalstorage.h
@@ -0,0 +1,357 @@
+/**
+ * @file llthreadlocalstorage.h
+ * @author Richard
+ * @brief Class wrappers for thread local storage
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTHREADLOCALSTORAGE_H
+#define LL_LLTHREADLOCALSTORAGE_H
+
+#include "llinstancetracker.h"
+
+class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
+{
+public:
+ LLThreadLocalPointerBase()
+ : mThreadKey(NULL)
+ {
+ if (sInitialized)
+ {
+ initStorage();
+ }
+ }
+
+ LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
+ : mThreadKey(NULL)
+ {
+ if (sInitialized)
+ {
+ initStorage();
+ }
+ }
+
+ ~LLThreadLocalPointerBase()
+ {
+ destroyStorage();
+ }
+
+ static void initAllThreadLocalStorage();
+ static void destroyAllThreadLocalStorage();
+
+protected:
+ void set(void* value);
+
+ void* get() const;
+
+ void initStorage();
+ void destroyStorage();
+
+protected:
+ struct apr_threadkey_t* mThreadKey;
+ static bool sInitialized;
+};
+
+template <typename T>
+class LLThreadLocalPointer : public LLThreadLocalPointerBase
+{
+public:
+
+ LLThreadLocalPointer()
+ {}
+
+ explicit LLThreadLocalPointer(T* value)
+ {
+ set(value);
+ }
+
+
+ LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
+ : LLThreadLocalPointerBase(other)
+ {
+ set(other.get());
+ }
+
+ LL_FORCE_INLINE T* get() const
+ {
+ return (T*)LLThreadLocalPointerBase::get();
+ }
+
+ T* operator -> () const
+ {
+ return (T*)get();
+ }
+
+ T& operator*() const
+ {
+ return *(T*)get();
+ }
+
+ LLThreadLocalPointer<T>& operator = (T* value)
+ {
+ set((void*)value);
+ return *this;
+ }
+
+ bool operator ==(const T* other) const
+ {
+ if (!sInitialized) return false;
+ return get() == other;
+ }
+
+ bool isNull() const { return !sInitialized || get() == NULL; }
+
+ bool notNull() const { return sInitialized && get() != NULL; }
+};
+
+template<typename DERIVED_TYPE>
+class LLThreadLocalSingleton
+{
+ typedef enum e_init_state
+ {
+ UNINITIALIZED = 0,
+ CONSTRUCTING,
+ INITIALIZING,
+ INITIALIZED,
+ DELETED
+ } EInitState;
+
+public:
+ LLThreadLocalSingleton()
+ {}
+
+ virtual ~LLThreadLocalSingleton()
+ {
+#if LL_DARWIN
+ pthread_setspecific(sInstanceKey, NULL);
+#else
+ sInstance = NULL;
+#endif
+ setInitState(DELETED);
+ }
+
+ static void deleteSingleton()
+ {
+ delete getIfExists();
+ }
+
+ static DERIVED_TYPE* getInstance()
+ {
+ EInitState init_state = getInitState();
+ if (init_state == CONSTRUCTING)
+ {
+ llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
+ }
+
+ if (init_state == DELETED)
+ {
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ }
+
+#if LL_DARWIN
+ createTLSInstance();
+#endif
+ if (!getIfExists())
+ {
+ setInitState(CONSTRUCTING);
+ DERIVED_TYPE* instancep = new DERIVED_TYPE();
+#if LL_DARWIN
+ S32 result = pthread_setspecific(sInstanceKey, (void*)instancep);
+ if (result != 0)
+ {
+ llerrs << "Could not set thread local storage" << llendl;
+ }
+#else
+ sInstance = instancep;
+#endif
+ setInitState(INITIALIZING);
+ instancep->initSingleton();
+ setInitState(INITIALIZED);
+ }
+
+ return getIfExists();
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+#if LL_DARWIN
+ return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey);
+#else
+ return sInstance;
+#endif
+ }
+
+ // Reference version of getInstance()
+ // Preferred over getInstance() as it disallows checking for NULL
+ static DERIVED_TYPE& instance()
+ {
+ return *getInstance();
+ }
+
+ // Has this singleton been created uet?
+ // Use this to avoid accessing singletons before the can safely be constructed
+ static bool instanceExists()
+ {
+ return getInitState() == INITIALIZED;
+ }
+
+ // Has this singleton already been deleted?
+ // Use this to avoid accessing singletons from a static object's destructor
+ static bool destroyed()
+ {
+ return getInitState() == DELETED;
+ }
+private:
+#if LL_DARWIN
+ static void createTLSInitState()
+ {
+ static S32 key_created = pthread_key_create(&sInitStateKey, NULL);
+ if (key_created != 0)
+ {
+ llerrs << "Could not create thread local storage" << llendl;
+ }
+ }
+
+ static void createTLSInstance()
+ {
+ static S32 key_created = pthread_key_create(&sInstanceKey, NULL);
+ if (key_created != 0)
+ {
+ llerrs << "Could not create thread local storage" << llendl;
+ }
+ }
+#endif
+ static EInitState getInitState()
+ {
+#if LL_DARWIN
+ createTLSInitState();
+ return (EInitState)(int)pthread_getspecific(sInitStateKey);
+#else
+ return sInitState;
+#endif
+ }
+
+ static void setInitState(EInitState state)
+ {
+#if LL_DARWIN
+ createTLSInitState();
+ pthread_setspecific(sInitStateKey, (void*)state);
+#else
+ sInitState = state;
+#endif
+ }
+ LLThreadLocalSingleton(const LLThreadLocalSingleton& other);
+ virtual void initSingleton() {}
+
+#ifdef LL_WINDOWS
+ static __declspec(thread) DERIVED_TYPE* sInstance;
+ static __declspec(thread) EInitState sInitState;
+#elif LL_LINUX
+ static __thread DERIVED_TYPE* sInstance;
+ static __thread EInitState sInitState;
+#elif LL_DARWIN
+ static pthread_key_t sInstanceKey;
+ static pthread_key_t sInitStateKey;
+#endif
+};
+
+#if LL_WINDOWS
+template<typename DERIVED_TYPE>
+__declspec(thread) DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL;
+
+template<typename DERIVED_TYPE>
+__declspec(thread) typename LLThreadLocalSingleton<DERIVED_TYPE>::EInitState LLThreadLocalSingleton<DERIVED_TYPE>::sInitState = LLThreadLocalSingleton<DERIVED_TYPE>::UNINITIALIZED;
+#elif LL_LINUX
+template<typename DERIVED_TYPE>
+__thread DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL;
+
+template<typename DERIVED_TYPE>
+__thread typename LLThreadLocalSingleton<DERIVED_TYPE>::EInitState LLThreadLocalSingleton<DERIVED_TYPE>::sInitState = LLThreadLocalSingleton<DERIVED_TYPE>::UNINITIALIZED;
+#elif LL_DARWIN
+template<typename DERIVED_TYPE>
+pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInstanceKey;
+
+template<typename DERIVED_TYPE>
+pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInitStateKey;
+
+#endif
+
+template<typename DERIVED_TYPE>
+class LLThreadLocalSingletonPointer
+{
+public:
+ LL_FORCE_INLINE static DERIVED_TYPE* getInstance()
+ {
+#if LL_DARWIN
+ createTLSKey();
+ return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey);
+#else
+ return sInstance;
+#endif
+ }
+
+ static void setInstance(DERIVED_TYPE* instance)
+ {
+#if LL_DARWIN
+ createTLSKey();
+ pthread_setspecific(sInstanceKey, (void*)instance);
+#else
+ sInstance = instance;
+#endif
+ }
+
+private:
+
+#if LL_WINDOWS
+ static __declspec(thread) DERIVED_TYPE* sInstance;
+#elif LL_LINUX
+ static __thread DERIVED_TYPE* sInstance;
+#elif LL_DARWIN
+ static void TLSError()
+ {
+ llerrs << "Could not create thread local storage" << llendl;
+ }
+ static void createTLSKey()
+ {
+ static S32 key_created = pthread_key_create(&sInstanceKey, NULL);
+ if (key_created != 0)
+ {
+ llerrs << "Could not create thread local storage" << llendl;
+ }
+ }
+ static pthread_key_t sInstanceKey;
+#endif
+};
+
+#if LL_WINDOWS
+template<typename DERIVED_TYPE>
+__declspec(thread) DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
+#elif LL_LINUX
+template<typename DERIVED_TYPE>
+__thread DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
+#elif LL_DARWIN
+template<typename DERIVED_TYPE>
+pthread_key_t LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstanceKey;
+#endif
+
+#endif // LL_LLTHREADLOCALSTORAGE_H
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 9ebc6de7f4..693809b622 100755
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -31,11 +31,9 @@
#include "u64.h"
#if LL_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
+# include "llwin32headerslean.h"
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
-# include <errno.h>
+# include <errno.h>
# include <sys/time.h>
#else
# error "architecture not supported"
@@ -287,14 +285,14 @@ LLTimer::~LLTimer()
}
// static
-U64 LLTimer::getTotalTime()
+LLUnitImplicit<U64, LLUnits::Microseconds> LLTimer::getTotalTime()
{
// simply call into the implementation function.
return totalTime();
}
// static
-F64 LLTimer::getTotalSeconds()
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getTotalSeconds()
{
return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
}
@@ -343,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-F64 LLTimer::getElapsedTimeF64() const
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
}
-F32 LLTimer::getElapsedTimeF32() const
+LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-F64 LLTimer::getElapsedTimeAndResetF64()
+LLUnitImplicit<F64, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF64()
{
return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
}
-F32 LLTimer::getElapsedTimeAndResetF32()
+LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
@@ -372,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration)
+ (U64)((F32)(expiration * gClockFrequency));
}
-F32 LLTimer::getRemainingTimeF32() const
+LLUnitImplicit<F32, LLUnits::Seconds> LLTimer::getRemainingTimeF32() const
{
U64 cur_ticks = get_clock_count();
if (cur_ticks > mExpirationTicks)
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 513de0605d..9e464c4b1a 100755
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -37,6 +37,7 @@
#include <string>
#include <list>
// units conversions
+#include "llunit.h"
#ifndef USEC_PER_SEC
const U32 USEC_PER_SEC = 1000000;
#endif
@@ -55,7 +56,7 @@ public:
protected:
U64 mLastClockCount;
U64 mExpirationTicks;
- BOOL mStarted;
+ bool mStarted;
public:
LLTimer();
@@ -66,16 +67,16 @@ public:
// Return a high precision number of seconds since the start of
// this application instance.
- static F64 getElapsedSeconds()
+ static LLUnitImplicit<F64, LLUnits::Seconds> getElapsedSeconds()
{
return sTimer->getElapsedTimeF64();
}
// Return a high precision usec since epoch
- static U64 getTotalTime();
+ static LLUnitImplicit<U64, LLUnits::Microseconds> getTotalTime();
// Return a high precision seconds since epoch
- static F64 getTotalSeconds();
+ static LLUnitImplicit<F64, LLUnits::Seconds> getTotalSeconds();
// MANIPULATORS
@@ -86,18 +87,18 @@ public:
void setTimerExpirySec(F32 expiration);
BOOL checkExpirationAndReset(F32 expiration);
BOOL hasExpired() const;
- F32 getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
- F64 getElapsedTimeAndResetF64();
+ LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset
+ LLUnitImplicit<F64, LLUnits::Seconds> getElapsedTimeAndResetF64();
- F32 getRemainingTimeF32() const;
+ LLUnitImplicit<F32, LLUnits::Seconds> getRemainingTimeF32() const;
static BOOL knownBadTimer();
// ACCESSORS
- F32 getElapsedTimeF32() const; // Returns elapsed time in seconds
- F64 getElapsedTimeF64() const; // Returns elapsed time in seconds
+ LLUnitImplicit<F32, LLUnits::Seconds> getElapsedTimeF32() const; // Returns elapsed time in seconds
+ LLUnitImplicit<F64, LLUnits::Seconds> getElapsedTimeF64() const; // Returns elapsed time in seconds
- BOOL getStarted() const { return mStarted; }
+ bool getStarted() const { return mStarted; }
static U64 getCurrentClockCount(); // Returns the raw clockticks
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
new file mode 100644
index 0000000000..59a4b42c97
--- /dev/null
+++ b/indra/llcommon/lltrace.cpp
@@ -0,0 +1,116 @@
+/**
+ * @file lltrace.cpp
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltrace.h"
+#include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
+#include "llfasttimer.h"
+
+static S32 sInitializationCount = 0;
+
+namespace LLTrace
+{
+
+static MasterThreadRecorder* gUIThreadRecorder = NULL;
+
+void init()
+{
+ if (sInitializationCount++ == 0)
+ {
+ gUIThreadRecorder = new MasterThreadRecorder();
+ }
+}
+
+bool isInitialized()
+{
+ return sInitializationCount > 0;
+}
+
+void cleanup()
+{
+ if (--sInitializationCount == 0)
+ {
+ delete gUIThreadRecorder;
+ gUIThreadRecorder = NULL;
+ }
+}
+
+MasterThreadRecorder& getUIThreadRecorder()
+{
+ llassert(gUIThreadRecorder != NULL);
+ return *gUIThreadRecorder;
+}
+
+LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
+{
+ static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
+ return s_thread_recorder;
+}
+
+const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
+{
+ return get_thread_recorder_ptr();
+}
+
+void set_thread_recorder(ThreadRecorder* recorder)
+{
+ get_thread_recorder_ptr() = recorder;
+}
+
+
+TimeBlockTreeNode::TimeBlockTreeNode()
+: mBlock(NULL),
+ mParent(NULL),
+ mNeedsSorting(false),
+ mCollapsed(true)
+{}
+
+void TimeBlockTreeNode::setParent( TimeBlock* parent )
+{
+ llassert_always(parent != mBlock);
+ llassert_always(parent != NULL);
+
+ TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(parent->getIndex());
+ if (!parent_tree_node) return;
+
+ if (mParent)
+ {
+ std::vector<TimeBlock*>& children = mParent->getChildren();
+ std::vector<TimeBlock*>::iterator found_it = std::find(children.begin(), children.end(), mBlock);
+ if (found_it != children.end())
+ {
+ children.erase(found_it);
+ }
+ }
+
+ mParent = parent;
+ mBlock->getPrimaryAccumulator()->mParent = parent;
+ parent_tree_node->mChildren.push_back(mBlock);
+ parent_tree_node->mNeedsSorting = true;
+}
+
+}
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
new file mode 100644
index 0000000000..fb7ffb0a29
--- /dev/null
+++ b/indra/llcommon/lltrace.h
@@ -0,0 +1,1099 @@
+/**
+ * @file lltrace.h
+ * @brief Runtime statistics accumulation.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTRACE_H
+#define LL_LLTRACE_H
+
+#include "stdtypes.h"
+#include "llpreprocessor.h"
+
+#include "llmemory.h"
+#include "llrefcount.h"
+#include "llunit.h"
+#include "llthreadlocalstorage.h"
+#include "lltimer.h"
+
+#include <list>
+
+#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::TimeBlock::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer);
+
+namespace LLTrace
+{
+class Recording;
+
+typedef LLUnit<F64, LLUnits::Bytes> Bytes;
+typedef LLUnit<F64, LLUnits::Kibibytes> Kibibytes;
+typedef LLUnit<F64, LLUnits::Mibibytes> Mibibytes;
+typedef LLUnit<F64, LLUnits::Gibibytes> Gibibytes;
+typedef LLUnit<F64, LLUnits::Bits> Bits;
+typedef LLUnit<F64, LLUnits::Kibibits> Kibibits;
+typedef LLUnit<F64, LLUnits::Mibibits> Mibibits;
+typedef LLUnit<F64, LLUnits::Gibibits> Gibibits;
+
+typedef LLUnit<F64, LLUnits::Seconds> Seconds;
+typedef LLUnit<F64, LLUnits::Milliseconds> Milliseconds;
+typedef LLUnit<F64, LLUnits::Minutes> Minutes;
+typedef LLUnit<F64, LLUnits::Hours> Hours;
+typedef LLUnit<F64, LLUnits::Milliseconds> Milliseconds;
+typedef LLUnit<F64, LLUnits::Microseconds> Microseconds;
+typedef LLUnit<F64, LLUnits::Nanoseconds> Nanoseconds;
+
+typedef LLUnit<F64, LLUnits::Meters> Meters;
+typedef LLUnit<F64, LLUnits::Kilometers> Kilometers;
+typedef LLUnit<F64, LLUnits::Centimeters> Centimeters;
+typedef LLUnit<F64, LLUnits::Millimeters> Millimeters;
+
+
+template<typename T>
+T storage_value(T val) { return val; }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE storage_value(LLUnit<STORAGE_TYPE, UNIT_TYPE> val) { return val.value(); }
+
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+STORAGE_TYPE storage_value(LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> val) { return val.value(); }
+
+void init();
+void cleanup();
+bool isInitialized();
+
+const LLThreadLocalPointer<class ThreadRecorder>& get_thread_recorder();
+void set_thread_recorder(class ThreadRecorder*);
+
+class MasterThreadRecorder& getUIThreadRecorder();
+
+template<typename ACCUMULATOR>
+class AccumulatorBuffer : public LLRefCount
+{
+ typedef AccumulatorBuffer<ACCUMULATOR> self_t;
+ static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64;
+private:
+ struct StaticAllocationMarker { };
+
+ AccumulatorBuffer(StaticAllocationMarker m)
+ : mStorageSize(0),
+ mStorage(NULL)
+ {}
+
+public:
+
+ AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer())
+ : mStorageSize(0),
+ mStorage(NULL)
+ {
+ resize(other.mStorageSize);
+ for (S32 i = 0; i < sNextStorageSlot; i++)
+ {
+ mStorage[i] = other.mStorage[i];
+ }
+ }
+
+ ~AccumulatorBuffer()
+ {
+ if (isPrimary())
+ {
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
+ }
+ delete[] mStorage;
+ }
+
+ LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
+ {
+ return mStorage[index];
+ }
+
+ LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
+ {
+ return mStorage[index];
+ }
+
+ void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, bool append = true)
+ {
+ llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot);
+ for (size_t i = 0; i < sNextStorageSlot; i++)
+ {
+ mStorage[i].addSamples(other.mStorage[i], append);
+ }
+ }
+
+ void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
+ {
+ llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot);
+ for (size_t i = 0; i < sNextStorageSlot; i++)
+ {
+ mStorage[i] = other.mStorage[i];
+ }
+ }
+
+ void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
+ {
+ llassert(mStorageSize >= sNextStorageSlot);
+ for (size_t i = 0; i < sNextStorageSlot; i++)
+ {
+ mStorage[i].reset(other ? &other->mStorage[i] : NULL);
+ }
+ }
+
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ {
+ llassert(mStorageSize >= sNextStorageSlot);
+ for (size_t i = 0; i < sNextStorageSlot; i++)
+ {
+ mStorage[i].flush(time_stamp);
+ }
+ }
+
+ void makePrimary()
+ {
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(mStorage);
+ }
+
+ bool isPrimary() const
+ {
+ return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage;
+ }
+
+ LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()
+ {
+ ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
+ return accumulator ? accumulator : getDefaultBuffer()->mStorage;
+ }
+
+ // 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()
+ {
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (LLTrace::isInitialized())
+ {
+ llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl;
+ }
+#endif
+ size_t next_slot = sNextStorageSlot++;
+ if (next_slot >= mStorageSize)
+ {
+ resize(mStorageSize + (mStorageSize >> 2));
+ }
+ llassert(mStorage && next_slot < mStorageSize);
+ return next_slot;
+ }
+
+ void resize(size_t new_size)
+ {
+ if (new_size <= mStorageSize) return;
+
+ ACCUMULATOR* old_storage = mStorage;
+ mStorage = new ACCUMULATOR[new_size];
+ if (old_storage)
+ {
+ for (S32 i = 0; i < mStorageSize; i++)
+ {
+ mStorage[i] = old_storage[i];
+ }
+ }
+ mStorageSize = new_size;
+ delete[] old_storage;
+
+ self_t* default_buffer = getDefaultBuffer();
+ if (this != default_buffer
+ && new_size > default_buffer->size())
+ {
+ //NB: this is not thread safe, but we assume that all resizing occurs during static initialization
+ default_buffer->resize(new_size);
+ }
+ }
+
+ size_t size() const
+ {
+ return getNumIndices();
+ }
+
+ static size_t getNumIndices()
+ {
+ return sNextStorageSlot;
+ }
+
+ static self_t* getDefaultBuffer()
+ {
+ static bool sInitialized = false;
+ if (!sInitialized)
+ {
+ // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data
+ // so as not to trigger an access violation
+ sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker());
+ sInitialized = true;
+ sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
+ }
+ return sDefaultBuffer;
+ }
+
+private:
+ ACCUMULATOR* mStorage;
+ size_t mStorageSize;
+ static size_t sNextStorageSlot;
+ static self_t* sDefaultBuffer;
+};
+
+template<typename ACCUMULATOR> size_t AccumulatorBuffer<ACCUMULATOR>::sNextStorageSlot = 0;
+template<typename ACCUMULATOR> AccumulatorBuffer<ACCUMULATOR>* AccumulatorBuffer<ACCUMULATOR>::sDefaultBuffer = NULL;
+
+template<typename ACCUMULATOR>
+class TraceType
+: public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>
+{
+public:
+ TraceType(const char* name, const char* description = NULL)
+ : LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name),
+ mName(name),
+ mDescription(description ? description : ""),
+ mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
+ {}
+
+ LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const
+ {
+ ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage();
+ return &accumulator_storage[mAccumulatorIndex];
+ }
+
+ size_t getIndex() const { return mAccumulatorIndex; }
+ static size_t getNumIndices() { return AccumulatorBuffer<ACCUMULATOR>::getNumIndices(); }
+
+ virtual const char* getUnitLabel() { return ""; }
+
+ const std::string& getName() const { return mName; }
+
+protected:
+ const std::string mName;
+ const std::string mDescription;
+ const size_t mAccumulatorIndex;
+};
+
+class EventAccumulator
+{
+public:
+ typedef F64 value_t;
+ typedef F64 mean_t;
+
+ EventAccumulator()
+ : mSum(0),
+ mMin((std::numeric_limits<F64>::max)()),
+ mMax((std::numeric_limits<F64>::min)()),
+ mMean(0),
+ mVarianceSum(0),
+ mNumSamples(0),
+ mLastValue(0)
+ {}
+
+ void record(F64 value)
+ {
+ mNumSamples++;
+ mSum += value;
+ // NOTE: both conditions will hold on first pass through
+ if (value < mMin)
+ {
+ mMin = value;
+ }
+ if (value > mMax)
+ {
+ mMax = value;
+ }
+ F64 old_mean = mMean;
+ mMean += (value - old_mean) / (F64)mNumSamples;
+ mVarianceSum += (value - old_mean) * (value - mMean);
+ mLastValue = value;
+ }
+
+ void addSamples(const EventAccumulator& other, bool append)
+ {
+ if (other.mNumSamples)
+ {
+ mSum += other.mSum;
+
+ // NOTE: both conditions will hold first time through
+ if (other.mMin < mMin) { mMin = other.mMin; }
+ if (other.mMax > mMax) { mMax = other.mMax; }
+
+ // combine variance (and hence standard deviation) of 2 different sized sample groups using
+ // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
+ F64 n_1 = (F64)mNumSamples,
+ n_2 = (F64)other.mNumSamples;
+ F64 m_1 = mMean,
+ m_2 = other.mMean;
+ F64 v_1 = mVarianceSum / mNumSamples,
+ v_2 = other.mVarianceSum / other.mNumSamples;
+ if (n_1 == 0)
+ {
+ mVarianceSum = other.mVarianceSum;
+ }
+ else if (n_2 == 0)
+ {
+ // don't touch variance
+ // mVarianceSum = mVarianceSum;
+ }
+ else
+ {
+ mVarianceSum = (F64)mNumSamples
+ * ((((n_1 - 1.f) * v_1)
+ + ((n_2 - 1.f) * v_2)
+ + (((n_1 * n_2) / (n_1 + n_2))
+ * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
+ / (n_1 + n_2 - 1.f));
+ }
+
+ F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples);
+ mNumSamples += other.mNumSamples;
+ mMean = mMean * weight + other.mMean * (1.f - weight);
+ if (append) mLastValue = other.mLastValue;
+ }
+ }
+
+ void reset(const EventAccumulator* other)
+ {
+ mNumSamples = 0;
+ mSum = 0;
+ mMin = std::numeric_limits<F64>::max();
+ mMax = std::numeric_limits<F64>::min();
+ mMean = 0;
+ mVarianceSum = 0;
+ mLastValue = other ? other->mLastValue : 0;
+ }
+
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+
+ F64 getSum() const { return mSum; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
+ F64 getLastValue() const { return mLastValue; }
+ F64 getMean() const { return mMean; }
+ F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); }
+ U32 getSampleCount() const { return mNumSamples; }
+
+private:
+ F64 mSum,
+ mMin,
+ mMax,
+ mLastValue;
+
+ F64 mMean,
+ mVarianceSum;
+
+ U32 mNumSamples;
+};
+
+
+class SampleAccumulator
+{
+public:
+ typedef F64 value_t;
+ typedef F64 mean_t;
+
+ SampleAccumulator()
+ : mSum(0),
+ mMin((std::numeric_limits<F64>::max)()),
+ mMax((std::numeric_limits<F64>::min)()),
+ mMean(0),
+ mVarianceSum(0),
+ mLastSampleTimeStamp(LLTimer::getTotalSeconds()),
+ mTotalSamplingTime(0),
+ mNumSamples(0),
+ mLastValue(0),
+ mHasValue(false)
+ {}
+
+ void sample(F64 value)
+ {
+ LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+ LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
+ mLastSampleTimeStamp = time_stamp;
+
+ if (mHasValue)
+ {
+ mTotalSamplingTime += delta_time;
+ mSum += mLastValue * delta_time;
+
+ // NOTE: both conditions will hold first time through
+ if (value < mMin) { mMin = value; }
+ if (value > mMax) { mMax = value; }
+
+ F64 old_mean = mMean;
+ mMean += (delta_time / mTotalSamplingTime) * (mLastValue - old_mean);
+ mVarianceSum += delta_time * (mLastValue - old_mean) * (mLastValue - mMean);
+ }
+
+ mLastValue = value;
+ mNumSamples++;
+ mHasValue = true;
+ }
+
+ void addSamples(const SampleAccumulator& other, bool append)
+ {
+ if (other.mTotalSamplingTime)
+ {
+ mSum += other.mSum;
+
+ // NOTE: both conditions will hold first time through
+ if (other.mMin < mMin) { mMin = other.mMin; }
+ if (other.mMax > mMax) { mMax = other.mMax; }
+
+ // combine variance (and hence standard deviation) of 2 different sized sample groups using
+ // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
+ F64 n_1 = mTotalSamplingTime,
+ n_2 = other.mTotalSamplingTime;
+ F64 m_1 = mMean,
+ m_2 = other.mMean;
+ F64 v_1 = mVarianceSum / mTotalSamplingTime,
+ v_2 = other.mVarianceSum / other.mTotalSamplingTime;
+ if (n_1 == 0)
+ {
+ mVarianceSum = other.mVarianceSum;
+ }
+ else if (n_2 == 0)
+ {
+ // variance is unchanged
+ // mVarianceSum = mVarianceSum;
+ }
+ else
+ {
+ mVarianceSum = mTotalSamplingTime
+ * ((((n_1 - 1.f) * v_1)
+ + ((n_2 - 1.f) * v_2)
+ + (((n_1 * n_2) / (n_1 + n_2))
+ * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
+ / (n_1 + n_2 - 1.f));
+ }
+
+ llassert(other.mTotalSamplingTime > 0);
+ F64 weight = mTotalSamplingTime / (mTotalSamplingTime + other.mTotalSamplingTime);
+ mNumSamples += other.mNumSamples;
+ mTotalSamplingTime += other.mTotalSamplingTime;
+ mMean = (mMean * weight) + (other.mMean * (1.0 - weight));
+ if (append)
+ {
+ mLastValue = other.mLastValue;
+ mLastSampleTimeStamp = other.mLastSampleTimeStamp;
+ mHasValue |= other.mHasValue;
+ }
+ }
+ }
+
+ void reset(const SampleAccumulator* other)
+ {
+ mNumSamples = 0;
+ mSum = 0;
+ mMin = std::numeric_limits<F64>::max();
+ mMax = std::numeric_limits<F64>::min();
+ mMean = other ? other->mLastValue : 0;
+ mVarianceSum = 0;
+ mLastSampleTimeStamp = LLTimer::getTotalSeconds();
+ mTotalSamplingTime = 0;
+ mLastValue = other ? other->mLastValue : 0;
+ mHasValue = other ? other->mHasValue : false;
+ }
+
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ {
+ LLUnitImplicit<F64, LLUnits::Seconds> delta_time = time_stamp - mLastSampleTimeStamp;
+
+ if (mHasValue)
+ {
+ mSum += mLastValue * delta_time;
+ mTotalSamplingTime += delta_time;
+ }
+ mLastSampleTimeStamp = time_stamp;
+ }
+
+ F64 getSum() const { return mSum; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
+ F64 getLastValue() const { return mLastValue; }
+ F64 getMean() const { return mMean; }
+ F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mTotalSamplingTime); }
+ U32 getSampleCount() const { return mNumSamples; }
+
+private:
+ F64 mSum,
+ mMin,
+ mMax,
+ mLastValue;
+
+ bool mHasValue;
+
+ F64 mMean,
+ mVarianceSum;
+
+ LLUnitImplicit<F64, LLUnits::Seconds> mLastSampleTimeStamp,
+ mTotalSamplingTime;
+
+ U32 mNumSamples;
+};
+
+class CountAccumulator
+{
+public:
+ typedef F64 value_t;
+ typedef F64 mean_t;
+
+ CountAccumulator()
+ : mSum(0),
+ mNumSamples(0)
+ {}
+
+ void add(F64 value)
+ {
+ mNumSamples++;
+ mSum += value;
+ }
+
+ void addSamples(const CountAccumulator& other, bool /*append*/)
+ {
+ mSum += other.mSum;
+ mNumSamples += other.mNumSamples;
+ }
+
+ void reset(const CountAccumulator* other)
+ {
+ mNumSamples = 0;
+ mSum = 0;
+ }
+
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+
+ F64 getSum() const { return mSum; }
+
+ U32 getSampleCount() const { return mNumSamples; }
+
+private:
+ F64 mSum;
+
+ U32 mNumSamples;
+};
+
+class TimeBlockAccumulator
+{
+public:
+ typedef LLUnit<F64, LLUnits::Seconds> value_t;
+ typedef LLUnit<F64, LLUnits::Seconds> mean_t;
+ typedef TimeBlockAccumulator self_t;
+
+ // fake classes that allows us to view different facets of underlying statistic
+ struct CallCountFacet
+ {
+ typedef U32 value_t;
+ typedef F32 mean_t;
+ };
+
+ struct SelfTimeFacet
+ {
+ typedef LLUnit<F64, LLUnits::Seconds> value_t;
+ typedef LLUnit<F64, LLUnits::Seconds> mean_t;
+ };
+
+ TimeBlockAccumulator();
+ void addSamples(const self_t& other, bool /*append*/);
+ void reset(const self_t* other);
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds>) {}
+
+ //
+ // members
+ //
+ U64 mStartTotalTimeCounter,
+ mTotalTimeCounter,
+ mSelfTimeCounter;
+ U32 mCalls;
+ class TimeBlock* mParent; // last acknowledged parent of this time block
+ class TimeBlock* mLastCaller; // used to bootstrap tree construction
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+
+};
+
+template<>
+class TraceType<TimeBlockAccumulator::CallCountFacet>
+: public TraceType<TimeBlockAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<TimeBlockAccumulator>(name, description)
+ {}
+};
+
+template<>
+class TraceType<TimeBlockAccumulator::SelfTimeFacet>
+ : public TraceType<TimeBlockAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<TimeBlockAccumulator>(name, description)
+ {}
+};
+
+class TimeBlock;
+class TimeBlockTreeNode
+{
+public:
+ TimeBlockTreeNode();
+
+ void setParent(TimeBlock* parent);
+ TimeBlock* getParent() { return mParent; }
+
+ TimeBlock* mBlock;
+ TimeBlock* mParent;
+ std::vector<TimeBlock*> mChildren;
+ bool mCollapsed;
+ bool mNeedsSorting;
+};
+
+
+template <typename T = F64>
+class EventStatHandle
+: public TraceType<EventAccumulator>
+{
+public:
+ typedef F64 storage_t;
+ typedef TraceType<EventAccumulator> trace_t;
+
+ EventStatHandle(const char* name, const char* description = NULL)
+ : trace_t(name, description)
+ {}
+
+ /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); }
+
+};
+
+template<typename T, typename VALUE_T>
+void record(EventStatHandle<T>& measurement, VALUE_T value)
+{
+ T converted_value(value);
+ measurement.getPrimaryAccumulator()->record(storage_value(converted_value));
+}
+
+template <typename T = F64>
+class SampleStatHandle
+: public TraceType<SampleAccumulator>
+{
+public:
+ typedef F64 storage_t;
+ typedef TraceType<SampleAccumulator> trace_t;
+
+ SampleStatHandle(const char* name, const char* description = NULL)
+ : trace_t(name, description)
+ {}
+
+ /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); }
+};
+
+template<typename T, typename VALUE_T>
+void sample(SampleStatHandle<T>& measurement, VALUE_T value)
+{
+ T converted_value(value);
+ measurement.getPrimaryAccumulator()->sample(storage_value(converted_value));
+}
+
+template <typename T = F64>
+class CountStatHandle
+: public TraceType<CountAccumulator>
+{
+public:
+ typedef F64 storage_t;
+ typedef TraceType<CountAccumulator> trace_t;
+
+ CountStatHandle(const char* name, const char* description = NULL)
+ : trace_t(name)
+ {}
+
+ /*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); }
+};
+
+template<typename T, typename VALUE_T>
+void add(CountStatHandle<T>& count, VALUE_T value)
+{
+ T converted_value(value);
+ count.getPrimaryAccumulator()->add(storage_value(converted_value));
+}
+
+
+struct MemStatAccumulator
+{
+ typedef MemStatAccumulator self_t;
+
+ // fake classes that allows us to view different facets of underlying statistic
+ struct AllocationCountFacet
+ {
+ typedef U32 value_t;
+ typedef F32 mean_t;
+ };
+
+ struct DeallocationCountFacet
+ {
+ typedef U32 value_t;
+ typedef F32 mean_t;
+ };
+
+ struct ChildMemFacet
+ {
+ typedef LLUnit<F64, LLUnits::Bytes> value_t;
+ typedef LLUnit<F64, LLUnits::Bytes> mean_t;
+ };
+
+ MemStatAccumulator()
+ : mAllocatedCount(0),
+ mDeallocatedCount(0)
+ {}
+
+ void addSamples(const MemStatAccumulator& other, bool append)
+ {
+ mSize.addSamples(other.mSize, append);
+ mChildSize.addSamples(other.mChildSize, append);
+ mAllocatedCount += other.mAllocatedCount;
+ mDeallocatedCount += other.mDeallocatedCount;
+ }
+
+ void reset(const MemStatAccumulator* other)
+ {
+ mSize.reset(other ? &other->mSize : NULL);
+ mChildSize.reset(other ? &other->mChildSize : NULL);
+ mAllocatedCount = 0;
+ mDeallocatedCount = 0;
+ }
+
+ void flush(LLUnitImplicit<F64, LLUnits::Seconds> time_stamp)
+ {
+ mSize.flush(time_stamp);
+ mChildSize.flush(time_stamp);
+ }
+
+ SampleAccumulator mSize,
+ mChildSize;
+ int mAllocatedCount,
+ mDeallocatedCount;
+};
+
+
+template<>
+class TraceType<MemStatAccumulator::AllocationCountFacet>
+: public TraceType<MemStatAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<MemStatAccumulator>(name, description)
+ {}
+};
+
+template<>
+class TraceType<MemStatAccumulator::DeallocationCountFacet>
+: public TraceType<MemStatAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<MemStatAccumulator>(name, description)
+ {}
+};
+
+template<>
+class TraceType<MemStatAccumulator::ChildMemFacet>
+ : public TraceType<MemStatAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<MemStatAccumulator>(name, description)
+ {}
+};
+
+class MemStatHandle : public TraceType<MemStatAccumulator>
+{
+public:
+ typedef TraceType<MemStatAccumulator> trace_t;
+ MemStatHandle(const char* name)
+ : trace_t(name)
+ {}
+
+ /*virtual*/ const char* getUnitLabel() { return "B"; }
+
+ TraceType<MemStatAccumulator::AllocationCountFacet>& allocationCount()
+ {
+ return static_cast<TraceType<MemStatAccumulator::AllocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+ }
+
+ TraceType<MemStatAccumulator::DeallocationCountFacet>& deallocationCount()
+ {
+ return static_cast<TraceType<MemStatAccumulator::DeallocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+ }
+
+ TraceType<MemStatAccumulator::ChildMemFacet>& childMem()
+ {
+ return static_cast<TraceType<MemStatAccumulator::ChildMemFacet>&>(*(TraceType<MemStatAccumulator>*)this);
+ }
+};
+
+// measures effective memory footprint of specified type
+// specialize to cover different types
+
+template<typename T>
+struct MemFootprint
+{
+ static size_t measure(const T& value)
+ {
+ return sizeof(T);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(T);
+ }
+};
+
+template<typename T>
+struct MemFootprint<T*>
+{
+ static size_t measure(const T* value)
+ {
+ if (!value)
+ {
+ return 0;
+ }
+ return MemFootprint<T>::measure(*value);
+ }
+
+ static size_t measure()
+ {
+ return MemFootprint<T>::measure();
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::basic_string<T> >
+{
+ static size_t measure(const std::basic_string<T>& value)
+ {
+ return value.capacity() * sizeof(T);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::basic_string<T>);
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::vector<T> >
+{
+ static size_t measure(const std::vector<T>& value)
+ {
+ return value.capacity() * MemFootprint<T>::measure();
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::vector<T>);
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::list<T> >
+{
+ static size_t measure(const std::list<T>& value)
+ {
+ return value.size() * (MemFootprint<T>::measure() + sizeof(void*) * 2);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::list<T>);
+ }
+};
+
+template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN>
+class MemTrackable
+{
+ template<typename TRACKED, typename TRACKED_IS_TRACKER>
+ struct TrackMemImpl;
+
+ typedef MemTrackable<DERIVED> mem_trackable_t;
+
+public:
+ typedef void mem_trackable_tag_t;
+
+ virtual ~MemTrackable()
+ {
+ memDisclaim(mMemFootprint);
+ }
+
+ void* operator new(size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
+ accumulator->mAllocatedCount++;
+ }
+
+ return ::operator new(size);
+ }
+
+ void operator delete(void* ptr, size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
+ accumulator->mAllocatedCount--;
+ accumulator->mDeallocatedCount++;
+ }
+ ::operator delete(ptr);
+ }
+
+ void *operator new [](size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
+ accumulator->mAllocatedCount++;
+ }
+
+ return ::operator new[](size);
+ }
+
+ void operator delete[](void* ptr, size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
+ accumulator->mAllocatedCount--;
+ accumulator->mDeallocatedCount++;
+ }
+ ::operator delete[](ptr);
+ }
+
+ // claim memory associated with other objects/data as our own, adding to our calculated footprint
+ template<typename CLAIM_T>
+ CLAIM_T& memClaim(CLAIM_T& value)
+ {
+ TrackMemImpl<CLAIM_T>::claim(*this, value);
+ return value;
+ }
+
+ template<typename CLAIM_T>
+ const CLAIM_T& memClaim(const CLAIM_T& value)
+ {
+ TrackMemImpl<CLAIM_T>::claim(*this, value);
+ return value;
+ }
+
+
+ void memClaimAmount(size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ mMemFootprint += size;
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
+ }
+ }
+
+ // remove memory we had claimed from our calculated footprint
+ template<typename CLAIM_T>
+ CLAIM_T& memDisclaim(CLAIM_T& value)
+ {
+ TrackMemImpl<CLAIM_T>::disclaim(*this, value);
+ return value;
+ }
+
+ template<typename CLAIM_T>
+ const CLAIM_T& memDisclaim(const CLAIM_T& value)
+ {
+ TrackMemImpl<CLAIM_T>::disclaim(*this, value);
+ return value;
+ }
+
+ void memDisclaimAmount(size_t size)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
+ }
+ }
+
+private:
+ size_t mMemFootprint;
+
+ template<typename TRACKED, typename TRACKED_IS_TRACKER = void>
+ struct TrackMemImpl
+ {
+ static void claim(mem_trackable_t& tracker, const TRACKED& tracked)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ size_t footprint = MemFootprint<TRACKED>::measure(tracked);
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)footprint);
+ tracker.mMemFootprint += footprint;
+ }
+ }
+
+ static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ size_t footprint = MemFootprint<TRACKED>::measure(tracked);
+ accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)footprint);
+ tracker.mMemFootprint -= footprint;
+ }
+ }
+ };
+
+ template<typename TRACKED>
+ struct TrackMemImpl<TRACKED, typename TRACKED::mem_trackable_tag_t>
+ {
+ static void claim(mem_trackable_t& tracker, TRACKED& tracked)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint<TRACKED>::measure(tracked));
+ }
+ }
+
+ static void disclaim(mem_trackable_t& tracker, TRACKED& tracked)
+ {
+ MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+ if (accumulator)
+ {
+ accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint<TRACKED>::measure(tracked));
+ }
+ }
+ };
+};
+
+}
+#endif // LL_LLTRACE_H
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
new file mode 100644
index 0000000000..d34434f161
--- /dev/null
+++ b/indra/llcommon/lltracerecording.cpp
@@ -0,0 +1,914 @@
+/**
+ * @file lltracesampler.cpp
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltrace.h"
+#include "llfasttimer.h"
+#include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
+#include "llthread.h"
+
+namespace LLTrace
+{
+
+
+///////////////////////////////////////////////////////////////////////
+// RecordingBuffers
+///////////////////////////////////////////////////////////////////////
+
+RecordingBuffers::RecordingBuffers()
+{}
+
+void RecordingBuffers::handOffTo(RecordingBuffers& other)
+{
+ other.mCounts.reset(&mCounts);
+ other.mSamples.reset(&mSamples);
+ other.mEvents.reset(&mEvents);
+ other.mStackTimers.reset(&mStackTimers);
+ other.mMemStats.reset(&mMemStats);
+}
+
+void RecordingBuffers::makePrimary()
+{
+ mCounts.makePrimary();
+ mSamples.makePrimary();
+ mEvents.makePrimary();
+ mStackTimers.makePrimary();
+ mMemStats.makePrimary();
+
+ ThreadRecorder* thread_recorder = get_thread_recorder().get();
+ AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
+ // update stacktimer parent pointers
+ for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)
+ {
+ TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(i);
+ if (tree_node)
+ {
+ timer_accumulator_buffer[i].mParent = tree_node->mParent;
+ }
+ }
+}
+
+bool RecordingBuffers::isPrimary() const
+{
+ return mCounts.isPrimary();
+}
+
+void RecordingBuffers::append( const RecordingBuffers& other )
+{
+ mCounts.addSamples(other.mCounts);
+ mSamples.addSamples(other.mSamples);
+ mEvents.addSamples(other.mEvents);
+ mMemStats.addSamples(other.mMemStats);
+ mStackTimers.addSamples(other.mStackTimers);
+}
+
+void RecordingBuffers::merge( const RecordingBuffers& other)
+{
+ mCounts.addSamples(other.mCounts, false);
+ mSamples.addSamples(other.mSamples, false);
+ mEvents.addSamples(other.mEvents, false);
+ mMemStats.addSamples(other.mMemStats, false);
+ // for now, hold out timers from merge, need to be displayed per thread
+ //mStackTimers.addSamples(other.mStackTimers, false);
+}
+
+void RecordingBuffers::reset(RecordingBuffers* other)
+{
+ mCounts.reset(other ? &other->mCounts : NULL);
+ mSamples.reset(other ? &other->mSamples : NULL);
+ mEvents.reset(other ? &other->mEvents : NULL);
+ mStackTimers.reset(other ? &other->mStackTimers : NULL);
+ mMemStats.reset(other ? &other->mMemStats : NULL);
+}
+
+void RecordingBuffers::flush()
+{
+ LLUnitImplicit<F64, LLUnits::Seconds> time_stamp = LLTimer::getTotalSeconds();
+
+ mSamples.flush(time_stamp);
+}
+
+///////////////////////////////////////////////////////////////////////
+// Recording
+///////////////////////////////////////////////////////////////////////
+
+Recording::Recording()
+: mElapsedSeconds(0)
+{
+ mBuffers = new RecordingBuffers();
+}
+
+Recording::Recording( const Recording& other )
+{
+ *this = other;
+}
+
+Recording& Recording::operator = (const Recording& other)
+{
+ // this will allow us to seamlessly start without affecting any data we've acquired from other
+ setPlayState(PAUSED);
+
+ Recording& mutable_other = const_cast<Recording&>(other);
+ mutable_other.update();
+ EPlayState other_play_state = other.getPlayState();
+
+ mBuffers = mutable_other.mBuffers;
+
+ LLStopWatchControlsMixin<Recording>::setPlayState(other_play_state);
+
+ // above call will clear mElapsedSeconds as a side effect, so copy it here
+ mElapsedSeconds = other.mElapsedSeconds;
+ mSamplingTimer = other.mSamplingTimer;
+ return *this;
+}
+
+
+Recording::~Recording()
+{
+ if (isStarted() && LLTrace::get_thread_recorder().notNull())
+ {
+ LLTrace::get_thread_recorder()->deactivate(this);
+ }
+}
+
+void Recording::update()
+{
+ if (isStarted())
+ {
+ mBuffers.write()->flush();
+ LLTrace::get_thread_recorder()->bringUpToDate(this);
+ mSamplingTimer.reset();
+ }
+}
+
+void Recording::handleReset()
+{
+ mBuffers.write()->reset();
+
+ mElapsedSeconds = 0.0;
+ mSamplingTimer.reset();
+}
+
+void Recording::handleStart()
+{
+ mSamplingTimer.reset();
+ LLTrace::get_thread_recorder()->activate(this);
+}
+
+void Recording::handleStop()
+{
+ mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+ mBuffers.write()->flush();
+ LLTrace::get_thread_recorder()->deactivate(this);
+}
+
+void Recording::handleSplitTo(Recording& other)
+{
+ mBuffers.write()->handOffTo(*other.mBuffers.write());
+}
+
+void Recording::appendRecording( const Recording& other )
+{
+ update();
+ mBuffers.write()->append(*other.mBuffers);
+ mElapsedSeconds += other.mElapsedSeconds;
+}
+
+void Recording::mergeRecording( const Recording& other)
+{
+ update();
+ mBuffers.write()->merge(*other.mBuffers);
+}
+
+LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat)
+{
+ const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
+ return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
+ / (F64)LLTrace::TimeBlock::countsPerSecond();
+}
+
+LLUnit<F64, LLUnits::Seconds> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
+{
+ const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
+ return (F64)(accumulator.mSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond();
+}
+
+
+U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
+{
+ return mBuffers->mStackTimers[stat.getIndex()].mCalls;
+}
+
+LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat)
+{
+ const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
+
+ return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
+}
+
+LLUnit<F64, LLUnits::Seconds> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat)
+{
+ const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
+
+ return (F64)(accumulator.mSelfTimeCounter)
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value());
+}
+
+F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat)
+{
+ return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds.value();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mSize.getMin();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mSize.getMean();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mSize.getMax();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation();
+}
+
+LLUnit<F64, LLUnits::Bytes> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue();
+}
+
+U32 Recording::getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
+}
+
+U32 Recording::getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat)
+{
+ return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount;
+}
+
+
+F64 Recording::getSum( const TraceType<CountAccumulator>& stat )
+{
+ return mBuffers->mCounts[stat.getIndex()].getSum();
+}
+
+F64 Recording::getSum( const TraceType<EventAccumulator>& stat )
+{
+ return (F64)mBuffers->mEvents[stat.getIndex()].getSum();
+}
+
+F64 Recording::getPerSec( const TraceType<CountAccumulator>& stat )
+{
+ F64 sum = mBuffers->mCounts[stat.getIndex()].getSum();
+ return (sum != 0.0)
+ ? (sum / mElapsedSeconds.value())
+ : 0.0;
+}
+
+U32 Recording::getSampleCount( const TraceType<CountAccumulator>& stat )
+{
+ return mBuffers->mCounts[stat.getIndex()].getSampleCount();
+}
+
+F64 Recording::getMin( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getMin();
+}
+
+F64 Recording::getMax( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getMax();
+}
+
+F64 Recording::getMean( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getMean();
+}
+
+F64 Recording::getStandardDeviation( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getStandardDeviation();
+}
+
+F64 Recording::getLastValue( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getLastValue();
+}
+
+U32 Recording::getSampleCount( const TraceType<SampleAccumulator>& stat )
+{
+ return mBuffers->mSamples[stat.getIndex()].getSampleCount();
+}
+
+F64 Recording::getMin( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getMin();
+}
+
+F64 Recording::getMax( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getMax();
+}
+
+F64 Recording::getMean( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getMean();
+}
+
+F64 Recording::getStandardDeviation( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getStandardDeviation();
+}
+
+F64 Recording::getLastValue( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getLastValue();
+}
+
+U32 Recording::getSampleCount( const TraceType<EventAccumulator>& stat )
+{
+ return mBuffers->mEvents[stat.getIndex()].getSampleCount();
+}
+
+///////////////////////////////////////////////////////////////////////
+// PeriodicRecording
+///////////////////////////////////////////////////////////////////////
+
+PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state)
+: mAutoResize(num_periods == 0),
+ mCurPeriod(0),
+ mNumPeriods(0),
+ mRecordingPeriods(num_periods ? num_periods : 1)
+{
+ setPlayState(state);
+}
+
+void PeriodicRecording::nextPeriod()
+{
+ if (mAutoResize)
+ {
+ mRecordingPeriods.push_back(Recording());
+ }
+
+ Recording& old_recording = getCurRecording();
+ mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size();
+ old_recording.splitTo(getCurRecording());
+
+ mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + 1);
+}
+
+void PeriodicRecording::appendRecording(Recording& recording)
+{
+ getCurRecording().appendRecording(recording);
+ nextPeriod();
+}
+
+
+void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
+{
+ if (other.mRecordingPeriods.empty()) return;
+
+ getCurRecording().update();
+ other.getCurRecording().update();
+
+ const U32 other_recording_slots = other.mRecordingPeriods.size();
+ const U32 other_num_recordings = other.getNumRecordedPeriods();
+ const U32 other_current_recording_index = other.mCurPeriod;
+ const U32 other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings + 1) % other_recording_slots;
+
+ // append first recording into our current slot
+ getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]);
+
+ // from now on, add new recordings for everything after the first
+ U32 other_index = (other_oldest_recording_index + 1) % other_recording_slots;
+
+ if (mAutoResize)
+ {
+ // append first recording into our current slot
+ getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]);
+
+ // push back recordings for everything in the middle
+ U32 other_index = (other_oldest_recording_index + 1) % other_recording_slots;
+ while (other_index != other_current_recording_index)
+ {
+ mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]);
+ other_index = (other_index + 1) % other_recording_slots;
+ }
+
+ // add final recording, if it wasn't already added as the first
+ if (other_num_recordings > 1)
+ {
+ mRecordingPeriods.push_back(other.mRecordingPeriods[other_current_recording_index]);
+ }
+
+ mCurPeriod = mRecordingPeriods.size() - 1;
+ mNumPeriods = mRecordingPeriods.size();
+ }
+ else
+ {
+ size_t num_to_copy = llmin( mRecordingPeriods.size(), (size_t)other_num_recordings);
+
+ std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin() + other_index ;
+ std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod;
+
+ // already consumed the first recording from other, so start counting at 1
+ for(size_t i = 1; i < num_to_copy; i++)
+ {
+ *dest_it = *src_it;
+
+ if (++src_it == other.mRecordingPeriods.end())
+ {
+ src_it = other.mRecordingPeriods.begin();
+ }
+
+ if (++dest_it == mRecordingPeriods.end())
+ {
+ dest_it = mRecordingPeriods.begin();
+ }
+ }
+
+ // want argument to % to be positive, otherwise result could be negative and thus out of bounds
+ llassert(num_to_copy >= 1);
+ // advance to last recording period copied, and make that our current period
+ mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size();
+ mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + num_to_copy - 1);
+ }
+
+ // end with fresh period, otherwise next appendPeriodicRecording() will merge the first
+ // recording period with the last one appended here
+ nextPeriod();
+ getCurRecording().setPlayState(getPlayState());
+}
+
+LLUnit<F64, LLUnits::Seconds> PeriodicRecording::getDuration() const
+{
+ LLUnit<F64, LLUnits::Seconds> duration;
+ size_t num_periods = mRecordingPeriods.size();
+ for (size_t i = 1; i <= num_periods; i++)
+ {
+ size_t index = (mCurPeriod + num_periods - i) % num_periods;
+ duration += mRecordingPeriods[index].getDuration();
+ }
+ return duration;
+}
+
+
+LLTrace::Recording PeriodicRecording::snapshotCurRecording() const
+{
+ Recording recording_copy(getCurRecording());
+ recording_copy.stop();
+ return recording_copy;
+}
+
+
+Recording& PeriodicRecording::getLastRecording()
+{
+ return getPrevRecording(1);
+}
+
+const Recording& PeriodicRecording::getLastRecording() const
+{
+ return getPrevRecording(1);
+}
+
+Recording& PeriodicRecording::getCurRecording()
+{
+ return mRecordingPeriods[mCurPeriod];
+}
+
+const Recording& PeriodicRecording::getCurRecording() const
+{
+ return mRecordingPeriods[mCurPeriod];
+}
+
+Recording& PeriodicRecording::getPrevRecording( U32 offset )
+{
+ U32 num_periods = mRecordingPeriods.size();
+ offset = llclamp(offset, 0u, num_periods - 1);
+ return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
+}
+
+const Recording& PeriodicRecording::getPrevRecording( U32 offset ) const
+{
+ U32 num_periods = mRecordingPeriods.size();
+ offset = llclamp(offset, 0u, num_periods - 1);
+ return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods];
+}
+
+void PeriodicRecording::handleStart()
+{
+ getCurRecording().start();
+}
+
+void PeriodicRecording::handleStop()
+{
+ getCurRecording().pause();
+}
+
+void PeriodicRecording::handleReset()
+{
+ if (mAutoResize)
+ {
+ mRecordingPeriods.clear();
+ mRecordingPeriods.push_back(Recording());
+ }
+ else
+ {
+ for (std::vector<Recording>::iterator it = mRecordingPeriods.begin(), end_it = mRecordingPeriods.end();
+ it != end_it;
+ ++it)
+ {
+ it->reset();
+ }
+ }
+ mCurPeriod = 0;
+ getCurRecording().setPlayState(getPlayState());
+}
+
+void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
+{
+ getCurRecording().splitTo(other.getCurRecording());
+}
+
+
+F64 PeriodicRecording::getPeriodMean( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 mean = 0;
+ if (num_periods <= 0) { return mean; }
+
+ S32 total_sample_count = 0;
+
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ if (mRecordingPeriods[index].getDuration() > 0.f)
+ {
+ S32 period_sample_count = mRecordingPeriods[index].getSampleCount(stat);
+ mean += mRecordingPeriods[index].getMean(stat) * period_sample_count;
+ total_sample_count += period_sample_count;
+ }
+ }
+
+ if (total_sample_count)
+ {
+ mean = mean / total_sample_count;
+ }
+ return mean;
+}
+
+F64 PeriodicRecording::getPeriodMin( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 min_val = std::numeric_limits<F64>::max();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat));
+ }
+ return min_val;
+}
+
+F64 PeriodicRecording::getPeriodMax( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 max_val = std::numeric_limits<F64>::min();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat));
+ }
+ return max_val;
+}
+
+F64 PeriodicRecording::getPeriodMin( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 min_val = std::numeric_limits<F64>::max();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat));
+ }
+ return min_val;
+}
+
+F64 PeriodicRecording::getPeriodMax(const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/)
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 max_val = std::numeric_limits<F64>::min();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat));
+ }
+ return max_val;
+}
+
+
+F64 PeriodicRecording::getPeriodMean( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ )
+{
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ LLUnit<F64, LLUnits::Seconds> total_duration = 0.f;
+
+ F64 mean = 0;
+ if (num_periods <= 0) { return mean; }
+
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ if (mRecordingPeriods[index].getDuration() > 0.f)
+ {
+ LLUnit<F64, LLUnits::Seconds> recording_duration = mRecordingPeriods[index].getDuration();
+ mean += mRecordingPeriods[index].getMean(stat) * recording_duration.value();
+ total_duration += recording_duration;
+ }
+ }
+
+ if (total_duration.value())
+ {
+ mean = mean / total_duration;
+ }
+ return mean;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////
+// ExtendableRecording
+///////////////////////////////////////////////////////////////////////
+
+void ExtendableRecording::extend()
+{
+ // stop recording to get latest data
+ mPotentialRecording.update();
+ // push the data back to accepted recording
+ mAcceptedRecording.appendRecording(mPotentialRecording);
+ // flush data, so we can start from scratch
+ mPotentialRecording.reset();
+}
+
+void ExtendableRecording::handleStart()
+{
+ mPotentialRecording.start();
+}
+
+void ExtendableRecording::handleStop()
+{
+ mPotentialRecording.pause();
+}
+
+void ExtendableRecording::handleReset()
+{
+ mAcceptedRecording.reset();
+ mPotentialRecording.reset();
+}
+
+void ExtendableRecording::handleSplitTo(ExtendableRecording& other)
+{
+ mPotentialRecording.splitTo(other.mPotentialRecording);
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// ExtendablePeriodicRecording
+///////////////////////////////////////////////////////////////////////
+
+
+ExtendablePeriodicRecording::ExtendablePeriodicRecording()
+: mAcceptedRecording(0),
+ mPotentialRecording(0)
+{}
+
+void ExtendablePeriodicRecording::extend()
+{
+ // push the data back to accepted recording
+ mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
+ // flush data, so we can start from scratch
+ mPotentialRecording.reset();
+}
+
+
+void ExtendablePeriodicRecording::handleStart()
+{
+ mPotentialRecording.start();
+}
+
+void ExtendablePeriodicRecording::handleStop()
+{
+ mPotentialRecording.pause();
+}
+
+void ExtendablePeriodicRecording::handleReset()
+{
+ mAcceptedRecording.reset();
+ mPotentialRecording.reset();
+}
+
+void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other)
+{
+ mPotentialRecording.splitTo(other.mPotentialRecording);
+}
+
+
+PeriodicRecording& get_frame_recording()
+{
+ static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(1000, PeriodicRecording::STARTED));
+ return *sRecording;
+}
+
+}
+
+void LLStopWatchControlsMixinCommon::start()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleReset();
+ handleStart();
+ break;
+ case PAUSED:
+ handleStart();
+ break;
+ case STARTED:
+ handleReset();
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLStopWatchControlsMixinCommon::stop()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ break;
+ case PAUSED:
+ break;
+ case STARTED:
+ handleStop();
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+ mPlayState = STOPPED;
+}
+
+void LLStopWatchControlsMixinCommon::pause()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ break;
+ case PAUSED:
+ break;
+ case STARTED:
+ handleStop();
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+ mPlayState = PAUSED;
+}
+
+void LLStopWatchControlsMixinCommon::resume()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleStart();
+ break;
+ case PAUSED:
+ handleStart();
+ break;
+ case STARTED:
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLStopWatchControlsMixinCommon::restart()
+{
+ switch (mPlayState)
+ {
+ case STOPPED:
+ handleReset();
+ handleStart();
+ break;
+ case PAUSED:
+ handleReset();
+ handleStart();
+ break;
+ case STARTED:
+ handleReset();
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+ mPlayState = STARTED;
+}
+
+void LLStopWatchControlsMixinCommon::reset()
+{
+ handleReset();
+}
+
+void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state )
+{
+ switch(state)
+ {
+ case STOPPED:
+ stop();
+ break;
+ case PAUSED:
+ pause();
+ break;
+ case STARTED:
+ start();
+ break;
+ default:
+ llassert(false);
+ break;
+ }
+
+ mPlayState = state;
+}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
new file mode 100644
index 0000000000..b839e85de0
--- /dev/null
+++ b/indra/llcommon/lltracerecording.h
@@ -0,0 +1,531 @@
+/**
+ * @file lltracerecording.h
+ * @brief Sampling object for collecting runtime statistics originating from lltrace.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTRACERECORDING_H
+#define LL_LLTRACERECORDING_H
+
+#include "stdtypes.h"
+#include "llpreprocessor.h"
+
+#include "llpointer.h"
+#include "lltimer.h"
+#include "lltrace.h"
+
+class LLStopWatchControlsMixinCommon
+{
+public:
+ virtual ~LLStopWatchControlsMixinCommon() {}
+
+ enum EPlayState
+ {
+ STOPPED,
+ PAUSED,
+ STARTED
+ };
+
+ void start();
+ void stop();
+ void pause();
+ void resume();
+ void restart();
+ void reset();
+
+ bool isStarted() const { return mPlayState == STARTED; }
+ bool isPaused() const { return mPlayState == PAUSED; }
+ bool isStopped() const { return mPlayState == STOPPED; }
+ EPlayState getPlayState() const { return mPlayState; }
+ // force play state to specific value by calling appropriate handle* methods
+ void setPlayState(EPlayState state);
+
+protected:
+ LLStopWatchControlsMixinCommon()
+ : mPlayState(STOPPED)
+ {}
+
+private:
+ // trigger active behavior (without reset)
+ virtual void handleStart() = 0;
+ // stop active behavior
+ virtual void handleStop() = 0;
+ // clear accumulated state, can be called while started
+ virtual void handleReset() = 0;
+
+ EPlayState mPlayState;
+};
+
+template<typename DERIVED>
+class LLStopWatchControlsMixin
+: public LLStopWatchControlsMixinCommon
+{
+public:
+ typedef LLStopWatchControlsMixin<DERIVED> self_t;
+ virtual void splitTo(DERIVED& other)
+ {
+ EPlayState play_state = getPlayState();
+ stop();
+ other.reset();
+
+ handleSplitTo(other);
+
+ other.setPlayState(play_state);
+ }
+
+ virtual void splitFrom(DERIVED& other)
+ {
+ static_cast<self_t&>(other).handleSplitTo(*static_cast<DERIVED*>(this));
+ }
+private:
+ // atomically stop this object while starting the other
+ // no data can be missed in between stop and start
+ virtual void handleSplitTo(DERIVED& other) {};
+
+};
+
+namespace LLTrace
+{
+ struct RecordingBuffers : public LLRefCount
+ {
+ RecordingBuffers();
+
+ void handOffTo(RecordingBuffers& other);
+ void makePrimary();
+ bool isPrimary() const;
+
+ void append(const RecordingBuffers& other);
+ void merge(const RecordingBuffers& other);
+ void reset(RecordingBuffers* other = NULL);
+ void flush();
+
+ AccumulatorBuffer<CountAccumulator> mCounts;
+ AccumulatorBuffer<SampleAccumulator> mSamples;
+ AccumulatorBuffer<EventAccumulator> mEvents;
+ AccumulatorBuffer<TimeBlockAccumulator> mStackTimers;
+ AccumulatorBuffer<MemStatAccumulator> mMemStats;
+ };
+
+ class Recording
+ : public LLStopWatchControlsMixin<Recording>
+ {
+ public:
+ Recording();
+
+ Recording(const Recording& other);
+ ~Recording();
+
+ Recording& operator = (const Recording& other);
+
+ // accumulate data from subsequent, non-overlapping recording
+ void appendRecording(const Recording& other);
+
+ // gather data from recording, ignoring time relationship (for example, pulling data from slave threads)
+ void mergeRecording(const Recording& other);
+
+ // grab latest recorded data
+ void update();
+
+ // ensure that buffers are exclusively owned by this recording
+ void makeUnique() { mBuffers.makeUnique(); }
+
+ // Timer accessors
+ LLUnit<F64, LLUnits::Seconds> getSum(const TraceType<TimeBlockAccumulator>& stat);
+ LLUnit<F64, LLUnits::Seconds> getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+ U32 getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
+
+ LLUnit<F64, LLUnits::Seconds> getPerSec(const TraceType<TimeBlockAccumulator>& stat);
+ LLUnit<F64, LLUnits::Seconds> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat);
+ F32 getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat);
+
+ // Memory accessors
+ LLUnit<F64, LLUnits::Bytes> getMin(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMean(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMax(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getStandardDeviation(const TraceType<MemStatAccumulator>& stat);
+ LLUnit<F64, LLUnits::Bytes> getLastValue(const TraceType<MemStatAccumulator>& stat);
+
+ LLUnit<F64, LLUnits::Bytes> getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+ LLUnit<F64, LLUnits::Bytes> getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat);
+
+ U32 getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat);
+ U32 getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat);
+
+ // CountStatHandle accessors
+ F64 getSum(const TraceType<CountAccumulator>& stat);
+ template <typename T>
+ T getSum(const CountStatHandle<T>& stat)
+ {
+ return (T)getSum(static_cast<const TraceType<CountAccumulator>&> (stat));
+ }
+
+ F64 getPerSec(const TraceType<CountAccumulator>& stat);
+ template <typename T>
+ T getPerSec(const CountStatHandle<T>& stat)
+ {
+ return (T)getPerSec(static_cast<const TraceType<CountAccumulator>&> (stat));
+ }
+
+ U32 getSampleCount(const TraceType<CountAccumulator>& stat);
+
+
+ // SampleStatHandle accessors
+ F64 getMin(const TraceType<SampleAccumulator>& stat);
+ template <typename T>
+ T getMin(const SampleStatHandle<T>& stat)
+ {
+ return (T)getMin(static_cast<const TraceType<SampleAccumulator>&> (stat));
+ }
+
+ F64 getMean(const TraceType<SampleAccumulator>& stat);
+ template <typename T>
+ T getMean(SampleStatHandle<T>& stat)
+ {
+ return (T)getMean(static_cast<const TraceType<SampleAccumulator>&> (stat));
+ }
+
+ F64 getMax(const TraceType<SampleAccumulator>& stat);
+ template <typename T>
+ T getMax(const SampleStatHandle<T>& stat)
+ {
+ return (T)getMax(static_cast<const TraceType<SampleAccumulator>&> (stat));
+ }
+
+ F64 getStandardDeviation(const TraceType<SampleAccumulator>& stat);
+ template <typename T>
+ T getStandardDeviation(const SampleStatHandle<T>& stat)
+ {
+ return (T)getStandardDeviation(static_cast<const TraceType<SampleAccumulator>&> (stat));
+ }
+
+ F64 getLastValue(const TraceType<SampleAccumulator>& stat);
+ template <typename T>
+ T getLastValue(const SampleStatHandle<T>& stat)
+ {
+ return (T)getLastValue(static_cast<const TraceType<SampleAccumulator>&> (stat));
+ }
+
+ U32 getSampleCount(const TraceType<SampleAccumulator>& stat);
+
+ // EventStatHandle accessors
+ F64 getSum(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getSum(const EventStatHandle<T>& stat)
+ {
+ return (T)getSum(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ F64 getMin(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getMin(const EventStatHandle<T>& stat)
+ {
+ return (T)getMin(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ F64 getMax(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getMax(const EventStatHandle<T>& stat)
+ {
+ return (T)getMax(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ F64 getMean(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getMean(EventStatHandle<T>& stat)
+ {
+ return (T)getMean(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ F64 getStandardDeviation(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getStandardDeviation(const EventStatHandle<T>& stat)
+ {
+ return (T)getStandardDeviation(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ F64 getLastValue(const TraceType<EventAccumulator>& stat);
+ template <typename T>
+ T getLastValue(const EventStatHandle<T>& stat)
+ {
+ return (T)getLastValue(static_cast<const TraceType<EventAccumulator>&> (stat));
+ }
+
+ U32 getSampleCount(const TraceType<EventAccumulator>& stat);
+
+ LLUnit<F64, LLUnits::Seconds> getDuration() const { return mElapsedSeconds; }
+
+ protected:
+ friend class ThreadRecorder;
+
+ // implementation for LLStopWatchControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
+ /*virtual*/ void handleSplitTo(Recording& other);
+
+ // returns data for current thread
+ class ThreadRecorder* getThreadRecorder();
+
+ LLTimer mSamplingTimer;
+ LLUnit<F64, LLUnits::Seconds> mElapsedSeconds;
+ LLCopyOnWritePointer<RecordingBuffers> mBuffers;
+ };
+
+ class LL_COMMON_API PeriodicRecording
+ : public LLStopWatchControlsMixin<PeriodicRecording>
+ {
+ public:
+ PeriodicRecording(U32 num_periods, EPlayState state = STOPPED);
+
+ void nextPeriod();
+ size_t getNumRecordedPeriods() { return mNumPeriods; }
+
+ LLUnit<F64, LLUnits::Seconds> getDuration() const;
+
+ void appendPeriodicRecording(PeriodicRecording& other);
+ void appendRecording(Recording& recording);
+ Recording& getLastRecording();
+ const Recording& getLastRecording() const;
+ Recording& getCurRecording();
+ const Recording& getCurRecording() const;
+ Recording& getPrevRecording(U32 offset);
+ const Recording& getPrevRecording(U32 offset) const;
+ Recording snapshotCurRecording() const;
+
+ // catch all for stats that have a defined sum
+ template <typename T>
+ typename T::value_t getPeriodMin(const TraceType<T>& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ typename T::value_t min_val = std::numeric_limits<typename T::value_t>::max();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ min_val = llmin(min_val, mRecordingPeriods[index].getSum(stat));
+ }
+ return min_val;
+ }
+
+ F64 getPeriodMin(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMin(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods));
+ }
+
+ F64 getPeriodMin(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMin(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods));
+ }
+
+ template <typename T>
+ F64 getPeriodMinPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 min_val = std::numeric_limits<F64>::max();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ min_val = llmin(min_val, mRecordingPeriods[index].getPerSec(stat));
+ }
+ return min_val;
+ }
+
+ // catch all for stats that have a defined sum
+ template <typename T>
+ typename T::value_t getPeriodMax(const TraceType<T>& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ typename T::value_t max_val = std::numeric_limits<typename T::value_t>::min();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ max_val = llmax(max_val, mRecordingPeriods[index].getSum(stat));
+ }
+ return max_val;
+ }
+
+ F64 getPeriodMax(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMax(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods));
+ }
+
+ F64 getPeriodMax(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMax(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods));
+ }
+
+ template <typename T>
+ F64 getPeriodMaxPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ F64 max_val = std::numeric_limits<F64>::min();
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ max_val = llmax(max_val, mRecordingPeriods[index].getPerSec(stat));
+ }
+ return max_val;
+ }
+
+ // catch all for stats that have a defined sum
+ template <typename T>
+ typename T::mean_t getPeriodMean(const TraceType<T >& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ typename T::mean_t mean = 0;
+ if (num_periods <= 0) { return mean; }
+
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ if (mRecordingPeriods[index].getDuration() > 0.f)
+ {
+ mean += mRecordingPeriods[index].getSum(stat);
+ }
+ }
+ mean = mean / num_periods;
+ return mean;
+ }
+
+ F64 getPeriodMean(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMean(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods));
+ }
+
+ F64 getPeriodMean(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX);
+ template<typename T>
+ T getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX)
+ {
+ return T(getPeriodMean(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods));
+ }
+
+ template <typename T>
+ typename T::mean_t getPeriodMeanPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX)
+ {
+ size_t total_periods = mRecordingPeriods.size();
+ num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods);
+
+ typename T::mean_t mean = 0;
+ if (num_periods <= 0) { return mean; }
+
+ for (S32 i = 1; i <= num_periods; i++)
+ {
+ S32 index = (mCurPeriod + total_periods - i) % total_periods;
+ if (mRecordingPeriods[index].getDuration() > 0.f)
+ {
+ mean += mRecordingPeriods[index].getPerSec(stat);
+ }
+ }
+ mean = mean / num_periods;
+ return mean;
+ }
+
+ private:
+ // implementation for LLStopWatchControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
+ /*virtual*/ void handleSplitTo(PeriodicRecording& other);
+
+ private:
+ std::vector<Recording> mRecordingPeriods;
+ const bool mAutoResize;
+ size_t mCurPeriod;
+ size_t mNumPeriods;
+ };
+
+ PeriodicRecording& get_frame_recording();
+
+ class ExtendableRecording
+ : public LLStopWatchControlsMixin<ExtendableRecording>
+ {
+ public:
+ void extend();
+
+ Recording& getAcceptedRecording() { return mAcceptedRecording; }
+ const Recording& getAcceptedRecording() const {return mAcceptedRecording;}
+
+ Recording& getPotentialRecording() { return mPotentialRecording; }
+ const Recording& getPotentialRecording() const { return mPotentialRecording;}
+
+ private:
+ // implementation for LLStopWatchControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
+ /*virtual*/ void handleSplitTo(ExtendableRecording& other);
+
+ private:
+ Recording mAcceptedRecording;
+ Recording mPotentialRecording;
+ };
+
+ class ExtendablePeriodicRecording
+ : public LLStopWatchControlsMixin<ExtendablePeriodicRecording>
+ {
+ public:
+ ExtendablePeriodicRecording();
+ void extend();
+
+ PeriodicRecording& getAcceptedRecording() { return mAcceptedRecording; }
+ const PeriodicRecording& getAcceptedRecording() const {return mAcceptedRecording;}
+
+ PeriodicRecording& getPotentialRecording() { return mPotentialRecording; }
+ const PeriodicRecording& getPotentialRecording() const {return mPotentialRecording;}
+
+ private:
+ // implementation for LLStopWatchControlsMixin
+ /*virtual*/ void handleStart();
+ /*virtual*/ void handleStop();
+ /*virtual*/ void handleReset();
+ /*virtual*/ void handleSplitTo(ExtendablePeriodicRecording& other);
+
+ private:
+ PeriodicRecording mAcceptedRecording;
+ PeriodicRecording mPotentialRecording;
+ };
+}
+
+#endif // LL_LLTRACERECORDING_H
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
new file mode 100644
index 0000000000..54006f4e5b
--- /dev/null
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -0,0 +1,292 @@
+/**
+ * @file lltracethreadrecorder.cpp
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lltracethreadrecorder.h"
+#include "llfasttimer.h"
+
+namespace LLTrace
+{
+
+
+///////////////////////////////////////////////////////////////////////
+// ThreadRecorder
+///////////////////////////////////////////////////////////////////////
+
+ThreadRecorder::ThreadRecorder()
+{
+ //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies
+ set_thread_recorder(this);
+ TimeBlock& root_time_block = TimeBlock::getRootTimeBlock();
+
+ ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance();
+ timer_stack->mTimeBlock = &root_time_block;
+ timer_stack->mActiveTimer = NULL;
+
+ mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size();
+ mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes];
+
+ mThreadRecording.start();
+
+ // initialize time block parent pointers
+ for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances();
+ it != end_it;
+ ++it)
+ {
+ TimeBlock& time_block = *it;
+ TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()];
+ tree_node.mBlock = &time_block;
+ tree_node.mParent = &root_time_block;
+
+ it->getPrimaryAccumulator()->mParent = &root_time_block;
+ }
+
+ mRootTimer = new BlockTimer(root_time_block);
+ timer_stack->mActiveTimer = mRootTimer;
+
+ TimeBlock::getRootTimeBlock().getPrimaryAccumulator()->mActiveCount = 1;
+}
+
+ThreadRecorder::~ThreadRecorder()
+{
+ delete mRootTimer;
+
+ if (!mActiveRecordings.empty())
+ {
+ std::for_each(mActiveRecordings.begin(), mActiveRecordings.end(), DeletePointer());
+ mActiveRecordings.clear();
+ }
+
+ set_thread_recorder(NULL);
+ delete[] mTimeBlockTreeNodes;
+}
+
+TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index)
+{
+ if (0 <= index && index < mNumTimeBlockTreeNodes)
+ {
+ return &mTimeBlockTreeNodes[index];
+ }
+ return NULL;
+}
+
+
+void ThreadRecorder::activate( Recording* recording )
+{
+ ActiveRecording* active_recording = new ActiveRecording(recording);
+ if (!mActiveRecordings.empty())
+ {
+ mActiveRecordings.back()->mPartialRecording.handOffTo(active_recording->mPartialRecording);
+ }
+ mActiveRecordings.push_back(active_recording);
+
+ mActiveRecordings.back()->mPartialRecording.makePrimary();
+}
+
+ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( Recording* recording )
+{
+ if (mActiveRecordings.empty()) return mActiveRecordings.rend();
+
+ mActiveRecordings.back()->mPartialRecording.flush();
+ TimeBlock::updateTimes();
+
+ active_recording_list_t::reverse_iterator it, end_it;
+ for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend();
+ it != end_it;
+ ++it)
+ {
+ ActiveRecording* cur_recording = *it;
+
+ active_recording_list_t::reverse_iterator next_it = it;
+ ++next_it;
+
+ // if we have another recording further down in the stack...
+ if (next_it != mActiveRecordings.rend())
+ {
+ // ...push our gathered data down to it
+ (*next_it)->mPartialRecording.append(cur_recording->mPartialRecording);
+ }
+
+ // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording)
+ cur_recording->movePartialToTarget();
+
+ if (cur_recording->mTargetRecording == recording)
+ {
+ // found the recording, so return it
+ break;
+ }
+ }
+
+ if (it == end_it)
+ {
+ llwarns << "Recording not active on this thread" << llendl;
+ }
+
+ return it;
+}
+
+void ThreadRecorder::deactivate( Recording* recording )
+{
+ active_recording_list_t::reverse_iterator it = bringUpToDate(recording);
+ if (it != mActiveRecordings.rend())
+ {
+ // and if we've found the recording we wanted to update
+ active_recording_list_t::reverse_iterator next_it = it;
+ ++next_it;
+ if (next_it != mActiveRecordings.rend())
+ {
+ (*next_it)->mPartialRecording.makePrimary();
+ }
+
+ active_recording_list_t::iterator recording_to_remove = (++it).base();
+ llassert((*recording_to_remove)->mTargetRecording == recording);
+ delete *recording_to_remove;
+ mActiveRecordings.erase(recording_to_remove);
+ }
+}
+
+ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target )
+: mTargetRecording(target)
+{
+}
+
+void ThreadRecorder::ActiveRecording::movePartialToTarget()
+{
+ mTargetRecording->mBuffers.write()->append(mPartialRecording);
+ // reset based on self to keep history
+ mPartialRecording.reset(&mPartialRecording);
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// SlaveThreadRecorder
+///////////////////////////////////////////////////////////////////////
+
+SlaveThreadRecorder::SlaveThreadRecorder(MasterThreadRecorder& master)
+: mMasterRecorder(master)
+{
+ mMasterRecorder.addSlaveThread(this);
+}
+
+SlaveThreadRecorder::~SlaveThreadRecorder()
+{
+ mMasterRecorder.removeSlaveThread(this);
+}
+
+void SlaveThreadRecorder::pushToMaster()
+{
+ mThreadRecording.stop();
+ {
+ LLMutexLock(mMasterRecorder.getSlaveListMutex());
+ mSharedData.appendFrom(mThreadRecording);
+ }
+ mThreadRecording.start();
+}
+
+void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ appendRecording(source);
+}
+
+void SlaveThreadRecorder::SharedData::appendTo( Recording& sink )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ sink.appendRecording(*this);
+}
+
+void SlaveThreadRecorder::SharedData::mergeFrom( const RecordingBuffers& source )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ mBuffers.write()->merge(source);
+}
+
+void SlaveThreadRecorder::SharedData::mergeTo( RecordingBuffers& sink )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ sink.merge(*mBuffers);
+}
+
+void SlaveThreadRecorder::SharedData::reset()
+{
+ LLMutexLock lock(&mRecordingMutex);
+ Recording::reset();
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// MasterThreadRecorder
+///////////////////////////////////////////////////////////////////////
+
+static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data");
+void MasterThreadRecorder::pullFromSlaveThreads()
+{
+ LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES);
+ if (mActiveRecordings.empty()) return;
+
+ LLMutexLock lock(&mSlaveListMutex);
+
+ RecordingBuffers& target_recording_buffers = mActiveRecordings.back()->mPartialRecording;
+ for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end();
+ it != end_it;
+ ++it)
+ {
+ // ignore block timing info for now
+ (*it)->mSharedData.mergeTo(target_recording_buffers);
+ (*it)->mSharedData.reset();
+ }
+}
+
+void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child )
+{
+ LLMutexLock lock(&mSlaveListMutex);
+
+ mSlaveThreadRecorders.push_back(child);
+}
+
+void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child )
+{
+ LLMutexLock lock(&mSlaveListMutex);
+
+ for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end();
+ it != end_it;
+ ++it)
+ {
+ if ((*it) == child)
+ {
+ mSlaveThreadRecorders.erase(it);
+ break;
+ }
+ }
+}
+
+void MasterThreadRecorder::pushToMaster()
+{}
+
+MasterThreadRecorder::MasterThreadRecorder()
+{}
+
+}
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
new file mode 100644
index 0000000000..bf3701304f
--- /dev/null
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -0,0 +1,126 @@
+/**
+ * @file lltrace.h
+ * @brief Runtime statistics accumulation.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTRACETHREADRECORDER_H
+#define LL_LLTRACETHREADRECORDER_H
+
+#include "stdtypes.h"
+#include "llpreprocessor.h"
+
+#include "llmutex.h"
+#include "lltracerecording.h"
+
+namespace LLTrace
+{
+ class LL_COMMON_API ThreadRecorder
+ {
+ protected:
+ struct ActiveRecording;
+ typedef std::vector<ActiveRecording*> active_recording_list_t;
+ public:
+ ThreadRecorder();
+
+ virtual ~ThreadRecorder();
+
+ void activate(Recording* recording);
+ void deactivate(Recording* recording);
+ active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording);
+
+ virtual void pushToMaster() = 0;
+
+ TimeBlockTreeNode* getTimeBlockTreeNode(S32 index);
+
+ protected:
+ struct ActiveRecording
+ {
+ ActiveRecording(Recording* target);
+
+ Recording* mTargetRecording;
+ RecordingBuffers mPartialRecording;
+
+ void movePartialToTarget();
+ };
+ Recording mThreadRecording;
+
+ active_recording_list_t mActiveRecordings;
+
+ class BlockTimer* mRootTimer;
+ TimeBlockTreeNode* mTimeBlockTreeNodes;
+ size_t mNumTimeBlockTreeNodes;
+ };
+
+ class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder
+ {
+ public:
+ MasterThreadRecorder();
+
+ void addSlaveThread(class SlaveThreadRecorder* child);
+ void removeSlaveThread(class SlaveThreadRecorder* child);
+
+ /*virtual */ void pushToMaster();
+
+ // call this periodically to gather stats data from slave threads
+ void pullFromSlaveThreads();
+
+ LLMutex* getSlaveListMutex() { return &mSlaveListMutex; }
+
+
+ private:
+
+ typedef std::list<class SlaveThreadRecorder*> slave_thread_recorder_list_t;
+
+ slave_thread_recorder_list_t mSlaveThreadRecorders; // list of slave thread recorders associated with this master
+ LLMutex mSlaveListMutex; // protects access to slave list
+ };
+
+ class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder
+ {
+ public:
+ SlaveThreadRecorder(MasterThreadRecorder& master);
+ ~SlaveThreadRecorder();
+
+ // call this periodically to gather stats data for master thread to consume
+ /*virtual*/ void pushToMaster();
+
+ MasterThreadRecorder* mMaster;
+
+ class SharedData : public Recording
+ {
+ public:
+ void appendFrom(const Recording& source);
+ void appendTo(Recording& sink);
+ void mergeFrom(const RecordingBuffers& source);
+ void mergeTo(RecordingBuffers& sink);
+ void reset();
+ private:
+ LLMutex mRecordingMutex;
+ };
+ SharedData mSharedData;
+ MasterThreadRecorder& mMasterRecorder;
+ };
+}
+
+#endif // LL_LLTRACETHREADRECORDER_H
diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h
deleted file mode 100755
index 0b6862444e..0000000000
--- a/indra/llcommon/lltypeinfolookup.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @file lltypeinfolookup.h
- * @author Nat Goodspeed
- * @date 2012-04-08
- * @brief Template data structure like std::map<std::type_info*, T>
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Copyright (c) 2012, Linden Research, Inc.
- * $/LicenseInfo$
- */
-
-#if ! defined(LL_LLTYPEINFOLOOKUP_H)
-#define LL_LLTYPEINFOLOOKUP_H
-
-#include <boost/unordered_map.hpp>
-#include <boost/functional/hash.hpp>
-#include <boost/optional.hpp>
-#include <functional> // std::binary_function
-#include <typeinfo>
-
-/**
- * The following helper classes are based on the Boost.Unordered documentation:
- * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
- */
-
-/**
- * Compute hash for a string passed as const char*
- */
-struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
-{
- std::size_t operator()(const char* str) const
- {
- std::size_t seed = 0;
- for ( ; *str; ++str)
- {
- boost::hash_combine(seed, *str);
- }
- return seed;
- }
-};
-
-/**
- * Compute equality for strings passed as const char*
- *
- * I (nat) suspect that this is where the default behavior breaks for the
- * const char* values returned from std::type_info::name(). If you compare the
- * two const char* pointer values, as a naive, unspecialized implementation
- * will surely do, they'll compare unequal.
- */
-struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
-{
- bool operator()(const char* lhs, const char* rhs) const
- {
- return strcmp(lhs, rhs) == 0;
- }
-};
-
-/**
- * LLTypeInfoLookup is specifically designed for use cases for which you might
- * consider std::map<std::type_info*, VALUE>. We have several such data
- * structures in the viewer. The trouble with them is that at least on Linux,
- * you can't rely on always getting the same std::type_info* for a given type:
- * different load modules will produce different std::type_info*.
- * LLTypeInfoLookup contains a workaround to address this issue.
- *
- * The API deliberately diverges from std::map in several respects:
- * * It avoids iterators, not only begin()/end() but also as return values
- * from insert() and find(). This bypasses transform_iterator overhead.
- * * Since we literally use compile-time types as keys, the essential insert()
- * and find() methods accept the key type as a @em template parameter,
- * accepting and returning value_type as a normal runtime value. This is to
- * permit future optimization (e.g. compile-time type hashing) without
- * changing the API.
- */
-template <typename VALUE>
-class LLTypeInfoLookup
-{
- // Use this for our underlying implementation: lookup by
- // std::type_info::name() string. This is one of the rare cases in which I
- // dare use const char* directly, rather than std::string, because I'm
- // sure that every value returned by std::type_info::name() is static.
- // HOWEVER, specify our own hash + equality functors: naively comparing
- // distinct const char* values won't work.
- typedef boost::unordered_map<const char*, VALUE,
- const_char_star_hash, const_char_star_equal> impl_map_type;
-
-public:
- typedef VALUE value_type;
-
- LLTypeInfoLookup() {}
-
- bool empty() const { return mMap.empty(); }
- std::size_t size() const { return mMap.size(); }
-
- template <typename KEY>
- bool insert(const value_type& value)
- {
- // Obtain and store the std::type_info::name() string as the key.
- // Return just the bool from std::map::insert()'s return pair.
- return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second;
- }
-
- template <typename KEY>
- boost::optional<value_type> find() const
- {
- // Use the std::type_info::name() string as the key.
- typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name());
- if (found == mMap.end())
- return boost::optional<value_type>();
- return found->second;
- }
-
-private:
- impl_map_type mMap;
-};
-
-#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
new file mode 100644
index 0000000000..2402cdbb95
--- /dev/null
+++ b/indra/llcommon/llunit.h
@@ -0,0 +1,563 @@
+/**
+ * @file llunit.h
+ * @brief Unit conversion classes
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLUNIT_H
+#define LL_LLUNIT_H
+
+#include "stdtypes.h"
+#include "llpreprocessor.h"
+#include "llerrorlegacy.h"
+#include <boost/type_traits/is_same.hpp>
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE>
+struct LLUnit
+{
+ typedef LLUnit<STORAGE_TYPE, UNIT_TYPE> self_t;
+ typedef STORAGE_TYPE storage_t;
+
+ // value initialization
+ LLUnit(storage_t value = storage_t())
+ : mValue(value)
+ {}
+
+ // unit initialization and conversion
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ LLUnit(LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ : mValue(convert(other).mValue)
+ {}
+
+ bool operator == (const self_t& other)
+ {
+ return mValue = other.mValue;
+ }
+
+ // value assignment
+ self_t& operator = (storage_t value)
+ {
+ mValue = value;
+ return *this;
+ }
+
+ // unit assignment
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ self_t& operator = (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ {
+ mValue = convert(other).mValue;
+ return *this;
+ }
+
+ storage_t value() const
+ {
+ return mValue;
+ }
+
+ template<typename NEW_UNIT_TYPE>
+ STORAGE_TYPE getAs()
+ {
+ return LLUnit<STORAGE_TYPE, NEW_UNIT_TYPE>(*this).value();
+ }
+
+ template<typename NEW_UNIT_TYPE>
+ STORAGE_TYPE setAs(STORAGE_TYPE val)
+ {
+ *this = LLUnit<STORAGE_TYPE, NEW_UNIT_TYPE>(val);
+ }
+
+ void operator += (storage_t value)
+ {
+ mValue += value;
+ }
+
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator += (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ {
+ mValue += convert(other).mValue;
+ }
+
+ void operator -= (storage_t value)
+ {
+ mValue -= value;
+ }
+
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ void operator -= (LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ {
+ mValue -= convert(other).mValue;
+ }
+
+ void operator *= (storage_t multiplicand)
+ {
+ mValue *= multiplicand;
+ }
+
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator *= (LLUnit<OTHER_STORAGE, OTHER_UNIT> multiplicand)
+ {
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Multiplication of unit types not supported.");
+ }
+
+ void operator /= (storage_t divisor)
+ {
+ mValue /= divisor;
+ }
+
+ template<typename OTHER_UNIT, typename OTHER_STORAGE>
+ void operator /= (LLUnit<OTHER_STORAGE, OTHER_UNIT> divisor)
+ {
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ LL_BAD_TEMPLATE_INSTANTIATION(OTHER_UNIT, "Illegal in-place division of unit types.");
+ }
+
+ template<typename SOURCE_STORAGE, typename SOURCE_UNITS>
+ static self_t convert(LLUnit<SOURCE_STORAGE, SOURCE_UNITS> v)
+ {
+ self_t result;
+ ll_convert_units(v, result);
+ return result;
+ }
+
+protected:
+ storage_t mValue;
+};
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE>
+struct LLUnitImplicit : public LLUnit<STORAGE_TYPE, UNIT_TYPE>
+{
+ typedef LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> self_t;
+ typedef typename LLUnit<STORAGE_TYPE, UNIT_TYPE>::storage_t storage_t;
+ typedef LLUnit<STORAGE_TYPE, UNIT_TYPE> base_t;
+
+ LLUnitImplicit(storage_t value = storage_t())
+ : base_t(value)
+ {}
+
+ template<typename OTHER_STORAGE, typename OTHER_UNIT>
+ LLUnitImplicit(LLUnit<OTHER_STORAGE, OTHER_UNIT> other)
+ : base_t(convert(other))
+ {}
+
+ // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc)
+ // this allows for interoperability with legacy code
+ operator storage_t() const
+ {
+ return base_t::value();
+ }
+};
+
+
+template<typename S1, typename T1, typename S2, typename T2>
+LL_FORCE_INLINE void ll_convert_units(LLUnit<S1, T1> in, LLUnit<S2, T2>& out, ...)
+{
+ typedef boost::integral_constant<bool,
+ boost::is_same<T1, T2>::value
+ || !boost::is_same<T1, typename T1::base_unit_t>::value
+ || !boost::is_same<T2, typename T2::base_unit_t>::value> conversion_valid_t;
+ LL_STATIC_ASSERT(conversion_valid_t::value, "invalid conversion");
+
+ if (boost::is_same<T1, typename T1::base_unit_t>::value)
+ {
+ if (boost::is_same<T2, typename T2::base_unit_t>::value)
+ {
+ // T1 and T2 fully reduced and equal...just copy
+ out = (S2)in.value();
+ }
+ else
+ {
+ // reduce T2
+ LLUnit<S2, typename T2::base_unit_t> new_out;
+ ll_convert_units(in, new_out);
+ ll_convert_units(new_out, out);
+ }
+ }
+ else
+ {
+ // reduce T1
+ LLUnit<S1, typename T1::base_unit_t> new_in;
+ ll_convert_units(in, new_in);
+ ll_convert_units(new_in, out);
+ }
+}
+
+//
+// operator +
+//
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result += second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result += second;
+ return result;
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result += second;
+ return result;
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result += second;
+ return result;
+}
+
+//
+// operator -
+//
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator - (SCALAR_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> result(first);
+ result -= second;
+ return result;
+}
+
+//
+// operator *
+//
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first * second.value()));
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() * second));
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");
+ return LLUnit<STORAGE_TYPE1, UNIT_TYPE1>();
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator * (SCALAR_TYPE first, LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>(first * second.value());
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>(first.value() * second);
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> operator * (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2>)
+{
+ // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
+ LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE1, "Multiplication of unit types results in new unit type - not supported.");
+ return LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1>();
+}
+
+//
+// operator /
+//
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+ return SCALAR_TYPE(first / second.value());
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() / second));
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+STORAGE_TYPE1 operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ return STORAGE_TYPE1(first.value() / first.convert(second));
+}
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+ return LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE>((STORAGE_TYPE)(first.value() / second));
+}
+
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+STORAGE_TYPE1 operator / (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second)
+{
+ return STORAGE_TYPE1(first.value() / first.convert(second));
+}
+
+#define COMPARISON_OPERATORS(op) \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE> \
+bool operator op (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second) \
+{ \
+ return first op second.value(); \
+} \
+ \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE> \
+bool operator op (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second) \
+{ \
+ return first.value() op second; \
+} \
+ \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+bool operator op (LLUnitImplicit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnitImplicit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
+} \
+ \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2> \
+ bool operator op (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{ \
+ return first.value() op first.convert(second); \
+}
+
+COMPARISON_OPERATORS(<)
+COMPARISON_OPERATORS(<=)
+COMPARISON_OPERATORS(>)
+COMPARISON_OPERATORS(>=)
+COMPARISON_OPERATORS(==)
+COMPARISON_OPERATORS(!=)
+
+
+template<typename T>
+struct LLGetUnitLabel
+{
+ static const char* getUnitLabel() { return ""; }
+};
+
+template<typename T, typename STORAGE_T>
+struct LLGetUnitLabel<LLUnit<STORAGE_T, T> >
+{
+ static const char* getUnitLabel() { return T::getUnitLabel(); }
+};
+
+template<typename VALUE_TYPE>
+struct LLUnitLinearOps
+{
+ typedef LLUnitLinearOps<VALUE_TYPE> self_t;
+ LLUnitLinearOps(VALUE_TYPE val) : mValue (val) {}
+
+ operator VALUE_TYPE() const { return mValue; }
+ VALUE_TYPE mValue;
+
+ template<typename T>
+ self_t operator * (T other)
+ {
+ return mValue * other;
+ }
+
+ template<typename T>
+ self_t operator / (T other)
+ {
+ return mValue / other;
+ }
+
+ template<typename T>
+ self_t operator + (T other)
+ {
+ return mValue + other;
+ }
+
+ template<typename T>
+ self_t operator - (T other)
+ {
+ return mValue - other;
+ }
+};
+
+template<typename VALUE_TYPE>
+struct LLUnitInverseLinearOps
+{
+ typedef LLUnitInverseLinearOps<VALUE_TYPE> self_t;
+
+ LLUnitInverseLinearOps(VALUE_TYPE val) : mValue (val) {}
+ operator VALUE_TYPE() const { return mValue; }
+ VALUE_TYPE mValue;
+
+ template<typename T>
+ self_t operator * (T other)
+ {
+ return mValue / other;
+ }
+
+ template<typename T>
+ self_t operator / (T other)
+ {
+ return mValue * other;
+ }
+
+ template<typename T>
+ self_t operator + (T other)
+ {
+ return mValue - other;
+ }
+
+ template<typename T>
+ self_t operator - (T other)
+ {
+ return mValue + other;
+ }
+};
+
+#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \
+struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }}
+
+#define LL_DECLARE_DERIVED_UNIT(unit_name, unit_label, base_unit_name, conversion_operation) \
+struct unit_name \
+{ \
+ typedef base_unit_name base_unit_t; \
+ static const char* getUnitLabel() { return unit_label; } \
+}; \
+ \
+template<typename S1, typename S2> \
+void ll_convert_units(LLUnit<S1, unit_name> in, LLUnit<S2, base_unit_name>& out) \
+{ \
+ out = (S2)(LLUnitLinearOps<S1>(in.value()) conversion_operation).mValue; \
+} \
+ \
+template<typename S1, typename S2> \
+void ll_convert_units(LLUnit<S1, base_unit_name> in, LLUnit<S2, unit_name>& out) \
+{ \
+ out = (S2)(LLUnitInverseLinearOps<S1>(in.value()) conversion_operation).mValue; \
+}
+
+//
+// Unit declarations
+//
+
+namespace LLUnits
+{
+LL_DECLARE_BASE_UNIT(Bytes, "B");
+LL_DECLARE_DERIVED_UNIT(Kilobytes, "KB", Bytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Megabytes, "MB", Kilobytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Gigabytes, "GB", Megabytes, * 1000);
+LL_DECLARE_DERIVED_UNIT(Kibibytes, "KiB", Bytes, * 1024);
+LL_DECLARE_DERIVED_UNIT(Mibibytes, "MiB", Kibibytes, * 1024);
+LL_DECLARE_DERIVED_UNIT(Gibibytes, "GiB", Mibibytes, * 1024);
+
+LL_DECLARE_DERIVED_UNIT(Bits, "b", Bytes, / 8);
+LL_DECLARE_DERIVED_UNIT(Kilobits, "Kb", Bytes, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Megabits, "Mb", Kilobits, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Gigabits, "Gb", Megabits, * 1000 / 8);
+LL_DECLARE_DERIVED_UNIT(Kibibits, "Kib", Bytes, * 1024 / 8);
+LL_DECLARE_DERIVED_UNIT(Mibibits, "Mib", Kibibits, * 1024 / 8);
+LL_DECLARE_DERIVED_UNIT(Gibibits, "Gib", Mibibits, * 1024 / 8);
+
+LL_DECLARE_BASE_UNIT(Seconds, "s");
+LL_DECLARE_DERIVED_UNIT(Minutes, "min", Seconds, * 60);
+LL_DECLARE_DERIVED_UNIT(Hours, "h", Seconds, * 60 * 60);
+LL_DECLARE_DERIVED_UNIT(Milliseconds, "ms", Seconds, / 1000);
+LL_DECLARE_DERIVED_UNIT(Microseconds, "\x09\x3cs", Milliseconds, / 1000);
+LL_DECLARE_DERIVED_UNIT(Nanoseconds, "ns", Microseconds, / 1000);
+
+LL_DECLARE_BASE_UNIT(Meters, "m");
+LL_DECLARE_DERIVED_UNIT(Kilometers, "km", Meters, * 1000);
+LL_DECLARE_DERIVED_UNIT(Centimeters, "cm", Meters, / 100);
+LL_DECLARE_DERIVED_UNIT(Millimeters, "mm", Meters, / 1000);
+
+LL_DECLARE_BASE_UNIT(Hertz, "Hz");
+LL_DECLARE_DERIVED_UNIT(Kilohertz, "KHz", Hertz, * 1000);
+LL_DECLARE_DERIVED_UNIT(Megahertz, "MHz", Kilohertz, * 1000);
+LL_DECLARE_DERIVED_UNIT(Gigahertz, "GHz", Megahertz, * 1000);
+
+LL_DECLARE_BASE_UNIT(Radians, "rad");
+LL_DECLARE_DERIVED_UNIT(Degrees, "deg", Radians, * 0.01745329251994);
+
+
+} // namespace LLUnits
+
+#endif // LL_LLUNIT_H
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 0aaa50d231..ba4b670b9a 100755
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -27,9 +27,7 @@
// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.
#if LL_WINDOWS
-#undef WIN32_LEAN_AND_MEAN
-#include <winsock2.h>
-#include <windows.h>
+#include "llwin32headers.h"
// ugh, this is ugly. We need to straighten out our linking for this library
#pragma comment(lib, "IPHLPAPI.lib")
#include <iphlpapi.h>
diff --git a/indra/llcommon/lluuidhashmap.h b/indra/llcommon/lluuidhashmap.h
deleted file mode 100755
index e294670030..0000000000
--- a/indra/llcommon/lluuidhashmap.h
+++ /dev/null
@@ -1,583 +0,0 @@
-/**
- * @file lluuidhashmap.h
- * @brief A uuid based hash map.
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLUUIDHASHMAP_H
-#define LL_LLUUIDHASHMAP_H
-
-#include "stdtypes.h"
-#include "llerror.h"
-#include "lluuid.h"
-
-// UUID hash map
-
- /*
- LLUUIDHashMap<uuid_pair, 32> foo(test_equals);
- LLUUIDHashMapIter<uuid_pair, 32> bar(&foo);
-
- LLDynamicArray<LLUUID> source_ids;
- const S32 COUNT = 100000;
- S32 q;
- for (q = 0; q < COUNT; q++)
- {
- llinfos << "Creating" << llendl;
- LLUUID id;
- id.generate();
- //llinfos << q << ":" << id << llendl;
- uuid_pair pair;
- pair.mUUID = id;
- pair.mValue = q;
- foo.set(id, pair);
- source_ids.put(id);
- //ms_sleep(1);
- }
-
- uuid_pair cur;
- llinfos << "Iterating" << llendl;
- for (cur = bar.first(); !bar.done(); cur = bar.next())
- {
- if (source_ids[cur.mValue] != cur.mUUID)
- {
- llerrs << "Incorrect value iterated!" << llendl;
- }
- //llinfos << cur.mValue << ":" << cur.mUUID << llendl;
- //ms_sleep(1);
- }
-
- llinfos << "Finding" << llendl;
- for (q = 0; q < COUNT; q++)
- {
- cur = foo.get(source_ids[q]);
- if (source_ids[cur.mValue] != cur.mUUID)
- {
- llerrs << "Incorrect value found!" << llendl;
- }
- //llinfos << res.mValue << ":" << res.mUUID << llendl;
- //ms_sleep(1);
- }
-
- llinfos << "Removing" << llendl;
- for (q = 0; q < COUNT/2; q++)
- {
- if (!foo.remove(source_ids[q]))
- {
- llerrs << "Remove failed!" << llendl;
- }
- //ms_sleep(1);
- }
-
- llinfos << "Iterating" << llendl;
- for (cur = bar.first(); !bar.done(); cur = bar.next())
- {
- if (source_ids[cur.mValue] != cur.mUUID)
- {
- llerrs << "Incorrect value found!" << llendl;
- }
- //llinfos << cur.mValue << ":" << cur.mUUID << llendl;
- //ms_sleep(1);
- }
- llinfos << "Done with UUID map test" << llendl;
-
- return 0;
- */
-
-
-//
-// LLUUIDHashNode
-//
-
-template <class DATA, int SIZE>
-class LLUUIDHashNode
-{
-public:
- LLUUIDHashNode();
-
-public:
- S32 mCount;
- U8 mKey[SIZE];
- DATA mData[SIZE];
- LLUUIDHashNode<DATA, SIZE> *mNextNodep;
-};
-
-
-//
-// LLUUIDHashNode implementation
-//
-template <class DATA, int SIZE>
-LLUUIDHashNode<DATA, SIZE>::LLUUIDHashNode()
-{
- mCount = 0;
- mNextNodep = NULL;
-}
-
-
-template <class DATA_TYPE, int SIZE>
-class LLUUIDHashMap
-{
-public:
- // basic constructor including sorter
- LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data),
- const DATA_TYPE &null_data);
- ~LLUUIDHashMap();
-
- inline DATA_TYPE &get(const LLUUID &uuid);
- inline BOOL check(const LLUUID &uuid) const;
- inline DATA_TYPE &set(const LLUUID &uuid, const DATA_TYPE &type);
- inline BOOL remove(const LLUUID &uuid);
- void removeAll();
-
- inline S32 getLength() const; // Warning, NOT O(1!)
-public:
- BOOL (*mEquals)(const LLUUID &uuid, const DATA_TYPE &data);
- LLUUIDHashNode<DATA_TYPE, SIZE> mNodes[256];
-
- S32 mIterCount;
-protected:
- DATA_TYPE mNull;
-};
-
-
-//
-// LLUUIDHashMap implementation
-//
-
-template <class DATA_TYPE, int SIZE>
-LLUUIDHashMap<DATA_TYPE, SIZE>::LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data),
- const DATA_TYPE &null_data)
-: mEquals(equals),
- mIterCount(0),
- mNull(null_data)
-{ }
-
-template <class DATA_TYPE, int SIZE>
-LLUUIDHashMap<DATA_TYPE, SIZE>::~LLUUIDHashMap()
-{
- removeAll();
-}
-
-template <class DATA_TYPE, int SIZE>
-void LLUUIDHashMap<DATA_TYPE, SIZE>::removeAll()
-{
- S32 bin;
- for (bin = 0; bin < 256; bin++)
- {
- LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin];
-
- BOOL first = TRUE;
- while (nodep)
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- nodep->mData[i] = mNull;
- }
-
- nodep->mCount = 0;
- // Done with all objects in this node, go to the next.
-
- LLUUIDHashNode<DATA_TYPE, SIZE>* curp = nodep;
- nodep = nodep->mNextNodep;
-
- // Delete the node if it's not the first node
- if (first)
- {
- first = FALSE;
- curp->mNextNodep = NULL;
- }
- else
- {
- delete curp;
- }
- }
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-inline S32 LLUUIDHashMap<DATA_TYPE, SIZE>::getLength() const
-{
- S32 count = 0;
- S32 bin;
- for (bin = 0; bin < 256; bin++)
- {
- LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = (LLUUIDHashNode<DATA_TYPE, SIZE>*) &mNodes[bin];
- while (nodep)
- {
- count += nodep->mCount;
- nodep = nodep->mNextNodep;
- }
- }
- return count;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::get(const LLUUID &uuid)
-{
- LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]];
-
- // Grab the second byte of the UUID, which is the key for the node data
- const S32 second_byte = uuid.mData[1];
- while (nodep)
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i]))
- {
- // The second byte matched, and our equality test passed.
- // We found it.
- return nodep->mData[i];
- }
- }
-
- // Done with all objects in this node, go to the next.
- nodep = nodep->mNextNodep;
- }
- return mNull;
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::check(const LLUUID &uuid) const
-{
- const LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]];
-
- // Grab the second byte of the UUID, which is the key for the node data
- const S32 second_byte = uuid.mData[1];
- while (nodep)
- {
- S32 i;
- const S32 count = nodep->mCount;
-
- // Iterate through all members of this node
- for (i = 0; i < count; i++)
- {
- if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i]))
- {
- // The second byte matched, and our equality test passed.
- // We found it.
- return TRUE;
- }
- }
-
- // Done with all objects in this node, go to the next.
- nodep = nodep->mNextNodep;
- }
-
- // Didn't find anything
- return FALSE;
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::set(const LLUUID &uuid, const DATA_TYPE &data)
-{
- // Set is just like a normal find, except that if we find a match
- // we replace it with the input value.
- // If we don't find a match, we append to the end of the list.
-
- LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]];
-
- const S32 second_byte = uuid.mData[1];
- while (1)
- {
- const S32 count = nodep->mCount;
-
- S32 i;
- for (i = 0; i < count; i++)
- {
- if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i]))
- {
- // We found a match for this key, replace the data with
- // the incoming data.
- nodep->mData[i] = data;
- return nodep->mData[i];
- }
- }
- if (!nodep->mNextNodep)
- {
- // We've iterated through all of the keys without finding a match
- if (i < SIZE)
- {
- // There's still some space on this node, append
- // the key and data to it.
- nodep->mKey[i] = second_byte;
- nodep->mData[i] = data;
- nodep->mCount++;
-
- return nodep->mData[i];
- }
- else
- {
- // This node is full, append a new node to the end.
- nodep->mNextNodep = new LLUUIDHashNode<DATA_TYPE, SIZE>;
- nodep->mNextNodep->mKey[0] = second_byte;
- nodep->mNextNodep->mData[0] = data;
- nodep->mNextNodep->mCount = 1;
-
- return nodep->mNextNodep->mData[0];
- }
- }
-
- // No match on this node, go to the next
- nodep = nodep->mNextNodep;
- }
-}
-
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::remove(const LLUUID &uuid)
-{
- if (mIterCount)
- {
- // We don't allow remove when we're iterating, it's bad karma!
- llerrs << "Attempted remove while an outstanding iterator in LLUUIDHashMap!" << llendl;
- }
- // Remove is the trickiest operation.
- // What we want to do is swap the last element of the last
- // node if we find the one that we want to remove, but we have
- // to deal with deleting the node from the tail if it's empty, but
- // NOT if it's the only node left.
-
- LLUUIDHashNode<DATA_TYPE, SIZE> *nodep = &mNodes[uuid.mData[0]];
-
- // Not empty, we need to search through the nodes
- const S32 second_byte = uuid.mData[1];
-
- // A modification of the standard search algorithm.
- while (nodep)
- {
- const S32 count = nodep->mCount;
-
- S32 i;
- for (i = 0; i < count; i++)
- {
- if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i]))
- {
- // We found the node that we want to remove.
- // Find the last (and next-to-last) node, and the index of the last
- // element. We could conceviably start from the node we're on,
- // but that makes it more complicated, this is easier.
-
- LLUUIDHashNode<DATA_TYPE, SIZE> *prevp = &mNodes[uuid.mData[0]];
- LLUUIDHashNode<DATA_TYPE, SIZE> *lastp = prevp;
-
- // Find the last and next-to-last
- while (lastp->mNextNodep)
- {
- prevp = lastp;
- lastp = lastp->mNextNodep;
- }
-
- // First, swap in the last to the current location.
- nodep->mKey[i] = lastp->mKey[lastp->mCount - 1];
- nodep->mData[i] = lastp->mData[lastp->mCount - 1];
-
- // Now, we delete the entry
- lastp->mCount--;
- lastp->mData[lastp->mCount] = mNull;
-
- if (!lastp->mCount)
- {
- // We deleted the last element!
- if (lastp != &mNodes[uuid.mData[0]])
- {
- // Only blitz the node if it's not the head
- // Set the previous node to point to NULL, then
- // blitz the empty last node
- prevp->mNextNodep = NULL;
- delete lastp;
- }
- }
- return TRUE;
- }
- }
-
- // Iterate to the next node, we've scanned all the entries in this one.
- nodep = nodep->mNextNodep;
- }
- return FALSE;
-}
-
-
-//
-// LLUUIDHashMapIter
-//
-
-template <class DATA_TYPE, int SIZE>
-class LLUUIDHashMapIter
-{
-public:
- LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *hash_mapp);
- ~LLUUIDHashMapIter();
-
-
- inline void reset();
- inline void first();
- inline void next();
- inline BOOL done() const;
-
- DATA_TYPE& operator*() const
- {
- return mCurHashNodep->mData[mCurHashNodeKey];
- }
- DATA_TYPE* operator->() const
- {
- return &(operator*());
- }
-
-protected:
- LLUUIDHashMap<DATA_TYPE, SIZE> *mHashMapp;
- LLUUIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep;
-
- S32 mCurHashMapNodeNum;
- S32 mCurHashNodeKey;
-
- DATA_TYPE mNull;
-};
-
-
-//
-// LLUUIDHashMapIter Implementation
-//
-template <class DATA_TYPE, int SIZE>
-LLUUIDHashMapIter<DATA_TYPE, SIZE>::LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *hash_mapp)
-{
- mHashMapp = hash_mapp;
- mCurHashNodep = NULL;
- mCurHashMapNodeNum = 0;
- mCurHashNodeKey = 0;
-}
-
-template <class DATA_TYPE, int SIZE>
-LLUUIDHashMapIter<DATA_TYPE, SIZE>::~LLUUIDHashMapIter()
-{
- reset();
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::reset()
-{
- if (mCurHashNodep)
- {
- // We're partway through an iteration, we can clean up now
- mHashMapp->mIterCount--;
- mCurHashNodep = NULL;
- }
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::first()
-{
- // Iterate through until we find the first non-empty node;
- S32 i;
- for (i = 0; i < 256; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
- if (!mCurHashNodep)
- {
- // Increment, since it's no longer safe for us to do a remove
- mHashMapp->mIterCount++;
- }
-
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
- }
-
- // Completely empty!
- mCurHashNodep = NULL;
- //return mNull;
- return;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline BOOL LLUUIDHashMapIter<DATA_TYPE, SIZE>::done() const
-{
- return mCurHashNodep ? FALSE : TRUE;
-}
-
-template <class DATA_TYPE, int SIZE>
-inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::next()
-{
- // No current entry, this iterator is done
- if (!mCurHashNodep)
- {
- //return mNull;
- return;
- }
-
- // Go to the next element
- mCurHashNodeKey++;
- if (mCurHashNodeKey < mCurHashNodep->mCount)
- {
- // We're not done with this node, return the current element
- //return mCurHashNodep->mData[mCurHashNodeKey];
- return;
- }
-
- // Done with this node, move to the next
- mCurHashNodep = mCurHashNodep->mNextNodep;
- if (mCurHashNodep)
- {
- // Return the first element
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
-
- // Find the next non-empty node (keyed on the first byte)
- mCurHashMapNodeNum++;
-
- S32 i;
- for (i = mCurHashMapNodeNum; i < 256; i++)
- {
- if (mHashMapp->mNodes[i].mCount)
- {
- // We found one that wasn't empty
- mCurHashNodep = &mHashMapp->mNodes[i];
- mCurHashMapNodeNum = i;
- mCurHashNodeKey = 0;
- //return mCurHashNodep->mData[0];
- return;
- }
- }
-
- // OK, we're done, nothing else to iterate
- mCurHashNodep = NULL;
- mHashMapp->mIterCount--; // Decrement since we're safe to do removes now
- //return mNull;
-}
-
-#endif // LL_LLUUIDHASHMAP_H
diff --git a/indra/llcommon/reflective.h b/indra/llcommon/llwin32headers.h
index da5c5a2630..cf85067d95 100755..100644
--- a/indra/llcommon/reflective.h
+++ b/indra/llcommon/llwin32headers.h
@@ -1,10 +1,8 @@
/**
- * @file reflective.h
- * @author Babbage
- * @date 2006-05-15
- * @brief Interface that must be implemented by all reflective classes.
+ * @file llwindows.h
+ * @brief sanitized include of windows header files
*
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
@@ -26,17 +24,19 @@
* $/LicenseInfo$
*/
-#ifndef LL_REFLECTIVE_H
-#define LL_REFLECTIVE_H
+#ifndef LL_LLWINDOWS_H
+#define LL_LLWINDOWS_H
-class LLMetaClass;
-class LL_COMMON_API LLReflective
-{
-public:
- LLReflective();
- virtual ~LLReflective();
-
- virtual const LLMetaClass& getMetaClass() const = 0;
-};
+#ifdef LL_WINDOWS
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#undef WIN32_LEAN_AND_MEAN
+#include <winsock2.h>
+#include <windows.h>
+// reset to default, which is lean
+#define WIN32_LEAN_AND_MEAN
+#undef NOMINMAX
+#endif
-#endif // LL_REFLECTIVE_H
+#endif
diff --git a/indra/llcommon/lldarrayptr.h b/indra/llcommon/llwin32headerslean.h
index c9a0b204d1..f7e71301a8 100755..100644
--- a/indra/llcommon/lldarrayptr.h
+++ b/indra/llcommon/llwin32headerslean.h
@@ -1,6 +1,6 @@
/**
- * @file lldarrayptr.h
- * @brief Wrapped std::vector for backward compatibility.
+ * @file llwindows.h
+ * @brief sanitized include of windows header files
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,14 +23,18 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LL_LLDARRAYPTR_H
-#define LL_LLDARRAYPTR_H
-#include "lldarray.h"
+#ifndef LL_LLWINDOWS_H
+#define LL_LLWINDOWS_H
-template <class Type, int BlockSize = 32>
-class LLDynamicArrayPtr : public LLDynamicArray<Type, BlockSize>
-{
-};
+#ifdef LL_WINDOWS
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <winsock2.h>
+#include <windows.h>
+#undef NOMINMAX
+#endif
-#endif // LL_LLDARRAYPTR_H
+#endif
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index be46394d6e..09776816a8 100755
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -26,10 +26,11 @@
#ifndef LL_LLWORKERTHREAD_H
#define LL_LLWORKERTHREAD_H
-#include <queue>
-#include <string>
+#include <list>
#include <map>
+#include <queue>
#include <set>
+#include <string>
#include "llqueuedthread.h"
#include "llapr.h"
diff --git a/indra/llcommon/metaclass.cpp b/indra/llcommon/metaclass.cpp
deleted file mode 100755
index 5e403511cf..0000000000
--- a/indra/llcommon/metaclass.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file metaclass.cpp
- * @author Babbage
- * @date 2006-05-15
- * @brief Implementation of LLMetaClass
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "metaclass.h"
-
-#include "metaproperty.h"
-#include "reflective.h"
-
-LLMetaClass::LLMetaClass()
-{
-}
-
-//virtual
-LLMetaClass::~LLMetaClass()
-{
-}
-
-const LLMetaProperty* LLMetaClass::findProperty(const std::string& name) const
-{
- PropertyIterator iter = mProperties.find(name);
- if(iter == mProperties.end())
- {
- return NULL;
- }
- return (*iter).second;
-}
-
-void LLMetaClass::addProperty(const LLMetaProperty* property)
-{
- mProperties.insert(std::make_pair(property->getName(), property));
-}
-
-U32 LLMetaClass::getPropertyCount() const
-{
- return mProperties.size();
-}
-
-LLMetaClass::PropertyIterator LLMetaClass::beginProperties() const
-{
- return mProperties.begin();
-}
-
-LLMetaClass::PropertyIterator LLMetaClass::endProperties() const
-{
- return mProperties.end();
-}
-
-bool LLMetaClass::isInstance(const LLReflective* object) const
-{
- // TODO: Babbage: Search through super classes of objects MetaClass.
- const LLMetaClass* object_meta_class = &(object->getMetaClass());
- return (object_meta_class == this);
-}
-
diff --git a/indra/llcommon/metaclass.h b/indra/llcommon/metaclass.h
deleted file mode 100755
index 626757d58d..0000000000
--- a/indra/llcommon/metaclass.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file metaclass.h
- * @author Babbage
- * @date 2006-05-15
- * @brief Reflective meta information describing a class.
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_METACLASS_H
-#define LL_METACLASS_H
-
-#include <string>
-#include <map>
-
-#include "stdtypes.h"
-
-class LLReflective;
-class LLMetaProperty;
-class LLMetaMethod;
-class LL_COMMON_API LLMetaClass
-{
-public:
-
- LLMetaClass();
- virtual ~LLMetaClass();
-
- // Create instance of this MetaClass. NULL if class is abstract.
- // Gives ownership of returned object.
- // virtual LLReflective* create() const = 0;
-
- // Returns named property or NULL.
- const LLMetaProperty* findProperty(const std::string& name) const;
-
- // Add property to metaclass. Takes ownership of given property.
- void addProperty(const LLMetaProperty* property);
-
- typedef std::map<std::string, const LLMetaProperty*>::const_iterator PropertyIterator;
-
- U32 getPropertyCount() const;
-
- PropertyIterator beginProperties() const;
- PropertyIterator endProperties() const;
-
- // Returns named property or NULL.
- // const LLMetaMethod* findMethod(const std::string& name) const;
-
- // Add method to metaclass. Takes ownership of given method.
- // void addMethod(const LLMetaMethod* method);
-
- // Find MetaClass by name. NULL if name is unknown.
- // static LLMetaClass* findClass(const std::string& name);
-
- // True if object is instance of this meta class.
- bool isInstance(const LLReflective* object) const;
-
-private:
-
- typedef std::map<std::string, const LLMetaProperty*> PropertyMap;
- PropertyMap mProperties;
-};
-
-#endif // LL_METACLASS_H
diff --git a/indra/llcommon/metaclasst.h b/indra/llcommon/metaclasst.h
deleted file mode 100755
index b9a7ae219d..0000000000
--- a/indra/llcommon/metaclasst.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file metaclasst.h
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_METACLASST_H
-#define LL_METACLASST_H
-
-#include "metaclass.h"
-
-template<class TObject>
-class LLMetaClassT : public LLMetaClass
-{
- public:
-
- virtual ~LLMetaClassT() {;}
-
- static const LLMetaClassT& instance()
- {
- static const LLMetaClassT& instance = buildMetaClass();
- return instance;
- }
-
- private:
-
- static const LLMetaClassT& buildMetaClass()
- {
- LLMetaClassT& meta_class = *(new LLMetaClassT());
- reflectProperties(meta_class);
- return meta_class;
- }
-
- LLMetaClassT() {;}
-
- static void reflectProperties(LLMetaClass&)
- {
- }
-};
-
-#endif // LL_METACLASST_H
diff --git a/indra/llcommon/metaproperty.h b/indra/llcommon/metaproperty.h
deleted file mode 100755
index bd5bb1a30f..0000000000
--- a/indra/llcommon/metaproperty.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file metaproperty.h
- * @author Babbage
- * @date 2006-05-15
- * @brief Reflective meta information describing a property of a class.
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_METAPROPERTY_H
-#define LL_METAPROPERTY_H
-
-#include "stdtypes.h"
-#include "llsd.h"
-#include "reflective.h"
-
-class LLMetaClass;
-class LLReflective;
-class LL_COMMON_API LLMetaProperty
-{
-public:
- LLMetaProperty(const std::string& name, const LLMetaClass& object_class);
- virtual ~LLMetaProperty();
-
- // Get property name.
- const std::string& getName() const {return mName;}
-
- // Get value of this property.
- virtual const LLReflective* get(const LLReflective* object) const = 0;
-
- // Set value of this property.
- // virtual void set(LLReflective* object, const LLReflective* value) = 0;
-
- // Get value of this property as LLSD. Default returns undefined LLSD.
- virtual LLSD getLLSD(const LLReflective* object) const = 0;
-
- // Get the MetaClass of legal values of this property.
- // const LLMetaClass& getValueMetaClass();
-
- // Get the meta class that this property is a member of.
- const LLMetaClass& getObjectMetaClass() const;
-
-protected:
-
- // Check object is instance of object class, throw exception if not.
- void checkObjectClass(const LLReflective* object) const;
-
-private:
-
- std::string mName;
- const LLMetaClass& mObjectClass;
-};
-
-#endif // LL_METAPROPERTY_H
diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h
deleted file mode 100755
index 7a36c161da..0000000000
--- a/indra/llcommon/metapropertyt.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * @file metapropertyt.h
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_METAPROPERTYT_H
-#define LL_METAPROPERTYT_H
-
-#include "llsd.h"
-#include "llstring.h"
-#include "metaclasst.h"
-#include "metaproperty.h"
-#include "reflectivet.h"
-
-template<class TProperty>
-class LLMetaPropertyT : public LLMetaProperty
-{
-public:
-
- virtual ~LLMetaPropertyT() {;}
-
- // Get value of this property. Gives ownership of returned value.
- virtual const LLReflective* get(const LLReflective* object) const
- {
- checkObjectClass(object);
- return getProperty(object);
- }
-
- // Set value of this property.
- /*virtual void set(LLReflective* object, const LLReflective* value)
- {
- // TODO: Babbage: Check types.
- ref(object) = static_cast<const LLReflectiveT<TProperty>* >(value)->getValue();
- }*/
-
- // Get value of this property as LLSD.
- virtual LLSD getLLSD(const LLReflective* object) const
- {
- return LLSD();
- }
-
-protected:
-
- LLMetaPropertyT(const std::string& name, const LLMetaClass& object_class) : LLMetaProperty(name, object_class) {;}
-
- virtual const TProperty* getProperty(const LLReflective* object) const = 0;
-};
-
-template <>
-inline const LLReflective* LLMetaPropertyT<S32>::get(const LLReflective* object) const
-{
- checkObjectClass(object);
- return NULL;
-}
-
-template <>
-inline const LLReflective* LLMetaPropertyT<std::string>::get(const LLReflective* object) const
-{
- checkObjectClass(object);
- return NULL;
-}
-
-template <>
-inline const LLReflective* LLMetaPropertyT<LLUUID>::get(const LLReflective* object) const
-{
- checkObjectClass(object);
- return NULL;
-}
-
-template <>
-inline const LLReflective* LLMetaPropertyT<bool>::get(const LLReflective* object) const
-{
- checkObjectClass(object);
- return NULL;
-}
-
-template <>
-inline LLSD LLMetaPropertyT<S32>::getLLSD(const LLReflective* object) const
-{
- return *(getProperty(object));
-}
-
-template <>
-inline LLSD LLMetaPropertyT<std::string>::getLLSD(const LLReflective* object) const
-{
- return *(getProperty(object));
-}
-
-template <>
-inline LLSD LLMetaPropertyT<LLUUID>::getLLSD(const LLReflective* object) const
-{
- return *(getProperty(object));
-}
-
-template <>
-inline LLSD LLMetaPropertyT<bool>::getLLSD(const LLReflective* object) const
-{
- return *(getProperty(object));
-}
-
-template<class TObject, class TProperty>
-class LLMetaPropertyTT : public LLMetaPropertyT<TProperty>
-{
-public:
-
- LLMetaPropertyTT(const std::string& name, const LLMetaClass& object_class, TProperty (TObject::*property)) :
- LLMetaPropertyT<TProperty>(name, object_class), mProperty(property) {;}
-
-protected:
-
- // Get void* to property.
- virtual const TProperty* getProperty(const LLReflective* object) const
- {
- const TObject* typed_object = static_cast<const TObject*>(object);
- return &(typed_object->*mProperty);
- };
-
-private:
-
- TProperty (TObject::*mProperty);
-};
-
-template<class TObject, class TProperty>
-class LLMetaPropertyPtrTT : public LLMetaPropertyT<TProperty>
-{
-public:
-
- LLMetaPropertyPtrTT(const std::string& name, const LLMetaClass& object_class, TProperty* (TObject::*property)) :
- LLMetaPropertyT<TProperty>(name, object_class), mProperty(property) {;}
-
-protected:
-
- // Get void* to property.
- virtual const TProperty* getProperty(const LLReflective* object) const
- {
- const TObject* typed_object = static_cast<const TObject*>(object);
- return typed_object->*mProperty;
- };
-
-private:
-
- TProperty* (TObject::*mProperty);
-};
-
-// Utility function to simplify the registration of members.
-template<class TObject, class TProperty>
-void reflectProperty(LLMetaClass& meta_class, const std::string& name, TProperty (TObject::*property))
-{
- typedef LLMetaPropertyTT<TObject, TProperty> PropertyType;
- const LLMetaProperty* meta_property = new PropertyType(name, meta_class, property);
- meta_class.addProperty(meta_property);
-}
-
-// Utility function to simplify the registration of ptr properties.
-template<class TObject, class TProperty>
-void reflectPtrProperty(LLMetaClass& meta_class, const std::string& name, TProperty* (TObject::*property))
-{
- typedef LLMetaPropertyPtrTT<TObject, TProperty> PropertyType;
- const LLMetaProperty* meta_property = new PropertyType(name, meta_class, property);
- meta_class.addProperty(meta_property);
-}
-
-#endif // LL_METAPROPERTYT_H
diff --git a/indra/llcommon/reflectivet.h b/indra/llcommon/reflectivet.h
deleted file mode 100755
index 958921f23e..0000000000
--- a/indra/llcommon/reflectivet.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file reflectivet.h
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_REFLECTIVET_H
-#define LL_REFLECTIVET_H
-
-#include "reflective.h"
-
-template <class T>
-class LLReflectiveT : public LLReflective
-{
-public:
-
- LLReflectiveT(const T& value) : mValue(value) {;}
- virtual ~LLReflectiveT() {;}
-
- virtual const LLMetaClass& getMetaClass() const {return LLMetaClassT<LLReflectiveT<T> >::instance();}
-
- const T& getValue() const {return mValue;}
-
-private:
-
- T mValue;
-};
-
-#endif
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
new file mode 100644
index 0000000000..a5df51f6de
--- /dev/null
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -0,0 +1,219 @@
+/**
+ * @file llsingleton_test.cpp
+ * @date 2011-08-11
+ * @brief Unit test for the LLSingleton class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llunit.h"
+#include "../test/lltut.h"
+
+namespace LLUnits
+{
+ // using powers of 2 to allow strict floating point equality
+ LL_DECLARE_BASE_UNIT(Quatloos, "Quat");
+ LL_DECLARE_DERIVED_UNIT(Latinum, "Lat", Quatloos, * 4);
+ LL_DECLARE_DERIVED_UNIT(Solari, "Sol", Latinum, / 16);
+}
+
+namespace tut
+{
+ using namespace LLUnits;
+ struct units
+ {
+ };
+
+ typedef test_group<units> units_t;
+ typedef units_t::object units_object_t;
+ tut::units_t tut_singleton("LLUnit");
+
+ // storage type conversions
+ template<> template<>
+ void units_object_t::test<1>()
+ {
+ LLUnit<F32, Quatloos> float_quatloos;
+ ensure(float_quatloos == 0.f);
+
+ LLUnit<F32, Quatloos> float_initialize_quatloos(1);
+ ensure(float_initialize_quatloos == 1.f);
+
+ LLUnit<S32, Quatloos> int_quatloos;
+ ensure(int_quatloos == 0);
+
+ int_quatloos = 42;
+ ensure(int_quatloos == 42);
+ float_quatloos = int_quatloos;
+ ensure(float_quatloos == 42.f);
+
+ int_quatloos = float_quatloos;
+ ensure(int_quatloos == 42);
+
+ float_quatloos = 42.1f;
+ ensure(float_quatloos == 42.1f);
+ int_quatloos = float_quatloos;
+ ensure(int_quatloos == 42);
+ LLUnit<U32, Quatloos> unsigned_int_quatloos(float_quatloos);
+ ensure(unsigned_int_quatloos == 42);
+ }
+
+ // conversions to/from base unit
+ template<> template<>
+ void units_object_t::test<2>()
+ {
+ LLUnit<F32, Quatloos> quatloos(1.f);
+ ensure(quatloos == 1.f);
+ LLUnit<F32, Latinum> latinum_bars(quatloos);
+ ensure(latinum_bars == 1.f / 4.f);
+
+ latinum_bars = 256;
+ quatloos = latinum_bars;
+ ensure(quatloos == 1024);
+
+ LLUnit<F32, Solari> solari(quatloos);
+ ensure(solari == 4096);
+ }
+
+ // conversions across non-base units
+ template<> template<>
+ void units_object_t::test<3>()
+ {
+ LLUnit<F32, Solari> solari = 4.f;
+ LLUnit<F32, Latinum> latinum_bars = solari;
+ ensure(latinum_bars == 0.25f);
+ }
+
+ // math operations
+ template<> template<>
+ void units_object_t::test<4>()
+ {
+ LLUnit<F32, Quatloos> quatloos = 1.f;
+ quatloos *= 4.f;
+ ensure(quatloos == 4);
+ quatloos = quatloos * 2;
+ ensure(quatloos == 8);
+ quatloos = 2.f * quatloos;
+ ensure(quatloos == 16);
+
+ quatloos += 4.f;
+ ensure(quatloos == 20);
+ quatloos += 4;
+ ensure(quatloos == 24);
+ quatloos = quatloos + 4;
+ ensure(quatloos == 28);
+ quatloos = 4 + quatloos;
+ ensure(quatloos == 32);
+ quatloos += quatloos * 3;
+ ensure(quatloos == 128);
+
+ quatloos -= quatloos / 4 * 3;
+ ensure(quatloos == 32);
+ quatloos = quatloos - 8;
+ ensure(quatloos == 24);
+ quatloos -= 4;
+ ensure(quatloos == 20);
+ quatloos -= 4.f;
+ ensure(quatloos == 16);
+
+ quatloos *= 2.f;
+ ensure(quatloos == 32);
+ quatloos = quatloos * 2.f;
+ ensure(quatloos == 64);
+ quatloos = 0.5f * quatloos;
+ ensure(quatloos == 32);
+
+ quatloos /= 2.f;
+ ensure(quatloos == 16);
+ quatloos = quatloos / 4;
+ ensure(quatloos == 4);
+
+ F32 ratio = quatloos / LLUnit<F32, Quatloos>(4.f);
+ ensure(ratio == 1);
+ ratio = quatloos / LLUnit<F32, Solari>(16.f);
+ ensure(ratio == 1);
+
+ quatloos += LLUnit<F32, Solari>(4.f);
+ ensure(quatloos == 5);
+ quatloos -= LLUnit<F32, Latinum>(1.f);
+ ensure(quatloos == 1);
+ }
+
+ // implicit units
+ template<> template<>
+ void units_object_t::test<5>()
+ {
+ // 0-initialized
+ LLUnit<F32, Quatloos> quatloos(0);
+ // initialize implicit unit from explicit
+ LLUnitImplicit<F32, Quatloos> quatloos_implicit = quatloos + 1;
+ ensure(quatloos_implicit == 1);
+
+ // assign implicit to explicit, or perform math operations
+ quatloos = quatloos_implicit;
+ ensure(quatloos == 1);
+ quatloos += quatloos_implicit;
+ ensure(quatloos == 2);
+
+ // math operations on implicits
+ quatloos_implicit = 1;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit += 2;
+ ensure(quatloos_implicit == 3);
+
+ quatloos_implicit *= 2;
+ ensure(quatloos_implicit == 6);
+
+ quatloos_implicit -= 1;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit /= 5;
+ ensure(quatloos_implicit == 1);
+
+ quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit;
+ ensure(quatloos_implicit == 5);
+
+ quatloos_implicit = 10 - quatloos_implicit - 1;
+ ensure(quatloos_implicit == 4);
+
+ quatloos_implicit = 2 * quatloos_implicit * 2;
+ ensure(quatloos_implicit == 16);
+
+ F32 one_half = quatloos_implicit / (quatloos_implicit * 2);
+ ensure(one_half == 0.5f);
+
+ // implicit conversion to POD
+ F32 float_val = quatloos_implicit;
+ ensure(float_val == 16);
+
+ S32 int_val = quatloos_implicit;
+ ensure(int_val == 16);
+
+ // conversion of implicits
+ LLUnitImplicit<F32, Latinum> latinum_implicit(2);
+ ensure(latinum_implicit == 2);
+
+ ensure(latinum_implicit * 2 == quatloos_implicit);
+ }
+}
diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp
deleted file mode 100755
index 8980ebb1f1..0000000000
--- a/indra/llcommon/tests/reflection_test.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * @file reflection_test.cpp
- * @date May 2006
- * @brief Reflection unit tests.
- *
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "../linden_common.h"
-#include "../reflective.h"
-#include "../metaclasst.h"
-#include "../metapropertyt.h"
-#include "../stdtypes.h"
-
-#include "../test/lltut.h"
-
-namespace tut
-{
- class TestAggregatedData : public LLReflective
- {
- public:
- TestAggregatedData() {;}
- virtual const LLMetaClass& getMetaClass() const;
-
- private:
- };
-
- class TestReflectionData : public LLReflective
- {
- public:
- TestReflectionData() : mInt(42), mString("foo"), mNullPtr(NULL), mPtr(new TestAggregatedData()), mRef(*(new TestAggregatedData)) {;}
- virtual ~TestReflectionData() {delete mPtr;}
- virtual const LLMetaClass& getMetaClass() const;
-
- static U32 getPropertyCount() {return 5;}
-
- private:
-
- friend class LLMetaClassT<TestReflectionData>;
- S32 mInt;
- std::string mString;
- TestAggregatedData* mNullPtr;
- TestAggregatedData* mPtr;
- TestAggregatedData mObj;
- TestAggregatedData& mRef;
- };
-}
-
-template <>
-void LLMetaClassT<tut::TestReflectionData>::reflectProperties(LLMetaClass& meta_class)
-{
- reflectProperty(meta_class, "mInt", &tut::TestReflectionData::mInt);
- reflectProperty(meta_class, "mString", &tut::TestReflectionData::mString);
- reflectPtrProperty(meta_class, "mNullPtr", &tut::TestReflectionData::mNullPtr);
- reflectPtrProperty(meta_class, "mPtr", &tut::TestReflectionData::mPtr);
- reflectProperty(meta_class, "mObj", &tut::TestReflectionData::mObj);
- //reflectProperty(meta_class, "mRef", &tut::TestReflectionData::mRef); // AARGH!
-}
-
-namespace tut
-{
- // virtual
- const LLMetaClass& TestReflectionData::getMetaClass() const
- {
- return LLMetaClassT<TestReflectionData>::instance();
- }
-
- const LLMetaClass& TestAggregatedData::getMetaClass() const
- {
- return LLMetaClassT<TestAggregatedData>::instance();
- }
-}
-
-namespace tut
-{
- typedef tut::test_group<TestReflectionData> TestReflectionGroup;
- typedef TestReflectionGroup::object TestReflectionObject;
- TestReflectionGroup gTestReflectionGroup("reflection");
-
- template<> template<>
- void TestReflectionObject::test<1>()
- {
- // Check properties can be found.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- const LLMetaProperty* null = NULL;
- ensure_not_equals(meta_class.findProperty("mInt"), null);
- ensure_not_equals(meta_class.findProperty("mString"), null);
- }
-
- template<> template<>
- void TestReflectionObject::test<2>()
- {
- // Check non-existent property cannot be found.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- const LLMetaProperty* null = NULL;
- ensure_equals(meta_class.findProperty("foo"), null);
- }
-
- template<> template<>
- void TestReflectionObject::test<3>()
- {
- // Check integer property has correct value.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- ensure_equals(meta_class.findProperty("mInt")->getLLSD(this).asInteger(), 42);
- }
-
- template<> template<>
- void TestReflectionObject::test<4>()
- {
- // Check string property has correct value.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- ensure_equals(meta_class.findProperty("mString")->getLLSD(this).asString(), std::string("foo"));
- }
-
- template<> template<>
- void TestReflectionObject::test<5>()
- {
- // Check NULL reference property has correct value.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- const LLReflective* null = NULL;
- ensure_equals(meta_class.findProperty("mNullPtr")->get(this), null);
- }
-
- template<> template<>
- void TestReflectionObject::test<6>()
- {
- // Check reference property has correct value.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- const LLReflective* null = NULL;
- const LLReflective* ref = meta_class.findProperty("mPtr")->get(this);
- ensure_not_equals(ref, null);
- }
-
- template<> template<>
- void TestReflectionObject::test<7>()
- {
- // Check reflective property has correct value.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- const LLReflective* null = NULL;
- const LLReflective* ref = meta_class.findProperty("mObj")->get(this);
- ensure_not_equals(ref, null);
- }
-
- template<> template<>
- void TestReflectionObject::test<8>()
- {
- // Check property count.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- ensure_equals(meta_class.getPropertyCount(), TestReflectionData::getPropertyCount());
- }
-
- template<> template<>
- void TestReflectionObject::test<9>()
- {
- // Check property iteration.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- U32 count = 0;
- LLMetaClass::PropertyIterator iter;
- for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter)
- {
- ++count;
- }
- ensure_equals(count, TestReflectionData::getPropertyCount());
- }
-
- template<> template<>
- void TestReflectionObject::test<10>()
- {
- // Check meta classes of different types do not compare equal.
- const LLMetaClass* reflection_data_meta_class = &(LLMetaClassT<TestReflectionData>::instance());
- const LLMetaClass* aggregated_data_meta_class = &(LLMetaClassT<TestAggregatedData>::instance());
- ensure_not_equals(reflection_data_meta_class, aggregated_data_meta_class);
- }
-
- template<> template<>
- void TestReflectionObject::test<11>()
- {
- // Check class cast checks.
- const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance();
- TestAggregatedData* aggregated_data = new TestAggregatedData();
- LLMetaClass::PropertyIterator iter;
- U32 exception_count = 0;
- for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter)
- {
- try
- {
- const LLMetaProperty* property = (*iter).second;
- const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception.
-
- // useless op to get rid of compiler warning.
- reflective = reflective;
- }
- catch(...)
- {
- ++exception_count;
- }
- }
- ensure_equals(exception_count, getPropertyCount());
-
- }
-}
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index 21a916b13b..402e725152 100755
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -72,7 +72,7 @@ private:
inline void RefCounted::addRef() const
{
- S32 count(mRefCount++);
+ S32 count(++mRefCount);
llassert_always(count >= 0);
}
@@ -82,7 +82,7 @@ inline void RefCounted::release() const
S32 count(mRefCount);
llassert_always(count != NOT_REF_COUNTED);
llassert_always(count > 0);
- count = mRefCount--;
+ count = --mRefCount;
// clean ourselves up if that was the last reference
if (0 == count)
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 1c25256e95..50df2ebe55 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -50,6 +50,7 @@ LLMutex* LLImage::sMutex = NULL;
bool LLImage::sUseNewByteRange = false;
S32 LLImage::sMinimalReverseByteRangePercent = 75;
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
+LLTrace::MemStatHandle LLImageBase::sMemStat("LLImage");
//static
void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
@@ -158,6 +159,7 @@ void LLImageBase::sanityCheck()
void LLImageBase::deleteData()
{
FREE_MEM(sPrivatePoolp, mData) ;
+ memDisclaimAmount(mDataSize);
mData = NULL;
mDataSize = 0;
}
@@ -201,6 +203,7 @@ U8* LLImageBase::allocateData(S32 size)
mBadBufferAllocation = true ;
}
mDataSize = size;
+ memClaimAmount(mDataSize);
}
return mData;
@@ -222,7 +225,9 @@ U8* LLImageBase::reallocateData(S32 size)
FREE_MEM(sPrivatePoolp, mData) ;
}
mData = new_datap;
+ memDisclaimAmount(mDataSize);
mDataSize = size;
+ memClaimAmount(mDataSize);
return mData;
}
@@ -288,7 +293,6 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
: LLImageBase()
{
-
if(no_copy)
{
setDataAndSize(data, width, height, components);
@@ -1608,7 +1612,9 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
void LLImageBase::setDataAndSize(U8 *data, S32 size)
{
ll_assert_aligned(data, 16);
+ memDisclaimAmount(mDataSize);
mData = data; mDataSize = size;
+ memClaimAmount(mDataSize);
}
//static
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 4fc40ecff7..504b7e4795 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,6 +30,7 @@
#include "lluuid.h"
#include "llstring.h"
#include "llthread.h"
+#include "lltrace.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -110,7 +111,9 @@ protected:
//============================================================================
// Image base class
-class LLImageBase : public LLThreadSafeRefCount
+class LLImageBase
+: public LLThreadSafeRefCount,
+ public LLTrace::MemTrackable<LLImageBase>
{
protected:
virtual ~LLImageBase();
@@ -162,6 +165,8 @@ public:
static void destroyPrivatePool() ;
static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;}
+ static LLTrace::MemStatHandle sMemStat;
+
private:
U8 *mData;
S32 mDataSize;
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index e255d65b43..b6f2694742 100755
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -31,6 +31,8 @@
#include "../llimageworker.h"
// For timer class
#include "../llcommon/lltimer.h"
+// for lltrace class
+#include "../llcommon/lltrace.h"
// Tut header
#include "../test/lltut.h"
@@ -42,6 +44,9 @@
// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
// * A simulator for a class can be implemented here. Please comment and document thoroughly.
+LLTrace::MemStatHandle LLImageBase::sMemStat("LLImage");
+
+
LLImageBase::LLImageBase()
: mData(NULL),
mDataSize(0),
@@ -114,11 +119,13 @@ namespace tut
// Constructor and destructor of the test wrapper
imagedecodethread_test()
{
+ LLTrace::init();
mThread = NULL;
}
~imagedecodethread_test()
{
delete mThread;
+ LLTrace::cleanup();
}
};
@@ -136,6 +143,8 @@ namespace tut
imagerequest_test()
{
done = false;
+ LLTrace::init();
+
mRequest = new LLImageDecodeThread::ImageRequest(0, 0,
LLQueuedThread::PRIORITY_NORMAL, 0, FALSE,
new responder_test(&done));
@@ -145,6 +154,7 @@ namespace tut
// We should delete the object *but*, because its destructor is protected, that cannot be
// done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine...
//delete mRequest;
+ LLTrace::cleanup();
}
};
diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h
index eb2ecf71ba..47fcf688a2 100755
--- a/indra/llinventory/lleconomy.h
+++ b/indra/llinventory/lleconomy.h
@@ -27,6 +27,7 @@
#define LL_LLECONOMY_H
#include "llsingleton.h"
+#include <list>
class LLMessageSystem;
class LLVector3;
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 41d58c6deb..2a319c635f 100755
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -28,6 +28,7 @@
#include "llinventory.h"
#include "lldbstrings.h"
+#include "llfasttimer.h"
#include "llinventorydefines.h"
#include "llxorcipher.h"
#include "llsd.h"
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index 7e013de11a..55067cde73 100755
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -31,7 +31,6 @@
// library includes
#include "message.h"
-#include "metapropertyt.h"
#include "llsd.h"
///----------------------------------------------------------------------------
@@ -895,21 +894,6 @@ std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)
return s;
}
-template <>
-void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class)
-{
- reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator);
- reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner);
- reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup);
- reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned);
-}
-
-// virtual
-const LLMetaClass& LLPermissions::getMetaClass() const
-{
- return LLMetaClassT<LLPermissions>::instance();
-}
-
///----------------------------------------------------------------------------
/// Class LLAggregatePermissions
///----------------------------------------------------------------------------
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index 3ecc922370..89c66f6ebd 100755
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -31,7 +31,6 @@
#include "llsd.h"
#include "lluuid.h"
#include "llxmlnode.h"
-#include "reflective.h"
#include "llinventorytype.h"
// prototypes
@@ -83,7 +82,7 @@ template<class T> class LLMetaClassT;
// logical consistency.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLPermissions : public LLReflective
+class LLPermissions
{
private:
LLUUID mCreator; // null if object created by system
@@ -324,9 +323,6 @@ public:
friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm);
- // Reflection.
- friend class LLMetaClassT<LLPermissions>;
- virtual const LLMetaClass& getMetaClass() const;
};
// Inlines
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index 62c245f125..14fbf344ab 100755
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -43,7 +43,9 @@
// End Stubbing
// -------------------------------------------------------------------------------------------
-// Stubb the LL Image Classes
+// Stub the LL Image Classes
+LLTrace::MemStatHandle LLImageBase::sMemStat("LLImage");
+
LLImageRaw::LLImageRaw() { }
LLImageRaw::~LLImageRaw() { }
U8* LLImageRaw::allocateData(S32 ) { return NULL; }
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 22ba26f99b..054afd3e95 100755
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -161,7 +161,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
// ---------------- test methods ----------------
-S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
+S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius, const LLPlane* planes)
{
static const LLVector4a scaler[] = {
LLVector4a(-1,-1,-1),
@@ -174,6 +174,12 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
LLVector4a( 1, 1, 1)
};
+ if(!planes)
+ {
+ //use agent space
+ planes = mAgentPlanes;
+ }
+
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -183,7 +189,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
mask = mPlaneMask[i];
if (mask != 0xff)
{
- const LLPlane& p(mAgentPlanes[i]);
+ const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, scaler[mask]);
minp.setSub(center, rscale);
@@ -204,8 +210,14 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
return result?1:2;
}
+//exactly same as the function AABBInFrustum(...)
+//except uses mRegionPlanes instead of mAgentPlanes.
+S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)
+{
+ return AABBInFrustum(center, radius, mRegionPlanes);
+}
-S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
+S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)
{
static const LLVector4a scaler[] = {
LLVector4a(-1,-1,-1),
@@ -218,6 +230,12 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
LLVector4a( 1, 1, 1)
};
+ if(!planes)
+ {
+ //use agent space
+ planes = mAgentPlanes;
+ }
+
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -227,7 +245,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
mask = mPlaneMask[i];
if ((i != 5) && (mask != 0xff))
{
- const LLPlane& p(mAgentPlanes[i]);
+ const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, scaler[mask]);
minp.setSub(center, rscale);
@@ -248,6 +266,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
return result?1:2;
}
+//exactly same as the function AABBInFrustumNoFarClip(...)
+//except uses mRegionPlanes instead of mAgentPlanes.
+S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
+{
+ return AABBInFrustumNoFarClip(center, radius, mRegionPlanes);
+}
+
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
{
LLVector3 dist = sphere_center-mFrustCenter;
@@ -584,6 +609,23 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
}
}
+//calculate regional planes from mAgentPlanes.
+//vector "shift" is the vector of the region origin in the agent space.
+void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift)
+{
+ F32 d;
+ LLVector3 n;
+ for(S32 i = 0 ; i < 7; i++)
+ {
+ if (mPlaneMask[i] != 0xff)
+ {
+ n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]);
+ d = mAgentPlanes[i][3] + n * shift;
+ mRegionPlanes[i].setVec(n, d);
+ }
+ }
+}
+
void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)
{
LLVector3 a, b, c;
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 0b591be622..898d73ed7e 100755
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -109,6 +109,7 @@ public:
private:
LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ LL_ALIGN_16(LLPlane mRegionPlanes[7]); //frustum planes in a local region space, derived from mAgentPlanes
U8 mPlaneMask[8]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@@ -178,6 +179,7 @@ public:
// Return number of bytes copied.
size_t readFrustumFromBuffer(const char *buffer);
void calcAgentFrustumPlanes(LLVector3* frust);
+ void calcRegionFrustumPlanes(const LLVector3& shift); //calculate regional planes from mAgentPlanes.
void ignoreAgentFrustumPlane(S32 idx);
// Returns 1 if partly in, 2 if fully in.
@@ -186,8 +188,10 @@ public:
S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
- S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius);
- S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
+ S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
+ S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius);
+ S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
+ S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
//does a quick 'n dirty sphere-sphere check
S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index c4e1f0c84c..7867d2c546 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1392,7 +1392,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
@@ -1446,7 +1446,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
pt->mScale.mV[VX] = hole_x * lerp(taper_x_begin, taper_x_end, t);
pt->mScale.mV[VY] = hole_y * lerp(taper_y_begin, taper_y_end, t);
pt->mTexT = t;
-
+
// Twist rotates the path along the x,y plane (I think) - DJS 04/05/02
twist.setQuat (lerp(twist_begin,twist_end,t) * 2.f * F_PI - F_PI,0,0,1);
// Rotate the point around the circle's center.
@@ -4615,7 +4615,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
n1.add(n2);
n1.add(n3);
-
+
*normal = n1;
}
@@ -6130,7 +6130,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
S32 size = (grid_size+1)*(grid_size+1);
resizeVertices(size);
-
+
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
LLVector2* tc = (LLVector2*) mTexCoords;
@@ -6151,7 +6151,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
*pos++ = newVert.getPosition();
*norm++ = baseVert.getNormal();
*tc++ = newVert.mTexCoord;
-
+
if (gx == 0 && gy == 0)
{
min = newVert.getPosition();
@@ -6227,7 +6227,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
if (!(mTypeMask & HOLLOW_MASK) && !(mTypeMask & OPEN_MASK))
{
resizeVertices(num_vertices+1);
-
+
if (!partial_build)
{
resizeIndices(num_indices+3);
@@ -6236,7 +6236,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
else
{
resizeVertices(num_vertices);
-
+
if (!partial_build)
{
resizeIndices(num_indices);
@@ -6270,7 +6270,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
LLVector2* tc = (LLVector2*) mTexCoords;
LLVector4a* pos = (LLVector4a*) mPositions;
LLVector4a* norm = (LLVector4a*) mNormals;
-
+
// Copy the vertices into the array
for (S32 i = 0; i < num_vertices; i++)
{
@@ -6552,7 +6552,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
-
+
LLVector4a d0,d1;
d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
@@ -6562,13 +6562,13 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
normal.setCross3(d0,d1);
if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
- {
+ {
normal.normalize3fast();
}
else
{ //degenerate, make up a value
normal.set(0,0,1);
- }
+ }
llassert(llfinite(normal.getF32ptr()[0]));
llassert(llfinite(normal.getF32ptr()[1]));
@@ -6577,7 +6577,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
llassert(!llisnan(normal.getF32ptr()[0]));
llassert(!llisnan(normal.getF32ptr()[1]));
llassert(!llisnan(normal.getF32ptr()[2]));
-
+
for (S32 i = 0; i < num_vertices; i++)
{
norm[i].load4a(normal.getF32ptr());
@@ -6592,7 +6592,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
void LLVolumeFace::createTangents()
{
if (!mTangents)
- {
+ {
allocateTangents(mNumVertices);
//generate tangents
@@ -6602,7 +6602,7 @@ void LLVolumeFace::createTangents()
LLVector4a* end = mTangents+mNumVertices;
while (binorm < end)
- {
+ {
(*binorm++).clear();
}
@@ -7221,7 +7221,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
for (U32 a = 0; a < triangleCount; a++)
- {
+{
U32 i1 = *index_array++;
U32 i2 = *index_array++;
U32 i3 = *index_array++;
@@ -7265,7 +7265,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
tan1[i1].add(sdir);
tan1[i2].add(sdir);
tan1[i3].add(sdir);
-
+
tan2[i1].add(tdir);
tan2[i2].add(tdir);
tan2[i3].add(tdir);
@@ -7276,13 +7276,13 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
LLVector4a n = normal[a];
const LLVector4a& t = tan1[a];
-
+
llassert(tan1[a].getLength3().getF32() >= 0.f);
llassert(tan2[a].getLength3().getF32() >= 0.f);
LLVector4a ncrosst;
ncrosst.setCross3(n,t);
-
+
// Gram-Schmidt orthogonalize
n.mul(n.dot3(t).getF32());
@@ -7290,7 +7290,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
tsubn.setSub(t,n);
if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
- {
+ {
tsubn.normalize3fast();
// Calculate handedness
@@ -7309,12 +7309,12 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
llassert(!llisnan(tangent[a].getF32ptr()[0]));
llassert(!llisnan(tangent[a].getF32ptr()[1]));
llassert(!llisnan(tangent[a].getF32ptr()[2]));*/
- }
- else
+ }
+ else
{ //degenerate, make up a value
tangent[a].set(0,0,1,1);
}
- }
+ }
ll_aligned_free_16(tan1);
}
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index b047f86e6e..0d632f59be 100755
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -49,10 +49,10 @@ class LLColor4
LLColor4(); // Initializes LLColor4 to (0, 0, 0, 1)
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
- LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
- LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
explicit LLColor4(const LLSD& sd);
+ explicit LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
+ explicit LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 9b86daebe5..430c9503ac 100755
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -50,10 +50,14 @@
#include "lltransfertargetvfile.h" // For debugging
#include "llmetrics.h"
+#include "lltrace.h"
LLAssetStorage *gAssetStorage = NULL;
LLMetrics *LLAssetStorage::metric_recipient = NULL;
+static LLTrace::CountStatHandle<> sFailedDownloadCount("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed");
+
+
const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010"));
const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds
@@ -450,6 +454,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE);
}
return;
@@ -460,6 +465,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
// Special case early out for NULL uuid and for shutting down
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
}
return;
@@ -572,6 +578,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at
llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
}
}
@@ -649,6 +656,10 @@ void LLAssetStorage::downloadCompleteCallback(
LLAssetRequest* tmp = *curiter;
if (tmp->mDownCallback)
{
+ if (result != LL_ERR_NOERR)
+ {
+ add(sFailedDownloadCount, 1);
+ }
tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
}
delete tmp;
@@ -669,6 +680,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
// Special case early out for NULL uuid
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
}
return;
@@ -741,6 +753,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
}
}
@@ -783,6 +796,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
}
}
+ if (result != LL_ERR_NOERR)
+ {
+ add(sFailedDownloadCount, 1);
+ }
req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
}
@@ -883,6 +900,7 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
if (callback)
{
+ add(sFailedDownloadCount, 1);
callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
}
}
@@ -925,6 +943,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
}
}
+ if (result != LL_ERR_NOERR)
+ {
+ add(sFailedDownloadCount, 1);
+ }
req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
}
@@ -1237,6 +1259,7 @@ bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* re
}
if (req->mDownCallback)
{
+ add(sFailedDownloadCount, 1);
req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
}
if (req->mInfoCallback)
@@ -1363,6 +1386,10 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAss
}
}
+ if (status != LL_ERR_NOERR)
+ {
+ add(sFailedDownloadCount, 1);
+ }
legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status);
delete legacy;
}
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 01da20f060..1722b48f44 100755
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -32,6 +32,7 @@
#include "llmath.h"
#include "llstl.h"
#include "llthread.h"
+#include <iterator>
#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked());
diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h
index b0a638c16e..226752d52e 100755
--- a/indra/llmessage/lldatapacker.h
+++ b/indra/llmessage/lldatapacker.h
@@ -170,6 +170,7 @@ public:
S32 getBufferSize() const { return mBufferSize; }
const U8* getBuffer() const { return mBufferp; }
void reset() { mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); }
+ void shift(S32 offset) { reset(); mCurBufferp += offset;}
void freeBuffer() { delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = FALSE; }
void assignBuffer(U8 *bufferp, S32 size)
{
diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp
index b2dc414a68..7ac3651a76 100755
--- a/indra/llmessage/lldispatcher.cpp
+++ b/indra/llmessage/lldispatcher.cpp
@@ -29,6 +29,7 @@
#include "lldispatcher.h"
#include <algorithm>
+#include <iterator>
#include "llstl.h"
#include "message.h"
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
index e0ca056a5f..dbb8c4e28d 100755
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ b/indra/llmessage/llfiltersd2xmlrpc.cpp
@@ -80,6 +80,7 @@
#include "llbuffer.h"
#include "llbufferstream.h"
+#include "llfasttimer.h"
#include "llmemorystream.h"
#include "llsd.h"
#include "llsdserialize.h"
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 1236fc8b71..f9d37b2e39 100755
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -33,6 +33,7 @@
#include "llapr.h"
#include "llbuffer.h"
#include "llbufferstream.h"
+#include "llfasttimer.h"
#include "llhttpnode.h"
#include "lliopipe.h"
#include "lliosocket.h"
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index cbd17b5a3d..9a0a427efd 100755
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -31,6 +31,7 @@
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
+#include "llwin32headerslean.h"
#include "apr_poll.h"
#include "llsd.h"
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 2043bae5e7..27e3cc7898 100755
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -32,6 +32,7 @@
#include "llapr.h"
#include "llbuffer.h"
+#include "llfasttimer.h"
#include "llhost.h"
#include "llpumpio.h"
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index be0f7dfcc6..ec998552d0 100755
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,6 +38,7 @@
*/
#include "lliopipe.h"
+#include "llwin32headerslean.h"
#include "apr_pools.h"
#include "apr_network_io.h"
#include "llchainio.h"
diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp
index 8c50fd5069..9fd49d23d4 100755
--- a/indra/llmessage/llioutil.cpp
+++ b/indra/llmessage/llioutil.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llioutil.h"
+#include "llfasttimer.h"
/**
* LLIOFlush
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 08b31e9c7a..dc27f2ca4a 100755
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -29,12 +29,7 @@
#include "llmail.h"
// APR on Windows needs full windows headers
-#ifdef LL_WINDOWS
-# undef WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
-#endif
-
+#include "llwin32headers.h"
#include <string>
#include <sstream>
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 9988fcd9c0..9b8d19cc3e 100755
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -57,13 +57,15 @@ LLProxy::LLProxy():
mAuthMethodSelected(METHOD_NOAUTH),
mSocksUsername(),
mSocksPassword()
-{
-}
+{}
LLProxy::~LLProxy()
{
- stopSOCKSProxy();
- disableHTTPProxy();
+ if (ll_apr_is_initialized())
+ {
+ stopSOCKSProxy();
+ disableHTTPProxy();
+ }
}
/**
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 0623e99f0a..e3f09f34ee 100755
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -34,6 +34,7 @@
#include "apr_poll.h"
#include "llapr.h"
+#include "llfasttimer.h"
#include "llstl.h"
// These should not be enabled in production, but they can be
diff --git a/indra/llmessage/llsdrpcclient.cpp b/indra/llmessage/llsdrpcclient.cpp
index fcda0e81a3..05b27f582c 100755
--- a/indra/llmessage/llsdrpcclient.cpp
+++ b/indra/llmessage/llsdrpcclient.cpp
@@ -30,6 +30,7 @@
#include "llsdrpcclient.h"
#include "llbufferstream.h"
+#include "llfasttimer.h"
#include "llfiltersd2xmlrpc.h"
#include "llpumpio.h"
#include "llsd.h"
diff --git a/indra/llmessage/llsdrpcserver.cpp b/indra/llmessage/llsdrpcserver.cpp
index f26ee52f71..2c233c1c0d 100755
--- a/indra/llmessage/llsdrpcserver.cpp
+++ b/indra/llmessage/llsdrpcserver.cpp
@@ -31,6 +31,7 @@
#include "llbuffer.h"
#include "llbufferstream.h"
+#include "llfasttimer.h"
#include "llpumpio.h"
#include "llsdserialize.h"
#include "llstl.h"
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index de9e2fe294..7281ac35af 100755
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -33,6 +33,7 @@
#include <openssl/x509_vfy.h>
#include <openssl/ssl.h>
#include "llcurl.h"
+#include "llfasttimer.h"
#include "llioutil.h"
#include "llproxy.h"
#include "llpumpio.h"
@@ -284,6 +285,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");
static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
+static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond");
+static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout");
// virtual
LLIOPipe::EStatus LLURLRequest::process_impl(
@@ -303,7 +306,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
const S32 MIN_ACCUMULATION = 100000;
if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION))
{
- static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout");
LLFastTimer t(FTM_URL_ADJUST_TIMEOUT);
// This is a pretty sloppy calculation, but this
// tries to make the gross assumption that if data
@@ -314,11 +316,11 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
const F32 TIMEOUT_ADJUSTMENT = 2.0f;
mDetail->mByteAccumulator = 0;
pump->adjustTimeoutSeconds(TIMEOUT_ADJUSTMENT);
- lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
- if (mState == STATE_INITIALIZED)
- {
- llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
- }
+ lldebugs << "LLURLRequest adjustTimeoutSeconds for request: " << mDetail->mURL << llendl;
+ if (mState == STATE_INITIALIZED)
+ {
+ llinfos << "LLURLRequest adjustTimeoutSeconds called during upload" << llendl;
+ }
}
switch(mState)
@@ -402,7 +404,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
link.mChannels = LLBufferArray::makeChannelConsumer(
channels);
chain.push_back(link);
- static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond");
{
LLFastTimer t(FTM_PROCESS_URL_PUMP_RESPOND);
pump->respond(chain, buffer, context);
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 1589ea29c1..e94e2282a0 100755
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -50,9 +50,9 @@
#include "lltimer.h"
#include "llpacketring.h"
#include "llhost.h"
-#include "llhttpclient.h"
+#include "llcurl.h"
#include "llhttpnode.h"
-#include "llpacketack.h"
+//#include "llpacketack.h"
#include "llsingleton.h"
#include "message_prehash.h"
#include "llstl.h"
@@ -158,7 +158,6 @@ const F32 LL_MAX_LOST_TIMEOUT = 5.f; // Maximum amount of time before cons
const S32 MAX_MESSAGE_COUNT_NUM = 1024;
// Forward declarations
-class LLCircuit;
class LLVector3;
class LLVector4;
class LLVector3d;
@@ -214,19 +213,19 @@ class LLMessageSystem : public LLMessageSenderInterface
public:
LLPacketRing mPacketRing;
- LLReliablePacketParams mReliablePacketParams;
+ LLReliablePacketParams mReliablePacketParams;
// Set this flag to TRUE when you want *very* verbose logs.
- BOOL mVerboseLog;
+ BOOL mVerboseLog;
- F32 mMessageFileVersionNumber;
+ F32 mMessageFileVersionNumber;
typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
private:
message_template_name_map_t mMessageTemplates;
- message_template_number_map_t mMessageNumbers;
+ message_template_number_map_t mMessageNumbers;
public:
S32 mSystemVersionMajor;
@@ -235,7 +234,7 @@ public:
S32 mSystemVersionServer;
U32 mVersionFlags;
- BOOL mbProtected;
+ BOOL mbProtected;
U32 mNumberHighFreqMessages;
U32 mNumberMediumFreqMessages;
@@ -255,11 +254,11 @@ public:
U32 mReliablePacketsIn; // total reliable packets in
U32 mReliablePacketsOut; // total reliable packets out
- U32 mDroppedPackets; // total dropped packets in
- U32 mResentPackets; // total resent packets out
- U32 mFailedResendPackets; // total resend failure packets out
- U32 mOffCircuitPackets; // total # of off-circuit packets rejected
- U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected
+ U32 mDroppedPackets; // total dropped packets in
+ U32 mResentPackets; // total resent packets out
+ U32 mFailedResendPackets; // total resend failure packets out
+ U32 mOffCircuitPackets; // total # of off-circuit packets rejected
+ U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected
S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in
S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out
@@ -268,14 +267,14 @@ public:
S64 mTotalBytesIn; // total size of all uncompressed packets in
S64 mTotalBytesOut; // total size of all uncompressed packets out
- BOOL mSendReliable; // does the outgoing message require a pos ack?
+ BOOL mSendReliable; // does the outgoing message require a pos ack?
- LLCircuit mCircuitInfo;
+ LLCircuit mCircuitInfo;
F64 mCircuitPrintTime; // used to print circuit debug info every couple minutes
F32 mCircuitPrintFreq; // seconds
- std::map<U64, U32> mIPPortToCircuitCode;
- std::map<U32, U64> mCircuitCodeToIPPort;
+ std::map<U64, U32> mIPPortToCircuitCode;
+ std::map<U32, U64> mCircuitCodeToIPPort;
U32 mOurCircuitCode;
S32 mSendPacketFailureCount;
S32 mUnackedListDepth;
@@ -494,7 +493,7 @@ public:
void (*callback)(void **,S32),
void ** callback_data);
- LLHTTPClient::ResponderPtr createResponder(const std::string& name);
+ LLCurl::ResponderPtr createResponder(const std::string& name);
S32 sendMessage(const LLHost &host);
S32 sendMessage(const U32 circuit);
private:
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index 85aef5da00..1c9508214c 100755
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
@@ -26,15 +26,13 @@
#include "linden_common.h"
-#include "net.h"
+//#include "net.h"
// system library includes
#include <stdexcept>
#if LL_WINDOWS
- #define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>
- #include <windows.h>
+#include "llwin32headerslean.h"
#else
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h
index a9d6794e40..531422e792 100755
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -29,6 +29,7 @@
#ifndef LL_LLPLUGINPROCESSCHILD_H
#define LL_LLPLUGINPROCESSCHILD_H
+#include <queue>
#include "llpluginmessage.h"
#include "llpluginmessagepipe.h"
#include "llplugininstance.h"
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 990fc5cbae..24be7eb148 100755
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -29,6 +29,8 @@
#ifndef LL_LLPLUGINPROCESSPARENT_H
#define LL_LLPLUGINPROCESSPARENT_H
+#include <queue>
+
#include "llapr.h"
#include "llprocess.h"
#include "llpluginmessage.h"
diff --git a/indra/llplugin/tests/llplugincookiestore_test.cpp b/indra/llplugin/tests/llplugincookiestore_test.cpp
index aefa1ca144..c2cb236cba 100755
--- a/indra/llplugin/tests/llplugincookiestore_test.cpp
+++ b/indra/llplugin/tests/llplugincookiestore_test.cpp
@@ -27,6 +27,7 @@
*/
#include "linden_common.h"
+#include <list>
#include "../test/lltut.h"
#include "../llplugincookiestore.h"
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 0dd13916bf..8173083a85 100755
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -35,7 +35,6 @@ set(llprimitive_SOURCE_FILES
lltextureentry.cpp
lltreeparams.cpp
llvolumemessage.cpp
- llvolumexml.cpp
material_codes.cpp
)
@@ -55,7 +54,6 @@ set(llprimitive_HEADER_FILES
lltreeparams.h
lltree_common.h
llvolumemessage.h
- llvolumexml.h
material_codes.h
object_flags.h
)
diff --git a/indra/llprimitive/llvolumexml.cpp b/indra/llprimitive/llvolumexml.cpp
deleted file mode 100755
index bf2297a029..0000000000
--- a/indra/llprimitive/llvolumexml.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file llvolumexml.cpp
- * @brief LLVolumeXml base class
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llvolumexml.h"
-
-//============================================================================
-
-// LLVolumeXml is just a wrapper class; all members are static
-
-//============================================================================
-
-LLPointer<LLXMLNode> LLVolumeXml::exportProfileParams(const LLProfileParams* params)
-{
- LLPointer<LLXMLNode> ret = new LLXMLNode("profile", FALSE);
-
- ret->createChild("curve_type", TRUE)->setByteValue(1, &params->getCurveType());
- ret->createChild("interval", FALSE)->setFloatValue(2, &params->getBegin());
- ret->createChild("hollow", FALSE)->setFloatValue(1, &params->getHollow());
-
- return ret;
-}
-
-
-LLPointer<LLXMLNode> LLVolumeXml::exportPathParams(const LLPathParams* params)
-{
- LLPointer<LLXMLNode> ret = new LLXMLNode("path", FALSE);
- ret->createChild("curve_type", TRUE)->setByteValue(1, &params->getCurveType());
- ret->createChild("interval", FALSE)->setFloatValue(2, &params->getBegin());
- ret->createChild("scale", FALSE)->setFloatValue(2, params->getScale().mV);
- ret->createChild("shear", FALSE)->setFloatValue(2, params->getShear().mV);
- ret->createChild("twist_interval", FALSE)->setFloatValue(2, &params->getTwistBegin());
- ret->createChild("radius_offset", FALSE)->setFloatValue(1, &params->getRadiusOffset());
- ret->createChild("taper", FALSE)->setFloatValue(2, params->getTaper().mV);
- ret->createChild("revolutions", FALSE)->setFloatValue(1, &params->getRevolutions());
- ret->createChild("skew", FALSE)->setFloatValue(1, &params->getSkew());
-
- return ret;
-}
-
-
-LLPointer<LLXMLNode> LLVolumeXml::exportVolumeParams(const LLVolumeParams* params)
-{
- LLPointer<LLXMLNode> ret = new LLXMLNode("shape", FALSE);
-
- LLPointer<LLXMLNode> node ;
- node = exportPathParams(&params->getPathParams()) ;
- node->setParent(ret);
- node = exportProfileParams(&params->getProfileParams()) ;
- node->setParent(ret);
-
- return ret;
-}
-
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index c4f36cabd0..a646a0d35a 100755
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -29,6 +29,7 @@
#include "llfontgl.h"
// Linden library includes
+#include "llfasttimer.h"
#include "llfontfreetype.h"
#include "llfontbitmapcache.h"
#include "llfontregistry.h"
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index f5ca8d5b04..77aa3fcd2c 100755
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -34,13 +34,15 @@
#include "llcontrol.h"
#include "lldir.h"
#include "llwindow.h"
+#include "llxmlnode.h"
extern LLControlGroup gSavedSettings;
using std::string;
using std::map;
-bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc);
+bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
+bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
@@ -207,7 +209,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
if (root->hasName("fonts"))
{
// Expect a collection of children consisting of "font" or "font_size" entries
- bool init_succ = initFromXML(root);
+ bool init_succ = init_from_xml(this, root);
success = success || init_succ;
}
}
@@ -230,7 +232,7 @@ std::string currentOsName()
#endif
}
-bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
+bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (node->hasName("font"))
{
@@ -263,14 +265,14 @@ bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)
{
if (child_name == currentOsName())
{
- fontDescInitFromXML(child, desc);
+ font_desc_init_from_xml(child, desc);
}
}
}
return true;
}
-bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
+bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
{
LLXMLNodePtr child;
@@ -281,17 +283,17 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->hasName("font"))
{
LLFontDescriptor desc;
- bool font_succ = fontDescInitFromXML(child, desc);
+ bool font_succ = font_desc_init_from_xml(child, desc);
LLFontDescriptor norm_desc = desc.normalize();
if (font_succ)
{
// if this is the first time we've seen this font name,
// create a new template map entry for it.
- const LLFontDescriptor *match_desc = getMatchingFontDesc(desc);
+ const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);
if (match_desc == NULL)
{
// Create a new entry (with no corresponding font).
- mFontMap[norm_desc] = NULL;
+ registry->mFontMap[norm_desc] = NULL;
}
// otherwise, find the existing entry and combine data.
else
@@ -306,8 +308,8 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
desc.getFileNames().end());
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
- mFontMap.erase(*match_desc);
- mFontMap[new_desc] = NULL;
+ registry->mFontMap.erase(*match_desc);
+ registry->mFontMap[new_desc] = NULL;
}
}
}
@@ -318,7 +320,7 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)
if (child->getAttributeString("name",size_name) &&
child->getAttributeF32("size",size_value))
{
- mFontSizes[size_name] = size_value;
+ registry->mFontSizes[size_name] = size_value;
}
}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 059248fbbd..177eb6c8a5 100755
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -28,7 +28,7 @@
#ifndef LL_LLFONTREGISTRY_H
#define LL_LLFONTREGISTRY_H
-#include "llxmlnode.h"
+#include "llpointer.h"
class LLFontGL;
@@ -65,6 +65,7 @@ private:
class LLFontRegistry
{
public:
+ friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);
// create_gl_textures - set to false for test apps with no OpenGL window,
// such as llui_libtest
LLFontRegistry(bool create_gl_textures);
@@ -72,7 +73,6 @@ public:
// Load standard font info from XML file(s).
bool parseFontInfo(const std::string& xml_filename);
- bool initFromXML(LLXMLNodePtr node);
// Clear cached glyphs for all fonts.
void reset();
@@ -94,6 +94,7 @@ public:
const string_vec_t& getUltimateFallbackList() const;
private:
+ LLFontRegistry(const LLFontRegistry& other); // no-copy
LLFontGL *createFont(const LLFontDescriptor& desc);
typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;
typedef std::map<std::string,F32> font_size_map_t;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index dace572953..4b191415a7 100755
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -550,9 +550,7 @@ extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
// LL_WINDOWS
// windows gl headers depend on things like APIENTRY, so include windows.
-#define WIN32_LEAN_AND_MEAN
-#include <winsock2.h>
-#include <windows.h>
+#include "llwin32headerslean.h"
//----------------------------------------------------------------------------
#include <GL/gl.h>
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 38764eba23..01ed946d40 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -32,6 +32,7 @@
#include "llimagegl.h"
#include "llerror.h"
+#include "llfasttimer.h"
#include "llimage.h"
#include "llmath.h"
@@ -50,9 +51,9 @@ U32 wpo2(U32 i);
U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
-S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
-S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
-S32 LLImageGL::sCurBoundTextureMemory = 0;
+LLUnit<S32, LLUnits::Bytes> LLImageGL::sGlobalTextureMemory = 0;
+LLUnit<S32, LLUnits::Bytes> LLImageGL::sBoundTextureMemory = 0;
+LLUnit<S32, LLUnits::Bytes> LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
U32 LLImageGL::sCurTexName = 1;
@@ -247,7 +248,7 @@ void LLImageGL::updateStats(F32 current_time)
{
LLFastTimer t(FTM_IMAGE_UPDATE_STATS);
sLastFrameTime = current_time;
- sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
+ sBoundTextureMemory = sCurBoundTextureMemory;
sCurBoundTextureMemory = 0;
}
@@ -255,7 +256,7 @@ void LLImageGL::updateStats(F32 current_time)
S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
{
LLImageGL::sCurBoundTextureMemory += mem ;
- return LLImageGL::sCurBoundTextureMemory;
+ return LLImageGL::sCurBoundTextureMemory.value();
}
//----------------------------------------------------------------------------
@@ -1131,30 +1132,30 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip
default:
{
if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
- { //unknown internal format or unknown number of mip levels, not safe to reuse
- glDeleteTextures(numTextures, textures);
- }
- else
- {
- for (S32 i = 0; i < numTextures; ++i)
- { //remove texture from VRAM by setting its size to zero
-
- for (S32 j = 0; j <= mip_levels; j++)
+ { //unknown internal format or unknown number of mip levels, not safe to reuse
+ glDeleteTextures(numTextures, textures);
+ }
+ else
{
- gGL.getTexUnit(0)->bindManual(type, textures[i]);
+ for (S32 i = 0; i < numTextures; ++i)
+ { //remove texture from VRAM by setting its size to zero
+
+ for (S32 j = 0; j <= mip_levels; j++)
+ {
+ gGL.getTexUnit(0)->bindManual(type, textures[i]);
U32 internal_type = LLTexUnit::getInternalType(type);
glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
stop_glerror();
- }
+ }
- llassert(std::find(sDeadTextureList[type][format].begin(),
- sDeadTextureList[type][format].end(), textures[i]) ==
- sDeadTextureList[type][format].end());
+ llassert(std::find(sDeadTextureList[type][format].begin(),
+ sDeadTextureList[type][format].end(), textures[i]) ==
+ sDeadTextureList[type][format].end());
- sDeadTextureList[type][format].push_back(textures[i]);
- }
- }
- }
+ sDeadTextureList[type][format].push_back(textures[i]);
+ }
+ }
+ }
break;
}
}
@@ -1452,7 +1453,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (old_name != 0)
{
- sGlobalTextureMemoryInBytes -= mTextureMemory;
+ sGlobalTextureMemory -= mTextureMemory;
LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
@@ -1460,7 +1461,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
mTextureMemory = getMipBytes(discard_level);
- sGlobalTextureMemoryInBytes += mTextureMemory;
+ sGlobalTextureMemory += mTextureMemory;
mTexelsInGLTexture = getWidth() * getHeight() ;
// mark this as bound at this point, so we don't throw it out immediately
@@ -1619,7 +1620,7 @@ void LLImageGL::destroyGLTexture()
{
if(mTextureMemory)
{
- sGlobalTextureMemoryInBytes -= mTextureMemory;
+ sGlobalTextureMemory -= mTextureMemory;
mTextureMemory = 0;
}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 57a052b258..227ccc90bd 100755
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -34,6 +34,7 @@
#include "llpointer.h"
#include "llrefcount.h"
#include "v2math.h"
+#include "llunit.h"
#include "llrender.h"
class LLTextureAtlas ;
@@ -245,9 +246,9 @@ public:
static F32 sLastFrameTime;
// Global memory statistics
- static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem
- static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame
- static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame
+ static LLUnit<S32, LLUnits::Bytes> sGlobalTextureMemory; // Tracks main memory texmem
+ static LLUnit<S32, LLUnits::Bytes> sBoundTextureMemory; // Tracks bound texmem for last completed frame
+ static LLUnit<S32, LLUnits::Bytes> sCurBoundTextureMemory; // Tracks bound texmem for current frame
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
static BOOL sGlobalUseAnisotropic;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index c60eb8d9d9..918f5585a8 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -245,6 +245,11 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
return texture->bindDefaultImage(mIndex);
}
+ if(texture->isActiveFetching()) //in debug
+ {
+ return texture->bindDebugImage(mIndex);
+ }
+
//in audit, replace the selected texture by the default one.
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index d3cfbaf03a..fe34c218a8 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -35,6 +35,7 @@
#include "llrect.h"
#include "llgl.h"
#include "lltexture.h"
+#include "llfasttimer.h"
// Project includes
#include "llrender2dutils.h"
@@ -353,6 +354,11 @@ void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
}
+void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
+{
+ gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
+}
+
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
if (NULL == image)
@@ -639,9 +645,9 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
}
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
{
- if (NULL == image)
+ if (!image && !target)
{
llwarns << "image == NULL; aborting function" << llendl;
return;
@@ -649,8 +655,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
LLGLSUIDefault gls_ui;
-
- gGL.getTexUnit(0)->bind(image, true);
+ if(image != NULL)
+ {
+ gGL.getTexUnit(0)->bind(image, true);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(target);
+ }
gGL.color4fv(color.mV);
@@ -695,18 +707,25 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
{
gGL.pushUIMatrix();
gGL.translateUI((F32)x, (F32)y, 0.f);
-
+
F32 offset_x = F32(width/2);
F32 offset_y = F32(height/2);
gGL.translateUI(offset_x, offset_y, 0.f);
LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-
- gGL.getTexUnit(0)->bind(image, true);
+
+ if(image != NULL)
+ {
+ gGL.getTexUnit(0)->bind(image, true);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(target);
+ }
gGL.color4fv(color.mV);
-
+
gGL.begin(LLRender::QUADS);
{
LLVector3 v;
@@ -732,7 +751,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);
@@ -1044,6 +1062,8 @@ void gl_rect_2d_simple( S32 width, S32 height )
gGL.end();
}
+static LLFastTimer::DeclareTimer FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle");
+
void gl_segmented_rect_2d_tex(const S32 left,
const S32 top,
const S32 right,
@@ -1053,6 +1073,8 @@ void gl_segmented_rect_2d_tex(const S32 left,
const S32 border_size,
const U32 edges)
{
+ LLFastTimer _(FTM_RENDER_SEGMENTED_RECT);
+
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1202,18 +1224,19 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.popUIMatrix();
}
-//FIXME: rewrite to use scissor?
-void gl_segmented_rect_2d_fragment_tex(const S32 left,
- const S32 top,
- const S32 right,
- const S32 bottom,
- const S32 texture_width,
- const S32 texture_height,
- const S32 border_size,
- const F32 start_fragment,
- const F32 end_fragment,
- const U32 edges)
+void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
+ const S32 texture_width,
+ const S32 texture_height,
+ const S32 border_size,
+ const F32 start_fragment,
+ const F32 end_fragment,
+ const U32 edges)
{
+ LLFastTimer _(FTM_RENDER_SEGMENTED_RECT);
+ const S32 left = rect.mLeft;
+ const S32 right = rect.mRight;
+ const S32 top = rect.mTop;
+ const S32 bottom = rect.mBottom;
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1251,9 +1274,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
{
if (start_fragment < middle_start)
{
- u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+ u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
- x_min = (start_fragment / middle_start) * border_width_left;
+ x_min = (start_fragment / middle_start) * border_width_left;
x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
// draw bottom left
@@ -1281,7 +1304,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
+
// draw top left
gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
@@ -1343,10 +1366,10 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
if (end_fragment > middle_end)
{
- u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
- u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
- x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
- x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+ u_min = 1.f - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
+ u_max = 1.f - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
+ x_min = width_vec - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right);
+ x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
// draw bottom right
gGL.texCoord2f(u_min, 0.f);
@@ -1396,6 +1419,8 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
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)
{
+ LLFastTimer _(FTM_RENDER_SEGMENTED_RECT);
+
gGL.begin(LLRender::QUADS);
{
// draw bottom left
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index 4884422c58..2b8964742b 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -71,9 +71,10 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
@@ -105,7 +106,7 @@ typedef enum e_rounded_edge
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
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);
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 093bac20d1..ff711b8004 100755
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -57,10 +57,12 @@ public:
virtual S8 getType() const = 0 ;
virtual void setKnownDrawSize(S32 width, S32 height) = 0 ;
virtual bool bindDefaultImage(const S32 stage = 0) = 0 ;
+ virtual bool bindDebugImage(const S32 stage = 0) = 0;
virtual void forceImmediateUpdate() = 0 ;
virtual void setActive() = 0 ;
virtual S32 getWidth(S32 discard_level = -1) const = 0 ;
virtual S32 getHeight(S32 discard_level = -1) const = 0 ;
+ virtual bool isActiveFetching() = 0;
private:
//note: do not make this function public.
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 01541026b1..22ea96ee19 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -26,7 +26,7 @@
#include "linden_common.h"
-#include <boost/static_assert.hpp>
+#include "llfasttimer.h"
#include "llsys.h"
#include "llvertexbuffer.h"
// #include "llrender.h"
@@ -849,11 +849,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
- stop_glerror();
+ stop_glerror();
LLGLSLShader::startProfile();
- glDrawArrays(sGLMode[mode], first, count);
+ glDrawArrays(sGLMode[mode], first, count);
LLGLSLShader::stopProfile(count, mode);
- }
+ }
stop_glerror();
placeFence();
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 34a08603fa..c4270a62bd 100755
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -61,7 +61,6 @@ set(llui_SOURCE_FILES
llfolderview.cpp
llfolderviewitem.cpp
llfolderviewmodel.cpp
- llfunctorregistry.cpp
lliconctrl.cpp
llkeywords.cpp
lllayoutstack.cpp
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 43462bd244..53720a6044 100755
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -444,9 +444,9 @@ void LLAccordionCtrlTab::changeOpenClose(bool is_open)
}
}
-void LLAccordionCtrlTab::handleVisibilityChange(BOOL new_visibility)
+void LLAccordionCtrlTab::onVisibilityChange(BOOL new_visibility)
{
- LLUICtrl::handleVisibilityChange(new_visibility);
+ LLUICtrl::onVisibilityChange(new_visibility);
notifyParent(LLSD().with("child_visibility_change", new_visibility));
}
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index dddaa581e6..7a78700e0f 100755
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -158,7 +158,7 @@ public:
/**
* Raises notifyParent event with "child_visibility_change" = new_visibility
*/
- void handleVisibilityChange(BOOL new_visibility);
+ void onVisibilityChange(BOOL new_visibility);
// Changes expand/collapse state and triggers expand/collapse callbacks
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index a8149a9a1d..ce4d137478 100755
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -779,11 +779,11 @@ void LLButton::draw()
{
mCurGlowStrength = lerp(mCurGlowStrength,
mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
- LLCriticalDamp::getInterpolant(0.05f));
+ LLSmoothInterpolation::getInterpolant(0.05f));
}
else
{
- mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
+ mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));
}
// Draw button image, if available.
diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp
index e08ccb0b78..06f8e72c9c 100755
--- a/indra/llui/llcontainerview.cpp
+++ b/indra/llui/llcontainerview.cpp
@@ -49,7 +49,6 @@ LLContainerView::LLContainerView(const LLContainerView::Params& p)
mLabel(p.label),
mDisplayChildren(p.display_children)
{
- mCollapsible = TRUE;
mScrollContainer = NULL;
}
@@ -75,6 +74,11 @@ bool LLContainerView::addChild(LLView* child, S32 tab_group)
return res;
}
+BOOL LLContainerView::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ return handleMouseDown(x, y, mask);
+}
+
BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -84,7 +88,7 @@ BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)
}
if (!handled)
{
- if( mCollapsible && mShowLabel && (y >= getRect().getHeight() - 10) )
+ if( mShowLabel && (y >= getRect().getHeight() - 10) )
{
setDisplayChildren(!mDisplayChildren);
reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index e81600fd6c..ac92b19977 100755
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -66,6 +66,7 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -87,8 +88,5 @@ public:
protected:
BOOL mDisplayChildren;
std::string mLabel;
-public:
- BOOL mCollapsible;
-
};
#endif // LL_CONTAINERVIEW_
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 09e27a264a..d06e2c9334 100755
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -598,7 +598,7 @@ LLControlGroup* LLFloater::getControlGroup()
void LLFloater::setVisible( BOOL visible )
{
- LLPanel::setVisible(visible); // calls handleVisibilityChange()
+ LLPanel::setVisible(visible); // calls onVisibilityChange()
if( visible && mFirstLook )
{
mFirstLook = FALSE;
@@ -641,21 +641,21 @@ void LLFloater::setIsSingleInstance(BOOL is_single_instance)
// virtual
-void LLFloater::handleVisibilityChange ( BOOL new_visibility )
+void LLFloater::onVisibilityChange ( BOOL new_visibility )
{
if (new_visibility)
{
if (getHost())
getHost()->setFloaterFlashing(this, FALSE);
}
- LLPanel::handleVisibilityChange ( new_visibility );
+ LLPanel::onVisibilityChange ( new_visibility );
}
void LLFloater::openFloater(const LLSD& key)
{
llinfos << "Opening floater " << getName() << llendl;
mKey = key; // in case we need to open ourselves again
-
+
if (getSoundFlags() != SILENT
// don't play open sound for hosted (tabbed) windows
&& !getHost()
@@ -803,7 +803,7 @@ void LLFloater::closeFloater(bool app_quitting)
}
else
{
- setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called)
+ setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called)
if (!mReuseInstance)
{
destroy();
@@ -1157,11 +1157,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
{
setDocked( false, false);
}
- storeRectControl();
- mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
- LLRect screen_rect = calcScreenRect();
- mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
- }
+ storeRectControl();
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+ LLRect screen_rect = calcScreenRect();
+ mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
+ }
// gather all snapped dependents
for(handle_set_iter_t dependent_it = mDependents.begin();
@@ -3149,7 +3149,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName());
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
- parser.writeXUI(output_node, output_params, &default_params);
+ parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);
return TRUE;
}
@@ -3179,9 +3179,8 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
{
Params output_params(params);
setupParamsForExport(output_params, parent);
- Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
output_node->setName(node->getName()->mString);
- parser.writeXUI(output_node, output_params, &default_params);
+ parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);
}
// Default floater position to top-left corner of screen
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 4dba1e645f..ad0b800f1c 100755
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -302,7 +302,7 @@ public:
virtual BOOL canClose() { return TRUE; }
/*virtual*/ void setVisible(BOOL visible); // do not override
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); // do not override
void setFrontmost(BOOL take_focus = TRUE);
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index a1e1f8a988..e3b17dcb4f 100755
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -30,6 +30,7 @@
#include "llrect.h"
#include "llsd.h"
+#include <list>
#include <boost/function.hpp>
//*******************************************************
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index fdb4108afb..c7910cb883 100755..100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -489,7 +489,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
// No handler needed for focus lost since this class has no
// state that depends on it.
gFocusMgr.setMouseCapture( this );
-
+
if (!mIsSelected)
{
if(mask & MASK_CONTROL)
@@ -706,7 +706,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
}
gl_rect_2d(FOCUS_LEFT,
- focus_top,
+ focus_top,
getRect().getWidth() - 2,
focus_bottom,
bg_color, hasKeyboardFocus);
@@ -860,7 +860,7 @@ void LLFolderViewItem::draw()
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, S32_MAX, &right_x, FALSE );
}
-
+
//--------------------------------------------------------------------------------//
// Highlight string match
//
@@ -882,7 +882,7 @@ const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) c
{
return getRoot()->getFolderViewModel();
}
-
+
LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
{
return getRoot()->getFolderViewModel();
@@ -919,11 +919,11 @@ void LLFolderViewFolder::updateLabelRotation()
}
else if (isOpen())
{
- mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+ mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLSmoothInterpolation::getInterpolant(0.04f));
}
else
{
- mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+ mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLSmoothInterpolation::getInterpolant(0.025f));
}
}
@@ -1056,7 +1056,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
// animate current height towards target height
if (llabs(mCurHeight - mTargetHeight) > 1.f)
{
- mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+ mCurHeight = lerp(mCurHeight, mTargetHeight, LLSmoothInterpolation::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
requestArrange();
@@ -1577,7 +1577,7 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
item->setVisible(FALSE);
addChild(item);
-
+
// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
// Note: this happens when models are created before views or shared between views
if (!item->getViewModelItem()->hasParent())
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index e33ac1d5c2..edb32954c6 100755
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -41,12 +41,6 @@ static const F32 MAX_FRACTIONAL_SIZE = 1.f;
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
-void LLLayoutStack::OrientationNames::declareValues()
-{
- declare("horizontal", HORIZONTAL);
- declare("vertical", VERTICAL);
-}
-
//
// LLLayoutPanel
//
@@ -140,7 +134,7 @@ S32 LLLayoutPanel::getVisibleDim() const
+ (((F32)mTargetDim - min_dim) * (1.f - mCollapseAmt))));
}
-void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation )
+void LLLayoutPanel::setOrientation( LLView::EOrientation orientation )
{
mOrientation = orientation;
S32 layout_dim = llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL)
@@ -590,7 +584,7 @@ bool LLLayoutStack::animatePanels()
{
if (!mAnimatedThisFrame)
{
- panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant));
+ panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLSmoothInterpolation::getInterpolant(mOpenTimeConstant));
if (panelp->mVisibleAmt > 0.99f)
{
panelp->mVisibleAmt = 1.f;
@@ -615,7 +609,7 @@ bool LLLayoutStack::animatePanels()
{
if (!mAnimatedThisFrame)
{
- panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
+ panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLSmoothInterpolation::getInterpolant(mCloseTimeConstant));
if (panelp->mVisibleAmt < 0.001f)
{
panelp->mVisibleAmt = 0.f;
@@ -642,7 +636,7 @@ bool LLLayoutStack::animatePanels()
{
if (!mAnimatedThisFrame)
{
- panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
+ panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLSmoothInterpolation::getInterpolant(mCloseTimeConstant));
}
if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f)
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 02c664f1a0..5930741d5c 100755
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -38,24 +38,13 @@ class LLLayoutPanel;
class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
{
public:
- typedef enum e_layout_orientation
- {
- HORIZONTAL,
- VERTICAL
- } ELayoutOrientation;
-
- struct OrientationNames
- : public LLInitParam::TypeValuesHelper<ELayoutOrientation, OrientationNames>
- {
- static void declareValues();
- };
struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>
{};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- Mandatory<ELayoutOrientation, OrientationNames> orientation;
+ Mandatory<EOrientation> orientation;
Optional<S32> border_size;
Optional<bool> animate,
clip;
@@ -105,7 +94,7 @@ private:
bool animatePanels();
void createResizeBar(LLLayoutPanel* panel);
- const ELayoutOrientation mOrientation;
+ const EOrientation mOrientation;
typedef std::vector<LLLayoutPanel*> e_panel_list_t;
e_panel_list_t mPanels;
@@ -183,7 +172,7 @@ public:
bool isCollapsed() const { return mCollapsed;}
- void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
+ void setOrientation(LLView::EOrientation orientation);
void storeOriginalDim();
void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; }
@@ -202,7 +191,7 @@ protected:
F32 mFractionalSize;
S32 mTargetDim;
bool mIgnoreReshape;
- LLLayoutStack::ELayoutOrientation mOrientation;
+ LLView::EOrientation mOrientation;
class LLResizeBar* mResizeBar;
};
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index f7bf39c897..385dbc6e19 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -549,13 +549,13 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit&
return TRUE;
}
-void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility)
+void LLMenuItemGL::onVisibilityChange(BOOL new_visibility)
{
if (getMenu())
{
getMenu()->needsArrange();
}
- LLView::handleVisibilityChange(new_visibility);
+ LLView::onVisibilityChange(new_visibility);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1146,13 +1146,13 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)
}
}
-void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility )
+void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )
{
if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff())
{
getBranch()->setVisible(FALSE);
}
- LLMenuItemGL::handleVisibilityChange(new_visibility);
+ LLMenuItemGL::onVisibilityChange(new_visibility);
}
BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
@@ -1794,7 +1794,7 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
{
return appendMenu(menup);
}
-
+
return false;
}
@@ -3749,7 +3749,7 @@ void LLTearOffMenu::draw()
if (getRect().getHeight() != mTargetHeight)
{
// animate towards target height
- reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f))));
+ reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
}
LLFloater::draw();
}
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 51df5df1f8..feafaab199 100755
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -82,7 +82,7 @@ protected:
friend class LLUICtrlFactory;
public:
// LLView overrides
- /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
@@ -637,7 +637,7 @@ public:
virtual void updateBranchParent( LLView* parentp );
// LLView Functionality
- virtual void handleVisibilityChange( BOOL curVisibilityIn );
+ virtual void onVisibilityChange( BOOL curVisibilityIn );
virtual void draw();
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index d992212650..c1b1a357ed 100755
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -100,6 +100,3 @@ private:
};
#endif // LL_MULTI_FLOATER_H
-
-
-
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 1789f003b9..37b0a52036 100755
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -516,7 +516,7 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
LLSD LLNotification::asLLSD(bool excludeTemplateElements)
-{
+{
LLParamSDParser parser;
Params p;
@@ -544,12 +544,12 @@ LLSD LLNotification::asLLSD(bool excludeTemplateElements)
mForm->getElements(dynamicElements, templateForm->getNumElements());
p.form_elements = dynamicElements;
}
-
+
if(mResponder)
{
p.functor.responder_sd = mResponder->asLLSD();
}
-
+
if(!mResponseFunctorName.empty())
{
p.functor.name = mResponseFunctorName;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 87573c2a56..2948f88755 100755
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -92,6 +92,7 @@
#include "llevents.h"
#include "llfunctorregistry.h"
#include "llinitparam.h"
+#include "llinstancetracker.h"
#include "llmortician.h"
#include "llnotificationptr.h"
#include "llpointer.h"
@@ -845,7 +846,7 @@ public:
Iterator begin();
Iterator end();
size_t size();
-
+
std::string summarize();
private:
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 18a82190b5..0315ddbea8 100755
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -28,32 +28,9 @@
#ifndef LL_LLNOTIFICATION_TEMPLATE_H
#define LL_LLNOTIFICATION_TEMPLATE_H
-//#include <string>
-//#include <list>
-//#include <vector>
-//#include <map>
-//#include <set>
-//#include <iomanip>
-//#include <sstream>
-//
-//#include <boost/utility.hpp>
-//#include <boost/shared_ptr.hpp>
-//#include <boost/enable_shared_from_this.hpp>
-//#include <boost/type_traits.hpp>
-//
-//// we want to minimize external dependencies, but this one is important
-//#include "llsd.h"
-//
-//// and we need this to manage the notification callbacks
-//#include "llevents.h"
-//#include "llfunctorregistry.h"
-//#include "llpointer.h"
#include "llinitparam.h"
-//#include "llnotificationptr.h"
-//#include "llcachename.h"
#include "llnotifications.h"
-
typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
// This is the class of object read from the XML file (notifications.xml,
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 67472ad166..f157d6a923 100755
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -342,9 +342,9 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
return handled;
}
-void LLPanel::handleVisibilityChange ( BOOL new_visibility )
+void LLPanel::onVisibilityChange ( BOOL new_visibility )
{
- LLUICtrl::handleVisibilityChange ( new_visibility );
+ LLUICtrl::onVisibilityChange ( new_visibility );
if (mVisibleSignal)
(*mVisibleSignal)(this, LLSD(new_visibility) ); // Pass BOOL as LLSD
}
@@ -520,7 +520,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
Params output_params(params);
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
- parser.writeXUI(output_node, output_params, &default_params);
+ parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);
return TRUE;
}
@@ -551,7 +551,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
Params output_params(params);
setupParamsForExport(output_params, parent);
output_node->setName(node->getName()->mString);
- parser.writeXUI(output_node, output_params, &default_params);
+ parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);
}
params.from_xui = true;
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index e63b41f97c..ac8583ece9 100755
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -115,7 +115,7 @@ public:
/*virtual*/ BOOL isPanel() const;
/*virtual*/ void draw();
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
// From LLFocusableElement
/*virtual*/ void setFocus( BOOL b );
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 13887cbe73..bef1854748 100755
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -493,11 +493,11 @@ void LLScrollbar::draw()
BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
if (hovered)
{
- mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f));
+ mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLSmoothInterpolation::getInterpolant(0.05f));
}
else
{
- mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f));
+ mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));
}
// Draw background and thumb.
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 21fd2d631e..e2bf52c14b 100755
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -40,13 +40,11 @@ class LLScrollbar
{
public:
- enum ORIENTATION { HORIZONTAL, VERTICAL };
-
typedef boost::function<void (S32, LLScrollbar*)> callback_t;
struct Params
: public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Mandatory<ORIENTATION> orientation;
+ Mandatory<EOrientation> orientation;
Mandatory<S32> doc_size;
Mandatory<S32> doc_pos;
Mandatory<S32> page_size;
@@ -124,7 +122,7 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
-
+
S32 getThickness() const { return mThickness; }
void setThickness(S32 thickness);
@@ -134,7 +132,7 @@ private:
callback_t mChangeCallback;
- const ORIENTATION mOrientation;
+ const EOrientation mOrientation;
S32 mDocSize; // Size of the document that the scrollbar is modeling. Units depend on the user. 0 <= mDocSize.
S32 mDocPos; // Position within the doc that the scrollbar is modeling, in "lines" (user size)
S32 mPageSize; // Maximum number of lines that can be seen at one time.
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index cbcce0ece5..3b5fb2adfb 100755
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -144,7 +144,7 @@ LLScrollContainer::~LLScrollContainer( void )
{
// mScrolledView and mScrollbar are child views, so the LLView
// destructor takes care of memory deallocation.
- for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
+ for( S32 i = 0; i < ORIENTATION_COUNT; i++ )
{
mScrollbar[i] = NULL;
}
@@ -215,7 +215,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
{
return TRUE;
}
- for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
+ for( S32 i = 0; i < ORIENTATION_COUNT; i++ )
{
if( mScrollbar[i]->handleKeyHere(key, mask) )
{
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index 4eb43539b8..b67236c939 100755
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -56,7 +56,6 @@ class LLScrollContainer : public LLUICtrl
public:
// Note: vertical comes before horizontal because vertical
// scrollbars have priority for mouse and keyboard events.
- enum SCROLL_ORIENTATION { VERTICAL, HORIZONTAL, SCROLLBAR_COUNT };
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
@@ -130,7 +129,7 @@ private:
void updateScroll();
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
- LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
+ LLScrollbar* mScrollbar[ORIENTATION_COUNT];
S32 mSize;
BOOL mIsOpaque;
LLUIColor mBackgroundColor;
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index 700c17ea3e..3b492d8182 100755
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
@@ -34,8 +34,6 @@
class LLSlider : public LLF32UICtrl
{
public:
- enum ORIENTATION { HORIZONTAL, VERTICAL };
-
struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>
{
Optional<std::string> orientation;
@@ -98,7 +96,7 @@ private:
LLPointer<LLUIImage> mTrackHighlightHorizontalImage;
LLPointer<LLUIImage> mTrackHighlightVerticalImage;
- const ORIENTATION mOrientation;
+ const EOrientation mOrientation;
LLRect mThumbRect;
LLUIColor mTrackColor;
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 04cce7878e..d3cc2733e6 100755
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -34,8 +34,9 @@
#include "llgl.h"
#include "llfontgl.h"
-#include "llstat.h"
#include "lluictrlfactory.h"
+#include "lltracerecording.h"
+#include "llcriticaldamp.h"
///////////////////////////////////////////////////////////////////////////////////
@@ -45,68 +46,105 @@ LLStatBar::LLStatBar(const Params& p)
mUnitLabel(p.unit_label),
mMinBar(p.bar_min),
mMaxBar(p.bar_max),
- mStatp(LLStat::getStat(p.stat)),
+ mCurMaxBar(p.bar_max),
mTickSpacing(p.tick_spacing),
- mLabelSpacing(p.label_spacing),
mPrecision(p.precision),
mUpdatesPerSec(p.update_rate),
+ mUnitScale(p.unit_scale),
+ mNumFrames(p.num_frames),
+ mMaxHeight(p.max_height),
mPerSec(p.show_per_sec),
mDisplayBar(p.show_bar),
mDisplayHistory(p.show_history),
- mDisplayMean(p.show_mean)
+ mDisplayMean(p.show_mean),
+ mOrientation(p.orientation),
+ mScaleRange(p.scale_range)
{
+ setStat(p.stat);
}
BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (mDisplayBar)
+ BOOL handled = LLView::handleMouseDown(x, y, mask);
+ if (!handled)
{
- if (mDisplayHistory)
+ if (mDisplayBar)
{
- mDisplayBar = FALSE;
- mDisplayHistory = FALSE;
+ if (mDisplayHistory || mOrientation == HORIZONTAL)
+ {
+ mDisplayBar = FALSE;
+ mDisplayHistory = FALSE;
+ }
+ else
+ {
+ mDisplayHistory = TRUE;
+ }
}
else
{
- mDisplayHistory = TRUE;
+ mDisplayBar = TRUE;
+ if (mOrientation == HORIZONTAL)
+ {
+ mDisplayHistory = TRUE;
+ }
}
+ LLView* parent = getParent();
+ parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE);
}
- else
- {
- mDisplayBar = TRUE;
- }
-
- LLView* parent = getParent();
- parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE);
-
- return FALSE;
+ return TRUE;
}
void LLStatBar::draw()
{
- if (!mStatp)
+ F32 current = 0.f,
+ min = 0.f,
+ max = 0.f,
+ mean = 0.f;
+
+ LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording();
+
+ if (mCountFloatp)
{
-// llinfos << "No stats for statistics bar!" << llendl;
- return;
- }
+ LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();
- // Get the values.
- F32 current, min, max, mean;
- if (mPerSec)
+ if (mPerSec)
+ {
+ current = last_frame_recording.getPerSec(*mCountFloatp);
+ min = frame_recording.getPeriodMinPerSec(*mCountFloatp, mNumFrames);
+ max = frame_recording.getPeriodMaxPerSec(*mCountFloatp, mNumFrames);
+ mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp, mNumFrames);
+ }
+ else
+ {
+ current = last_frame_recording.getSum(*mCountFloatp);
+ min = frame_recording.getPeriodMin(*mCountFloatp, mNumFrames);
+ max = frame_recording.getPeriodMax(*mCountFloatp, mNumFrames);
+ mean = frame_recording.getPeriodMean(*mCountFloatp, mNumFrames);
+ }
+ }
+ else if (mEventFloatp)
{
- current = mStatp->getCurrentPerSec();
- min = mStatp->getMinPerSec();
- max = mStatp->getMaxPerSec();
- mean = mStatp->getMeanPerSec();
+ LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();
+
+ current = last_frame_recording.getMean(*mEventFloatp);
+ min = frame_recording.getPeriodMin(*mEventFloatp, mNumFrames);
+ max = frame_recording.getPeriodMax(*mEventFloatp, mNumFrames);
+ mean = frame_recording.getPeriodMean(*mEventFloatp, mNumFrames);
}
- else
+ else if (mSampleFloatp)
{
- current = mStatp->getCurrent();
- min = mStatp->getMin();
- max = mStatp->getMax();
- mean = mStatp->getMean();
+ LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();
+
+ current = last_frame_recording.getLastValue(*mSampleFloatp);
+ min = frame_recording.getPeriodMin(*mSampleFloatp, mNumFrames);
+ max = frame_recording.getPeriodMax(*mSampleFloatp, mNumFrames);
+ mean = frame_recording.getPeriodMean(*mSampleFloatp, mNumFrames);
}
+ current *= mUnitScale;
+ min *= mUnitScale;
+ max *= mUnitScale;
+ mean *= mUnitScale;
if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f))
{
@@ -121,15 +159,41 @@ void LLStatBar::draw()
mUpdateTimer.reset();
}
- S32 width = getRect().getWidth() - 40;
- S32 max_width = width;
- S32 bar_top = getRect().getHeight() - 15; // 16 pixels from top.
- S32 bar_height = bar_top - 20;
- S32 tick_height = 4;
- S32 tick_width = 1;
- S32 left, top, right, bottom;
+ S32 bar_top, bar_left, bar_right, bar_bottom;
+ if (mOrientation == HORIZONTAL)
+ {
+ bar_top = llmax(5, getRect().getHeight() - 15);
+ bar_left = 0;
+ bar_right = getRect().getWidth() - 40;
+ bar_bottom = llmin(bar_top - 5, 0);
+ }
+ else // VERTICAL
+ {
+ bar_top = llmax(5, getRect().getHeight() - 15);
+ bar_left = 0;
+ bar_right = getRect().getWidth();
+ bar_bottom = llmin(bar_top - 5, 20);
+ }
+ const S32 tick_length = 4;
+ const S32 tick_width = 1;
- F32 value_scale = max_width/(mMaxBar - mMinBar);
+ if (mScaleRange && min < max)
+ {
+ F32 cur_max = mTickSpacing;
+ while(max > cur_max && mMaxBar > cur_max)
+ {
+ cur_max += mTickSpacing;
+ }
+ mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, cur_max, 0.05f);
+ }
+ else
+ {
+ mCurMaxBar = mMaxBar;
+ }
+
+ F32 value_scale = (mOrientation == HORIZONTAL)
+ ? (bar_top - bar_bottom)/(mCurMaxBar - mMinBar)
+ : (bar_right - bar_left)/(mCurMaxBar - mMinBar);
LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f),
LLFontGL::LEFT, LLFontGL::TOP);
@@ -148,120 +212,231 @@ void LLStatBar::draw()
}
// Draw the value.
- LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, width, getRect().getHeight(),
- LLColor4(1.f, 1.f, 1.f, 0.5f),
- LLFontGL::RIGHT, LLFontGL::TOP);
+ if (mOrientation == HORIZONTAL)
+ {
+ LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(),
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::RIGHT, LLFontGL::TOP);
+ }
+ else
+ {
+ LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(),
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::RIGHT, LLFontGL::TOP);
+ }
value_format = llformat( "%%.%df", mPrecision);
- if (mDisplayBar)
+ if (mDisplayBar && (mCountFloatp || mEventFloatp || mSampleFloatp))
{
std::string tick_label;
// Draw the tick marks.
- F32 tick_value;
- top = bar_top;
- bottom = bar_top - bar_height - tick_height/2;
-
LLGLSUIDefault gls_ui;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mTickSpacing)
- {
- left = llfloor((tick_value - mMinBar)*value_scale);
- right = left + tick_width;
- gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
- }
-
- // Draw the tick labels (and big ticks).
- bottom = bar_top - bar_height - tick_height;
- for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mLabelSpacing)
+ S32 last_tick = 0;
+ S32 last_label = 0;
+ const S32 MIN_TICK_SPACING = mOrientation == HORIZONTAL ? 20 : 30;
+ const S32 MIN_LABEL_SPACING = mOrientation == HORIZONTAL ? 40 : 60;
+ for (F32 tick_value = mMinBar + mTickSpacing; tick_value <= mCurMaxBar; tick_value += mTickSpacing)
{
- left = llfloor((tick_value - mMinBar)*value_scale);
- right = left + tick_width;
- gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
+ const S32 begin = llfloor((tick_value - mMinBar)*value_scale);
+ const S32 end = begin + tick_width;
+ if (begin - last_tick < MIN_TICK_SPACING)
+ {
+ continue;
+ }
+ last_tick = begin;
tick_label = llformat( value_format.c_str(), tick_value);
- // draw labels for the tick marks
- LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left - 1, bar_top - bar_height - tick_height,
- LLColor4(1.f, 1.f, 1.f, 0.5f),
- LLFontGL::LEFT, LLFontGL::TOP);
- }
- // Now, draw the bars
- top = bar_top;
- bottom = bar_top - bar_height;
+ if (mOrientation == HORIZONTAL)
+ {
+ if (begin - last_label > MIN_LABEL_SPACING)
+ {
+ gl_rect_2d(bar_left, end, bar_right - tick_length, begin, LLColor4(1.f, 1.f, 1.f, 0.25f));
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, bar_right, begin,
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::LEFT, LLFontGL::VCENTER);
+ last_label = begin;
+ }
+ else
+ {
+ gl_rect_2d(bar_left, end, bar_right - tick_length/2, begin, LLColor4(1.f, 1.f, 1.f, 0.1f));
+ }
+ }
+ else
+ {
+ if (begin - last_label > MIN_LABEL_SPACING)
+ {
+ gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length, LLColor4(1.f, 1.f, 1.f, 0.25f));
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, begin - 1, bar_bottom - tick_length,
+ LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLFontGL::RIGHT, LLFontGL::TOP);
+ last_label = begin;
+ }
+ else
+ {
+ gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length/2, LLColor4(1.f, 1.f, 1.f, 0.1f));
+ }
+ }
+ }
// draw background bar.
- left = 0;
- right = width;
- gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 0.f, 0.f, 0.25f));
+ gl_rect_2d(bar_left, bar_top, bar_right, bar_bottom, LLColor4(0.f, 0.f, 0.f, 0.25f));
- if (mStatp->getNumValues() == 0)
+ if (frame_recording.getNumRecordedPeriods() == 0)
{
// No data, don't draw anything...
return;
}
+
// draw min and max
- left = (S32) ((min - mMinBar) * value_scale);
+ S32 begin = (S32) ((min - mMinBar) * value_scale);
- if (left < 0)
+ if (begin < 0)
{
- left = 0;
+ begin = 0;
llwarns << "Min:" << min << llendl;
}
- right = (S32) ((max - mMinBar) * value_scale);
- gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
+ S32 end = (S32) ((max - mMinBar) * value_scale);
+ if (mOrientation == HORIZONTAL)
+ {
+ gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 0.25f));
+ }
+ else // VERTICAL
+ {
+ gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
+ }
+
+ F32 span = (mOrientation == HORIZONTAL)
+ ? (bar_right - bar_left)
+ : (bar_top - bar_bottom);
- S32 num_values = mStatp->getNumValues() - 1;
- if (mDisplayHistory)
+ if (mDisplayHistory && (mCountFloatp || mEventFloatp || mSampleFloatp))
{
+ const S32 num_values = frame_recording.getNumRecordedPeriods() - 1;
+ F32 begin = 0;
+ F32 end = 0;
S32 i;
- for (i = 0; i < num_values; i++)
+ gGL.color4f( 1.f, 0.f, 0.f, 1.f );
+ gGL.begin( LLRender::QUADS );
+ const S32 max_frame = llmin(mNumFrames, num_values);
+ U32 num_samples = 0;
+ for (i = 1; i <= max_frame; i++)
{
- if (i == mStatp->getNextBin())
+ F32 offset = ((F32)i / (F32)mNumFrames) * span;
+ LLTrace::Recording& recording = frame_recording.getPrevRecording(i);
+ if (mPerSec)
{
- continue;
+ if (mCountFloatp)
+ {
+ begin = ((recording.getPerSec(*mCountFloatp) - mMinBar) * value_scale);
+ end = ((recording.getPerSec(*mCountFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mCountFloatp);
+ }
+ else if (mEventFloatp)
+ {
+ //rate isn't defined for measurement stats, so use mean
+ begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale);
+ end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mEventFloatp);
+ }
+ else if (mSampleFloatp)
+ {
+ //rate isn't defined for sample stats, so use mean
+ begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale);
+ end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mEventFloatp);
+ }
}
- if (mPerSec)
+ else
+ {
+ if (mCountFloatp)
+ {
+ begin = ((recording.getSum(*mCountFloatp) - mMinBar) * value_scale);
+ end = ((recording.getSum(*mCountFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mCountFloatp);
+ }
+ else if (mEventFloatp)
+ {
+ begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale);
+ end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mEventFloatp);
+ }
+ else if (mSampleFloatp)
+ {
+ begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale);
+ end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1;
+ num_samples = recording.getSampleCount(*mEventFloatp);
+ }
+ }
+
+ if (!num_samples) continue;
+
+ if (mOrientation == HORIZONTAL)
{
- left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale);
- right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1;
- gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ gGL.vertex2f((F32)bar_right - offset, end);
+ gGL.vertex2f((F32)bar_right - offset, begin);
+ gGL.vertex2f((F32)bar_right - offset - 1.f, begin);
+ gGL.vertex2f((F32)bar_right - offset - 1.f, end);
}
else
{
- left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale);
- right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1;
- gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ gGL.vertex2f(begin, (F32)bar_bottom+offset+1.f);
+ gGL.vertex2f(begin, (F32)bar_bottom+offset);
+ gGL.vertex2f(end, (F32)bar_bottom+offset);
+ gGL.vertex2f(end, (F32)bar_bottom+offset+1.f);
}
}
+ gGL.end();
}
else
{
+ S32 begin = (S32) ((current - mMinBar) * value_scale) - 1;
+ S32 end = (S32) ((current - mMinBar) * value_scale) + 1;
// draw current
- left = (S32) ((current - mMinBar) * value_scale) - 1;
- right = (S32) ((current - mMinBar) * value_scale) + 1;
- gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
+ if (mOrientation == HORIZONTAL)
+ {
+ gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 1.f));
+ }
+ else
+ {
+ gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
+ }
}
// draw mean bar
- top = bar_top + 2;
- bottom = bar_top - bar_height - 2;
- left = (S32) ((mean - mMinBar) * value_scale) - 1;
- right = (S32) ((mean - mMinBar) * value_scale) + 1;
- gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 1.f, 0.f, 1.f));
+ {
+ const S32 begin = (S32) ((mean - mMinBar) * value_scale) - 1;
+ const S32 end = (S32) ((mean - mMinBar) * value_scale) + 1;
+ if (mOrientation == HORIZONTAL)
+ {
+ gl_rect_2d(bar_left - 2, begin, bar_right + 2, end, LLColor4(0.f, 1.f, 0.f, 1.f));
+ }
+ else
+ {
+ gl_rect_2d(begin, bar_top + 2, end, bar_bottom - 2, LLColor4(0.f, 1.f, 0.f, 1.f));
+ }
+ }
}
LLView::draw();
}
-void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing)
+void LLStatBar::setStat(const std::string& stat_name)
{
- mMinBar = bar_min;
- mMaxBar = bar_max;
- mTickSpacing = tick_spacing;
- mLabelSpacing = label_spacing;
+ mCountFloatp = LLTrace::TraceType<LLTrace::CountAccumulator>::getInstance(stat_name);
+ mEventFloatp = LLTrace::TraceType<LLTrace::EventAccumulator>::getInstance(stat_name);
+ mSampleFloatp = LLTrace::TraceType<LLTrace::SampleAccumulator>::getInstance(stat_name);
+}
+
+
+void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing)
+{
+ mMinBar = bar_min;
+ mMaxBar = bar_max;
+ mTickSpacing = tick_spacing;
}
LLRect LLStatBar::getRequiredRect()
@@ -272,7 +447,7 @@ LLRect LLStatBar::getRequiredRect()
{
if (mDisplayHistory)
{
- rect.mTop = 35 + mStatp->getNumBins();
+ rect.mTop = mMaxHeight;
}
else
{
@@ -285,3 +460,4 @@ LLRect LLStatBar::getRequiredRect()
}
return rect;
}
+
diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h
index 513fff3234..3daec297bb 100755
--- a/indra/llui/llstatbar.h
+++ b/indra/llui/llstatbar.h
@@ -29,41 +29,54 @@
#include "llview.h"
#include "llframetimer.h"
-
-class LLStat;
+#include "lltracerecording.h"
class LLStatBar : public LLView
{
public:
+
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
- Optional<std::string> label;
- Optional<std::string> unit_label;
- Optional<F32> bar_min;
- Optional<F32> bar_max;
- Optional<F32> tick_spacing;
- Optional<F32> label_spacing;
- Optional<U32> precision;
- Optional<F32> update_rate;
- Optional<bool> show_per_sec;
- Optional<bool> show_bar;
- Optional<bool> show_history;
- Optional<bool> show_mean;
- Optional<std::string> stat;
+ Optional<std::string> label,
+ unit_label;
+
+ Optional<F32> bar_min,
+ bar_max,
+ tick_spacing,
+ update_rate,
+ unit_scale;
+
+ Optional<U32> precision;
+
+ Optional<bool> show_per_sec,
+ show_bar,
+ show_history,
+ show_mean,
+ scale_range;
+
+ Optional<S32> num_frames,
+ max_height;
+ Optional<std::string> stat;
+ Optional<EOrientation> orientation;
+
Params()
: label("label"),
unit_label("unit_label"),
bar_min("bar_min", 0.0f),
bar_max("bar_max", 50.0f),
tick_spacing("tick_spacing", 10.0f),
- label_spacing("label_spacing", 10.0f),
precision("precision", 0),
update_rate("update_rate", 5.0f),
- show_per_sec("show_per_sec", TRUE),
- show_bar("show_bar", TRUE),
- show_history("show_history", FALSE),
- show_mean("show_mean", TRUE),
- stat("stat")
+ unit_scale("unit_scale", 1.f),
+ show_per_sec("show_per_sec", true),
+ show_bar("show_bar", true),
+ show_history("show_history", false),
+ show_mean("show_mean", true),
+ scale_range("scale_range", true),
+ num_frames("num_frames", 300),
+ max_height("max_height", 200),
+ stat("stat"),
+ orientation("orientation", VERTICAL)
{
changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);
}
@@ -73,30 +86,39 @@ public:
virtual void draw();
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- void setStat(LLStat* stat) { mStatp = stat; }
- void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing);
+ void setStat(const std::string& stat_name);
+
+ void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing);
void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; }
/*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options.
private:
- F32 mMinBar;
- F32 mMaxBar;
- F32 mTickSpacing;
- F32 mLabelSpacing;
- U32 mPrecision;
- F32 mUpdatesPerSec;
- BOOL mPerSec; // Use the per sec stats.
- BOOL mDisplayBar; // Display the bar graph.
- BOOL mDisplayHistory;
- BOOL mDisplayMean; // If true, display mean, if false, display current value
-
- LLStat* mStatp;
+ F32 mMinBar;
+ F32 mMaxBar;
+ F32 mCurMaxBar;
+ F32 mTickSpacing;
+ F32 mLabelSpacing;
+ U32 mPrecision;
+ F32 mUpdatesPerSec;
+ F32 mUnitScale;
+ S32 mNumFrames;
+ S32 mMaxHeight;
+ bool mPerSec; // Use the per sec stats.
+ bool mDisplayBar; // Display the bar graph.
+ bool mDisplayHistory;
+ bool mDisplayMean; // If true, display mean, if false, display current value
+ bool mScaleRange;
+ EOrientation mOrientation;
+
+ LLTrace::TraceType<LLTrace::CountAccumulator>* mCountFloatp;
+ LLTrace::TraceType<LLTrace::EventAccumulator>* mEventFloatp;
+ LLTrace::TraceType<LLTrace::SampleAccumulator>* mSampleFloatp;
LLFrameTimer mUpdateTimer;
- LLUIString mLabel;
- std::string mUnitLabel;
- F32 mValue;
+ LLUIString mLabel;
+ std::string mUnitLabel;
+ F32 mValue;
};
#endif
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index e44887ebf0..a44bc18733 100755
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
@@ -32,48 +32,51 @@
#include "llmath.h"
#include "llui.h"
-#include "llstat.h"
#include "llgl.h"
#include "llglheaders.h"
+#include "lltracerecording.h"
+#include "lltracethreadrecorder.h"
//#include "llviewercontrol.h"
///////////////////////////////////////////////////////////////////////////////////
-LLStatGraph::LLStatGraph(const LLView::Params& p)
-: LLView(p)
+LLStatGraph::LLStatGraph(const Params& p)
+: LLView(p),
+ mMin(p.min),
+ mMax(p.max),
+ mPerSec(true),
+ mPrecision(p.precision),
+ mValue(p.value),
+ mNewStatFloatp(p.stat.count_stat_float)
{
- mStatp = NULL;
setToolTip(p.name());
- mNumThresholds = 3;
- mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f);
- mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f);
- mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f);
- mThresholdColors[3] = LLColor4(1.f, 0.f, 0.f, 1.f);
- mThresholds[0] = 50.f;
- mThresholds[1] = 75.f;
- mThresholds[2] = 100.f;
- mMin = 0.f;
- mMax = 125.f;
- mPerSec = TRUE;
- mValue = 0.f;
- mPrecision = 0;
+
+ for(LLInitParam::ParamIterator<ThresholdParams>::const_iterator it = p.thresholds.threshold.begin(), end_it = p.thresholds.threshold.end();
+ it != end_it;
+ ++it)
+ {
+ mThresholds.push_back(Threshold(it->value(), it->color));
+ }
}
void LLStatGraph::draw()
{
F32 range, frac;
range = mMax - mMin;
- if (mStatp)
+ if (mNewStatFloatp)
{
+ LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording();
+
if (mPerSec)
{
- mValue = mStatp->getMeanPerSec();
+ mValue = recording.getPerSec(*mNewStatFloatp);
}
else
{
- mValue = mStatp->getMean();
+ mValue = recording.getSum(*mNewStatFloatp);
}
}
+
frac = (mValue - mMin) / range;
frac = llmax(0.f, frac);
frac = llmin(1.f, frac);
@@ -91,19 +94,13 @@ void LLStatGraph::draw()
LLColor4 color;
- S32 i;
- for (i = 0; i < mNumThresholds - 1; i++)
+ threshold_vec_t::iterator it = std::lower_bound(mThresholds.begin(), mThresholds.end(), Threshold(mValue / mMax, LLUIColor()));
+
+ if (it != mThresholds.begin())
{
- if (mThresholds[i] > mValue)
- {
- break;
- }
+ it--;
}
- //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- // LLUIColorTable::instance().getColor("ColorDropShadow"),
- // (S32) gSavedSettings.getF32("DropShadowFloater") );
-
color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
gGL.color4fv(color.mV);
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE);
@@ -111,16 +108,11 @@ void LLStatGraph::draw()
gGL.color4fv(LLColor4::black.mV);
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, FALSE);
- color = mThresholdColors[i];
+ color = it->mColor;
gGL.color4fv(color.mV);
gl_rect_2d(1, llround(frac*getRect().getHeight()), getRect().getWidth() - 1, 0, TRUE);
}
-void LLStatGraph::setValue(const LLSD& value)
-{
- mValue = (F32)value.asReal();
-}
-
void LLStatGraph::setMin(const F32 min)
{
mMin = min;
@@ -131,27 +123,3 @@ void LLStatGraph::setMax(const F32 max)
mMax = max;
}
-void LLStatGraph::setStat(LLStat *statp)
-{
- mStatp = statp;
-}
-
-void LLStatGraph::setLabel(const std::string& label)
-{
- mLabel = label;
-}
-
-void LLStatGraph::setUnits(const std::string& units)
-{
- mUnits = units;
-}
-
-void LLStatGraph::setPrecision(const S32 precision)
-{
- mPrecision = precision;
-}
-
-void LLStatGraph::setThreshold(const S32 i, F32 value)
-{
- mThresholds[i] = value;
-}
diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h
index 757525e232..38fe12d18b 100755
--- a/indra/llui/llstatgraph.h
+++ b/indra/llui/llstatgraph.h
@@ -30,29 +30,84 @@
#include "llview.h"
#include "llframetimer.h"
#include "v4color.h"
-
-class LLStat;
+#include "lltrace.h"
class LLStatGraph : public LLView
{
public:
- LLStatGraph(const LLView::Params&);
+ struct ThresholdParams : public LLInitParam::Block<ThresholdParams>
+ {
+ Mandatory<F32> value;
+ Optional<LLUIColor> color;
- virtual void draw();
+ ThresholdParams()
+ : value("value"),
+ color("color", LLColor4::white)
+ {}
+ };
+
+ struct Thresholds : public LLInitParam::Block<Thresholds>
+ {
+ Multiple<ThresholdParams> threshold;
+
+ Thresholds()
+ : threshold("threshold")
+ {}
+ };
+
+ struct StatParams : public LLInitParam::ChoiceBlock<StatParams>
+ {
+ Alternative<LLTrace::TraceType<LLTrace::CountAccumulator>* > count_stat_float;
+ Alternative<LLTrace::TraceType<LLTrace::EventAccumulator>* > event_stat_float;
+ Alternative<LLTrace::TraceType<LLTrace::SampleAccumulator>* > sample_stat_float;
+ };
+
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Mandatory<StatParams> stat;
+ Optional<std::string> label,
+ units;
+ Optional<S32> precision;
+ Optional<F32> min,
+ max;
+ Optional<bool> per_sec;
+ Optional<F32> value;
+
+ Optional<Thresholds> thresholds;
+
+ Params()
+ : stat("stat"),
+ label("label"),
+ units("units"),
+ precision("precision", 0),
+ min("min", 0.f),
+ max("max", 125.f),
+ per_sec("per_sec", true),
+ value("value", 0.f),
+ thresholds("thresholds")
+ {
+ Thresholds _thresholds;
+ _thresholds.threshold.add(ThresholdParams().value(0.f).color(LLColor4::green))
+ .add(ThresholdParams().value(0.33f).color(LLColor4::yellow))
+ .add(ThresholdParams().value(0.5f).color(LLColor4::red))
+ .add(ThresholdParams().value(0.75f).color(LLColor4::red));
+ thresholds = _thresholds;
+ }
+ };
+ LLStatGraph(const Params&);
- void setLabel(const std::string& label);
- void setUnits(const std::string& units);
- void setPrecision(const S32 precision);
- void setStat(LLStat *statp);
- void setThreshold(const S32 i, F32 value);
void setMin(const F32 min);
void setMax(const F32 max);
+ virtual void draw();
+
/*virtual*/ void setValue(const LLSD& value);
- LLStat *mStatp;
- BOOL mPerSec;
private:
+ LLTrace::TraceType<LLTrace::CountAccumulator>* mNewStatFloatp;
+
+ BOOL mPerSec;
+
F32 mValue;
F32 mMin;
@@ -62,9 +117,25 @@ private:
std::string mUnits;
S32 mPrecision; // Num of digits of precision after dot
- S32 mNumThresholds;
- F32 mThresholds[4];
- LLColor4 mThresholdColors[4];
+ struct Threshold
+ {
+ Threshold(F32 value, const LLUIColor& color)
+ : mValue(value),
+ mColor(color)
+ {}
+
+ F32 mValue;
+ LLUIColor mColor;
+ bool operator <(const Threshold& other)
+ {
+ return mValue < other.mValue;
+ }
+ };
+ typedef std::vector<Threshold> threshold_vec_t;
+ threshold_vec_t mThresholds;
+ //S32 mNumThresholds;
+ //F32 mThresholds[4];
+ //LLColor4 mThresholdColors[4];
};
#endif // LL_LLSTATGRAPH_H
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index fd98155704..415da0b3d6 100755
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -406,7 +406,7 @@ void LLTabContainer::draw()
}
}
- setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f)));
+ setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLSmoothInterpolation::getInterpolant(0.08f)));
BOOL has_scroll_arrows = !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0));
if (!mIsVertical)
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index a45c4ced2e..7243931dbb 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -48,6 +48,8 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
const S32 CURSOR_THICKNESS = 2;
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click.
+LLTrace::MemStatHandle LLTextSegment::sMemStat("LLTextSegment");
+
LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num)
: mDocIndexStart(index_start),
mDocIndexEnd(index_end),
@@ -575,7 +577,7 @@ void LLTextBase::drawText()
if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
{
const LLWString& wstrText = getWText();
- mMisspellRanges.clear();
+ memDisclaim(mMisspellRanges).clear();
segment_set_t::const_iterator seg_it = getSegIterContaining(start);
while (mSegments.end() != seg_it)
@@ -651,6 +653,7 @@ void LLTextBase::drawText()
mSpellCheckStart = start;
mSpellCheckEnd = end;
+ memClaim(mMisspellRanges);
}
}
@@ -916,9 +919,11 @@ void LLTextBase::createDefaultSegment()
if (mSegments.empty())
{
LLStyleConstSP sp(new LLStyle(getStyleParams()));
+ memDisclaim(mSegments);
LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
mSegments.insert(default_segment);
default_segment->linkToDocument(this);
+ memClaim(mSegments);
}
}
@@ -929,6 +934,8 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
return;
}
+ memDisclaim(mSegments);
+
segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());
S32 reflow_start_index = 0;
@@ -1001,6 +1008,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
// layout potentially changed
needsReflow(reflow_start_index);
+ memClaim(mSegments);
}
BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1254,13 +1262,13 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)
}
//virtual
-void LLTextBase::handleVisibilityChange( BOOL new_visibility )
+void LLTextBase::onVisibilityChange( BOOL new_visibility )
{
if(!new_visibility && mPopupMenu)
{
mPopupMenu->hide();
}
- LLUICtrl::handleVisibilityChange(new_visibility);
+ LLUICtrl::onVisibilityChange(new_visibility);
}
//virtual
@@ -1311,8 +1319,11 @@ void LLTextBase::replaceWithSuggestion(U32 index)
removeStringNoUndo(it->first, it->second - it->first);
// Insert the suggestion in its place
+ memDisclaim(mSuggestionList);
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
+ memClaim(mSuggestionList);
+
setCursorPos(it->first + (S32)suggestion.length());
break;
@@ -1374,7 +1385,7 @@ bool LLTextBase::isMisspelledWord(U32 pos) const
void LLTextBase::onSpellCheckSettingsChange()
{
// Recheck the spelling on every change
- mMisspellRanges.clear();
+ memDisclaim(mMisspellRanges).clear();
mSpellCheckStart = mSpellCheckEnd = -1;
}
@@ -1652,7 +1663,7 @@ LLRect LLTextBase::getTextBoundingRect()
void LLTextBase::clearSegments()
{
- mSegments.clear();
+ memDisclaim(mSegments).clear();
createDefaultSegment();
}
@@ -3154,7 +3165,9 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
llwarns << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << llendl;
return;
}
+ memDisclaim(mTooltip);
mTooltip = tooltip;
+ memClaim(mTooltip);
}
bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 20a73387b5..74dc7f9693 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -51,7 +51,10 @@ class LLUrlMatch;
/// includes a start/end offset from the start of the string, a
/// style to render with, an optional tooltip, etc.
///
-class LLTextSegment : public LLRefCount, public LLMouseHandler
+class LLTextSegment
+: public LLRefCount,
+ public LLMouseHandler,
+ public LLTrace::MemTrackable<LLTextSegment>
{
public:
LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
@@ -92,10 +95,12 @@ public:
/*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
/*virtual*/ BOOL hasMouseCapture();
- S32 getStart() const { return mStart; }
- void setStart(S32 start) { mStart = start; }
- S32 getEnd() const { return mEnd; }
- void setEnd( S32 end ) { mEnd = end; }
+ S32 getStart() const { return mStart; }
+ void setStart(S32 start) { mStart = start; }
+ S32 getEnd() const { return mEnd; }
+ void setEnd( S32 end ) { mEnd = end; }
+
+ static LLTrace::MemStatHandle sMemStat;
protected:
S32 mStart;
@@ -325,7 +330,7 @@ public:
/*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; }
/*virtual*/ void setColor( const LLColor4& c );
virtual void setReadOnlyColor(const LLColor4 &c);
- virtual void handleVisibilityChange( BOOL new_visibility );
+ virtual void onVisibilityChange( BOOL new_visibility );
/*virtual*/ void setValue(const LLSD& value );
/*virtual*/ LLTextViewModel* getViewModel() const;
@@ -603,7 +608,7 @@ protected:
S32 mSelectionStart;
S32 mSelectionEnd;
LLTimer mTripleClickTimer;
-
+
BOOL mIsSelecting; // Are we in the middle of a drag-select?
// spell checking
diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp
index 00d52fe10d..ccb92ffbb2 100755
--- a/indra/llui/lltoggleablemenu.cpp
+++ b/indra/llui/lltoggleablemenu.cpp
@@ -52,7 +52,7 @@ boost::signals2::connection LLToggleableMenu::setVisibilityChangeCallback(const
}
// virtual
-void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn)
+void LLToggleableMenu::onVisibilityChange (BOOL curVisibilityIn)
{
S32 x,y;
LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y);
diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index dfe70cbf54..55a6483021 100755
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -45,7 +45,7 @@ public:
boost::signals2::connection setVisibilityChangeCallback( const commit_signal_t::slot_type& cb );
- virtual void handleVisibilityChange (BOOL curVisibilityIn);
+ virtual void onVisibilityChange (BOOL curVisibilityIn);
virtual bool addChild (LLView* view, S32 tab_group = 0);
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 3d9f5cbbc2..f683758962 100755
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -42,9 +42,9 @@
namespace LLToolBarEnums
{
- LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType)
+ LLView::EOrientation getOrientation(SideType sideType)
{
- LLLayoutStack::ELayoutOrientation orientation = LLLayoutStack::HORIZONTAL;
+ LLView::EOrientation orientation = LLLayoutStack::HORIZONTAL;
if ((sideType == SIDE_LEFT) || (sideType == SIDE_RIGHT))
{
@@ -173,7 +173,7 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)
// Initialize the base object
LLUICtrl::initFromParams(p);
- LLLayoutStack::ELayoutOrientation orientation = getOrientation(p.side);
+ LLView::EOrientation orientation = getOrientation(p.side);
LLLayoutStack::Params centering_stack_p;
centering_stack_p.name = "centering_stack";
@@ -525,7 +525,7 @@ int LLToolBar::getRankFromPosition(S32 x, S32 y)
int rank = 0;
// Convert the toolbar coord into button panel coords
- LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
+ LLView::EOrientation orientation = getOrientation(mSideType);
S32 button_panel_x = 0;
S32 button_panel_y = 0;
localPointToOtherView(x, y, &button_panel_x, &button_panel_y, mButtonPanel);
@@ -644,7 +644,7 @@ void LLToolBar::updateLayoutAsNeeded()
{
if (!mNeedsLayout) return;
- LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
+ LLView::EOrientation orientation = getOrientation(mSideType);
// our terminology for orientation-agnostic layout is such that
// length refers to a distance in the direction we stack the buttons
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 31424a36d4..6936cb37f7 100755
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -125,7 +125,7 @@ namespace LLToolBarEnums
SIDE_TOP,
};
- LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType);
+ LLView::EOrientation getOrientation(SideType sideType);
}
// NOTE: This needs to occur before Param block declaration for proper compilation.
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 0a0e0e164e..4ebfd0fd6e 100755
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -29,9 +29,11 @@
#define LL_LLUI_H
#include "llrect.h"
+#include "llcoord.h"
#include "llcontrol.h"
#include "llcoord.h"
-#include "v2math.h"
+#include "llcontrol.h"
+#include "llglslshader.h"
#include "llinitparam.h"
#include "llregistry.h"
#include "llrender2dutils.h"
@@ -40,8 +42,8 @@
#include "lluicolortable.h"
#include "lluiimage.h"
#include <boost/signals2.hpp>
-#include "lllazyvalue.h"
#include "llframetimer.h"
+#include "v2math.h"
#include <limits>
// for initparam specialization
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index b9c843e931..08358484ef 100755
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -118,6 +118,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
mDoubleClickSignal(NULL),
mTransparencyType(TT_DEFAULT)
{
+ memClaim(viewmodel.get());
}
void LLUICtrl::initFromParams(const Params& p)
@@ -940,7 +941,7 @@ 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();
+ if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
return mValidateSignal->connect(boost::bind(cb, _2));
}
@@ -1003,55 +1004,55 @@ 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();
+ if (!mCommitSignal) mCommitSignal = memClaim(new commit_signal_t());
return mCommitSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )
{
- if (!mValidateSignal) mValidateSignal = new enable_signal_t();
+ if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
return mValidateSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )
{
- if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t();
+ if (!mMouseEnterSignal) mMouseEnterSignal = memClaim(new commit_signal_t());
return mMouseEnterSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )
{
- if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t();
+ if (!mMouseLeaveSignal) mMouseLeaveSignal = memClaim(new commit_signal_t());
return mMouseLeaveSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t();
+ if (!mMouseDownSignal) mMouseDownSignal = memClaim(new mouse_signal_t());
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t();
+ if (!mMouseUpSignal) mMouseUpSignal = memClaim(new mouse_signal_t());
return mMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t();
+ if (!mRightMouseDownSignal) mRightMouseDownSignal = memClaim(new mouse_signal_t());
return mRightMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t();
+ if (!mRightMouseUpSignal) mRightMouseUpSignal = memClaim(new mouse_signal_t());
return mRightMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t();
+ if (!mDoubleClickSignal) mDoubleClickSignal = memClaim(new mouse_signal_t());
return mDoubleClickSignal->connect(cb);
}
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 876bb5ef46..f2fe4334ee 100755
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -170,7 +170,7 @@ public:
LLXMLNodePtr root_node;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
- {
+ {
llwarns << "Couldn't parse XUI file: " << instance().getCurFileName() << llendl;
goto fail;
}
@@ -259,10 +259,8 @@ private:
// We always want to output top-left coordinates
typename T::Params output_params(params);
T::setupParamsForExport(output_params, parent);
- // Export only the differences between this any default params
- typename T::Params default_params(getDefaultParams<T>());
copyName(node, output_node);
- parser.writeXUI(output_node, output_params, &default_params);
+ parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &getDefaultParams<T>());
}
// Apply layout transformations, usually munging rect
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index c4e073ccdb..23fc53ea88 100755
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -26,6 +26,8 @@
#include "linden_common.h"
#include "lluistring.h"
+
+#include "llfasttimer.h"
#include "llsd.h"
#include "lltrans.h"
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 3613a40e2c..daeb4d7939 100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -30,7 +30,6 @@
#define LLVIEW_CPP
#include "llview.h"
-#include <cassert>
#include <sstream>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
@@ -70,6 +69,7 @@ LLView* LLView::sPreviewClickedElement = NULL;
BOOL LLView::sDrawPreviewHighlights = FALSE;
S32 LLView::sLastLeftXML = S32_MIN;
S32 LLView::sLastBottomXML = S32_MIN;
+LLTrace::MemStatHandle LLView::sMemStat("LLView");
std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
LLView::DrilldownFunc LLView::sDrilldown =
@@ -85,6 +85,16 @@ template class LLView* LLView::getChild<class LLView>(
static LLDefaultChildRegistry::Register<LLView> r("view");
+namespace LLInitParam
+{
+ void TypeValues<LLView::EOrientation>::declareValues()
+ {
+ declare("horizontal", LLView::HORIZONTAL);
+ declare("vertical", LLView::VERTICAL);
+ }
+}
+
+
LLView::Follows::Follows()
: string(""),
flags("flags", FOLLOWS_LEFT | FOLLOWS_TOP)
@@ -633,21 +643,21 @@ void LLView::setVisible(BOOL visible)
{
// tell all children of this view that the visibility may have changed
dirtyRect();
- handleVisibilityChange( visible );
+ onVisibilityChange( visible );
}
updateBoundingRect();
}
}
// virtual
-void LLView::handleVisibilityChange ( BOOL new_visibility )
+void LLView::onVisibilityChange ( BOOL new_visibility )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
// only views that are themselves visible will have their overall visibility affected by their ancestors
if (viewp->getVisible())
{
- viewp->handleVisibilityChange ( new_visibility );
+ viewp->onVisibilityChange ( new_visibility );
}
}
}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 15b85a6418..0568fa889a 100755
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -100,9 +100,13 @@ 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 LLHandleProvider<LLView>, // passes out weak references to self
+ public LLTrace::MemTrackable<LLView> // track memory usage
{
public:
+
+ enum EOrientation { HORIZONTAL, VERTICAL, ORIENTATION_COUNT };
+
struct Follows : public LLInitParam::ChoiceBlock<Follows>
{
Alternative<std::string> string;
@@ -303,7 +307,7 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
- virtual void handleVisibilityChange ( BOOL new_visibility );
+ virtual void onVisibilityChange ( BOOL new_visibility );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
void popVisible() { setVisible(mLastVisible); }
@@ -671,7 +675,18 @@ public:
static S32 sLastLeftXML;
static S32 sLastBottomXML;
static BOOL sForceReshape;
+ static LLTrace::MemStatHandle sMemStat;
+};
+
+namespace LLInitParam
+{
+template<>
+struct TypeValues<LLView::EOrientation> : public LLInitParam::TypeValuesHelper<LLView::EOrientation>
+{
+ static void declareValues();
};
+}
+
class LLCompareByTabOrder
{
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index a9f8acc440..901260bec8 100755
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -35,6 +35,8 @@
// external library headers
// other Linden headers
+LLTrace::MemStatHandle LLViewModel::sMemStat("LLViewModel");
+
///
LLViewModel::LLViewModel()
: mDirty(false)
@@ -80,7 +82,10 @@ LLTextViewModel::LLTextViewModel(const LLSD& value)
void LLTextViewModel::setValue(const LLSD& value)
{
LLViewModel::setValue(value);
+ memDisclaim(mDisplay);
mDisplay = utf8str_to_wstring(value.asString());
+ memClaim(mDisplay);
+
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
@@ -91,7 +96,9 @@ 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.
+ memDisclaim(mDisplay);
mDisplay = value;
+ memClaim(mDisplay);
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
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index ef2e314799..2c016d2560 100755
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -39,6 +39,7 @@
#include "llrefcount.h"
#include "stdenums.h"
#include "llstring.h"
+#include "lltrace.h"
#include <string>
class LLScrollListItem;
@@ -60,7 +61,9 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr;
* LLViewModel data. This way, the LLViewModel is quietly deleted when the
* last referencing widget is destroyed.
*/
-class LLViewModel: public LLRefCount
+class LLViewModel
+: public LLRefCount,
+ public LLTrace::MemTrackable<LLViewModel>
{
public:
LLViewModel();
@@ -80,6 +83,8 @@ public:
//
void setDirty() { mDirty = true; }
+ static LLTrace::MemStatHandle sMemStat;
+
protected:
LLSD mValue;
bool mDirty;
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 6322da9123..2814efec47 100755
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -29,7 +29,7 @@
#include "llxuiparser.h"
#include "llxmlnode.h"
-
+#include "llfasttimer.h"
#ifdef LL_STANDALONE
#include <expat.h>
#else
@@ -334,6 +334,8 @@ LLXSDWriter::LLXSDWriter()
registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));
}
+LLXSDWriter::~LLXSDWriter() {}
+
void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
{
Schema schema(xml_namespace);
@@ -858,11 +860,11 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
return any_parsed;
}
-void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
+void LLXUIParser::writeXUIImpl(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)
{
mWriteRootNode = node;
name_stack_t name_stack = Parser::name_stack_t();
- block.serializeBlock(*this, name_stack, diff_block);
+ block.serializeBlock(*this, name_stack, rules, diff_block);
mOutNodes.clear();
}
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index e48663e5cc..ad2a39cab7 100755
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -29,21 +29,15 @@
#include "llinitparam.h"
#include "llregistry.h"
-#include "llpointer.h"
+#include "llxmlnode.h"
#include <boost/function.hpp>
#include <iosfwd>
#include <stack>
#include <set>
-
-
class LLView;
-
-typedef LLPointer<class LLXMLNode> LLXMLNodePtr;
-
-
// lookup widget type by name
class LLWidgetTypeRegistry
: public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
@@ -59,8 +53,6 @@ class LLChildRegistryRegistry
: public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
{};
-
-
class LLXSDWriter : public LLInitParam::Parser
{
LOG_CLASS(LLXSDWriter);
@@ -70,6 +62,7 @@ public:
/*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }
LLXSDWriter();
+ ~LLXSDWriter();
protected:
void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values);
@@ -109,9 +102,26 @@ public:
/*virtual*/ void parserError(const std::string& message);
void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false);
- void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
+ template<typename BLOCK>
+ void writeXUI(LLXMLNodePtr node,
+ const BLOCK& block,
+ const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(),
+ const LLInitParam::BaseBlock* diff_block = NULL)
+ {
+ if (!diff_block
+ && !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE))
+ {
+ diff_block = &LLInitParam::defaultValue<BLOCK>();
+ }
+ writeXUIImpl(node, block, rules, diff_block);
+ }
private:
+ LLXUIParser(const LLXUIParser& other); // no-copy
+ void writeXUIImpl(LLXMLNodePtr node,
+ const LLInitParam::BaseBlock& block,
+ const LLInitParam::predicate_rule_t rules,
+ const LLInitParam::BaseBlock* diff_block);
bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);
bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
index 0424f2379e..3b83d1b9e3 100755
--- a/indra/llvfs/llpidlock.cpp
+++ b/indra/llvfs/llpidlock.cpp
@@ -36,7 +36,7 @@
#if LL_WINDOWS //For windows platform.
-#include <windows.h>
+#include "llwin32headerslean.h"
namespace {
inline DWORD getpid() {
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index 306d7d8ec7..ea67b8027b 100755
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -30,9 +30,10 @@
#include "llerror.h"
#include "llthread.h"
-#include "llstat.h"
-#include "llvfs.h"
+#include "lltimer.h"
+#include "llfasttimer.h"
#include "llmemory.h"
+#include "llvfs.h"
const S32 LLVFile::READ = 0x00000001;
const S32 LLVFile::WRITE = 0x00000002;
@@ -135,7 +136,7 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S
data = NULL;
}
else
- {
+ {
data = (U8*) ll_aligned_malloc_16(file_size);
file.read(data, file_size); /* Flawfinder: ignore */
diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h
index 929e7f9e37..ba7fac0bd1 100755
--- a/indra/llwindow/lldragdropwin32.h
+++ b/indra/llwindow/lldragdropwin32.h
@@ -31,7 +31,7 @@
#ifndef LL_LLDRAGDROP32_H
#define LL_LLDRAGDROP32_H
-#include <windows.h>
+#include "llwin32headerslean.h"
#include <ole2.h>
class LLDragDropWin32
@@ -54,7 +54,7 @@ class LLDragDropWin32
#ifndef LL_LLDRAGDROP32_H
#define LL_LLDRAGDROP32_H
-#include <windows.h>
+#include "llwin32headerslean.h"
#include <ole2.h>
// imposter class that does nothing
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index c155c1b362..276074d4ca 100755
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -28,6 +28,7 @@
#define LL_LLKEYBOARD_H
#include <map>
+#include <boost/function.hpp>
#include "string_table.h"
#include "lltimer.h"
diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index be3fe5deb0..b76d526c5a 100755
--- a/indra/llwindow/llkeyboardwin32.cpp
+++ b/indra/llwindow/llkeyboardwin32.cpp
@@ -28,10 +28,7 @@
#include "linden_common.h"
-#define WIN32_LEAN_AND_MEAN
-#include <winsock2.h>
-#include <windows.h>
-
+#include "llwin32headerslean.h"
#include "llkeyboardwin32.h"
#include "llwindowcallbacks.h"
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index e9147d552e..c235d77656 100755
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -31,6 +31,7 @@
#include "llcoord.h"
#include "llstring.h"
#include "llcursortypes.h"
+#include "llinstancetracker.h"
#include "llsd.h"
class LLSplashScreen;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 43c0090993..6d887926fa 100755
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -38,6 +38,7 @@
// Linden library includes
#include "llerror.h"
+#include "llfasttimer.h"
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 54c9ac4d4d..169d264808 100755
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -28,9 +28,7 @@
#define LL_LLWINDOWWIN32_H
// Limit Windows API to small and manageable set.
-#define WIN32_LEAN_AND_MEAN
-#include <winsock2.h>
-#include <windows.h>
+#include "llwin32headerslean.h"
#include "llwindow.h"
#include "llwindowcallbacks.h"
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index b12d2e4a16..e9b4d1fcbb 100755
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -35,7 +35,6 @@
#include "lscript_library.h"
#include "lscript_heapruntime.h"
#include "lscript_alloc.h"
-#include "llstat.h"
// Static
diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
index 24328202cb..eb18a3776f 100755
--- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
+++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp
@@ -28,18 +28,10 @@
#include "linden_common.h"
-#include "llgl.h"
-
-#include "llplugininstance.h"
-#include "llpluginmessage.h"
-#include "llpluginmessageclasses.h"
-#include "media_plugin_base.h"
-
-#if LL_QUICKTIME_ENABLED
-
#if defined(LL_DARWIN)
#include <QuickTime/QuickTime.h>
#elif defined(LL_WINDOWS)
+ #include "llwin32headers.h"
#include "MacTypes.h"
#include "QTML.h"
#include "Movies.h"
@@ -48,6 +40,17 @@
#include "QTLoadLibraryUtils.h"
#endif
+#include "llgl.h"
+
+#include "llplugininstance.h"
+#include "llpluginmessage.h"
+#include "llpluginmessageclasses.h"
+#include "media_plugin_base.h"
+
+#if LL_QUICKTIME_ENABLED
+
+
+
// TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint
////////////////////////////////////////////////////////////////////////////////
//
diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp
index 8a06bb8487..c20bcd374d 100755
--- a/indra/media_plugins/webkit/mac_volume_catcher.cpp
+++ b/indra/media_plugins/webkit/mac_volume_catcher.cpp
@@ -38,6 +38,7 @@
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <AudioUnit/AudioUnit.h>
+#include <list>
struct VolumeCatcherStorage;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d06cee5ee6..3689c2856d 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -239,7 +239,6 @@ set(viewer_SOURCE_FILES
llfloaterinspect.cpp
llfloaterinventory.cpp
llfloaterjoystick.cpp
- llfloaterlagmeter.cpp
llfloaterland.cpp
llfloaterlandholdings.cpp
llfloatermap.cpp
@@ -264,6 +263,7 @@ set(viewer_SOURCE_FILES
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
llfloaterreporter.cpp
+ llfloatersceneloadstats.cpp
llfloaterscriptdebug.cpp
llfloaterscriptlimits.cpp
llfloatersearch.cpp
@@ -487,6 +487,7 @@ set(viewer_SOURCE_FILES
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
llsaveoutfitcombobtn.cpp
+ llscenemonitor.cpp
llsceneview.cpp
llscreenchannel.cpp
llscriptfloater.cpp
@@ -608,6 +609,7 @@ set(viewer_SOURCE_FILES
llviewernetwork.cpp
llviewerobject.cpp
llviewerobjectlist.cpp
+ llvieweroctree.cpp
llviewerparcelmedia.cpp
llviewerparcelmediaautoplay.cpp
llviewerparcelmgr.cpp
@@ -822,7 +824,6 @@ set(viewer_HEADER_FILES
llfloaterinspect.h
llfloaterinventory.h
llfloaterjoystick.h
- llfloaterlagmeter.h
llfloaterland.h
llfloaterlandholdings.h
llfloatermap.h
@@ -847,6 +848,7 @@ set(viewer_HEADER_FILES
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
llfloaterreporter.h
+ llfloatersceneloadstats.h
llfloaterscriptdebug.h
llfloaterscriptlimits.h
llfloatersearch.h
@@ -1060,6 +1062,7 @@ set(viewer_HEADER_FILES
llrootview.h
llsavedsettingsglue.h
llsaveoutfitcombobtn.h
+ llscenemonitor.h
llsceneview.h
llscreenchannel.h
llscriptfloater.h
@@ -1181,6 +1184,7 @@ set(viewer_HEADER_FILES
llviewernetwork.h
llviewerobject.h
llviewerobjectlist.h
+ llvieweroctree.h
llviewerparcelmedia.h
llviewerparcelmediaautoplay.h
llviewerparcelmgr.h
@@ -1568,7 +1572,7 @@ endif (WINDOWS)
if (OPENAL)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
-endif (OPENAL)
+endif (OPENAL)
if (FMODEX)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
@@ -1988,7 +1992,7 @@ if (DARWIN)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
- )
+ )
add_custom_command(
TARGET ${VIEWER_BINARY_NAME} POST_BUILD
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 12ca902c59..a255793017 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2928,7 +2928,7 @@
<key>Value</key>
<string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
</map>
- <key>DefaultObjectTexture</key>
+ <key>DefaultObjectTexture</key>
<map>
<key>Comment</key>
<string>Texture used as 'Default' in texture picker. (UUID texture reference)</string>
@@ -4611,6 +4611,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>InvisibleObjectsInMemoryTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of frames invisible objects stay in memory before being removed. 0 means never to remove.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>64</integer>
+ </map>
<key>JoystickAvatarEnabled</key>
<map>
<key>Comment</key>
@@ -6663,6 +6674,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>ObjectCacheViewCullingEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable the object cache view culling. Needs to restart viewer.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>OpenDebugStatAdvanced</key>
<map>
<key>Comment</key>
@@ -7155,6 +7177,17 @@
<key>Value</key>
<real>6.0</real>
</map>
+ <key>ClothingLoadingDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Time to wait for avatar appearance to resolve before showing world (seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
<key>PreferredMaturity</key>
<map>
<key>Comment</key>
@@ -7710,7 +7743,6 @@
<key>Value</key>
<integer>1</integer>
</map>
-
<key>OctreeMaxNodeCapacity</key>
<map>
<key>Comment</key>
@@ -9787,6 +9819,39 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SceneLoadingMonitorEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enabled scene loading monitor if set</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>SceneLoadingMonitorSampleTime</key>
+ <map>
+ <key>Comment</key>
+ <string>Time between screen samples when monitor scene load (seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.25</real>
+ </map>
+ <key>SceneLoadingPixelDiffThreshold</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount of pixels changed required to consider the scene as still loading (fraction of pixels on screen)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0003</real>
+ </map>
<key>ScriptHelpFollowsCursor</key>
<map>
<key>Comment</key>
@@ -12724,6 +12789,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>UseObjectCacheOcclusion</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable object cache level object culling based on occlusion (coverage) by other objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderSynchronousOcclusion</key>
<map>
<key>Comment</key>
@@ -14489,6 +14565,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>TeleportArrivalDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Time to wait before displaying world during teleport (seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2</real>
+ </map>
+ <key>TeleportLocalDelay</key>
+ <map>
+ <key>Comment</key>
+ <string>Delay to prevent teleports after starting an in-sim teleport. (seconds)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>DisablePrecacheDelayAfterTeleporting</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl
new file mode 100644
index 0000000000..f1400c9b44
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl
@@ -0,0 +1,49 @@
+/**
+ * @file onetexturefilterF.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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D tex0;
+uniform float tolerance;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
+{
+ frag_color = texture2D(tex0, vary_texcoord0.xy);
+
+ if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance)
+ {
+ discard;
+ }
+ else
+ {
+ frag_color[3] = 0.95f;
+ }
+}
diff --git a/indra/llcommon/reflective.cpp b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl
index 2cc0e7e1f2..a33ef7e92c 100755..100644
--- a/indra/llcommon/reflective.cpp
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl
@@ -1,12 +1,9 @@
/**
- * @file reflective.cpp
- * @author Babbage
- * @date 2006-05-15
- * @brief Implementation of LLReflective.
+ * @file onetexturefilterV.glsl
*
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * 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
@@ -25,16 +22,17 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#include "linden_common.h"
-#include "reflective.h"
+uniform mat4 modelview_projection_matrix;
-LLReflective::LLReflective()
-{
-}
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
-//virtual
-LLReflective::~LLReflective()
+VARYING vec2 vary_texcoord0;
+
+void main()
{
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = texcoord0;
}
+
diff --git a/indra/llcommon/metaproperty.cpp b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl
index 98d850bf1e..6eeb2596b2 100755..100644
--- a/indra/llcommon/metaproperty.cpp
+++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl
@@ -1,12 +1,9 @@
/**
- * @file metaproperty.cpp
- * @author Babbage
- * @date 2006-05-15
- * @brief Implementation of LLMetaProperty.
+ * @file twotexturecompareF.glsl
*
- * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * 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
@@ -26,31 +23,36 @@
* $/LicenseInfo$
*/
-#include "linden_common.h"
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
-#include "metaproperty.h"
+uniform sampler2D tex0;
+uniform sampler2D tex1;
+uniform sampler2D dither_tex;
+uniform float dither_scale;
+uniform float dither_scale_s;
+uniform float dither_scale_t;
-#include "metaclass.h"
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
-LLMetaProperty::LLMetaProperty(const std::string& name, const LLMetaClass& object_class) :
- mName(name), mObjectClass(object_class)
+void main()
{
-}
+ frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy));
-//virtual
-LLMetaProperty::~LLMetaProperty()
-{
-}
+ vec2 dither_coord;
+ dither_coord[0] = vary_texcoord0[0] * dither_scale_s;
+ dither_coord[1] = vary_texcoord0[1] * dither_scale_t;
+ vec4 dither_vec = texture(dither_tex, dither_coord.xy);
-const LLMetaClass& LLMetaProperty::getObjectMetaClass() const
-{
- return mObjectClass;
-}
-
-void LLMetaProperty::checkObjectClass(const LLReflective* object) const
-{
- if(! mObjectClass.isInstance(object))
+ for(int i = 0; i < 3; i++)
{
- throw "class cast exception";
+ if(frag_color[i] < dither_vec[i] * dither_scale)
+ {
+ frag_color[i] = 0.f;
+ }
}
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl
new file mode 100644
index 0000000000..67c6674f0c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl
@@ -0,0 +1,41 @@
+/**
+ * @file twotexturecompareV.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 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+ATTRIBUTE vec2 texcoord0;
+ATTRIBUTE vec2 texcoord1;
+
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+
+void main()
+{
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = texcoord0;
+ vary_texcoord1 = texcoord1;
+}
+
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index c64e11929d..4c39014c8b 100755
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -32,20 +32,20 @@
// 1 - We claim to support this card.
//
-3Dfx .*3Dfx.* 0 0 0 0
-3Dlabs .*3Dlabs.* 0 0 0 0
-ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
-ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
-ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
-ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
+3Dfx .*3Dfx.* 0 0 0 0
+3Dlabs .*3Dlabs.* 0 0 0 0
+ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0
+ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0
+ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0
+ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0
ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 0 0
-ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
-ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
-ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
-ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
-ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
-ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
-ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
+ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 1 3.3
+ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 0 0
+ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 1 1 1 2.1
+ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0
+ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0
+ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0
+ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0
ATI ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0
ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0
ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3
@@ -79,30 +79,30 @@ ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1
ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0
ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1
ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1
-ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
+ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1
ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1
ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1
ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1
ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 1 1 1 2.1
-ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
-ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
-ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
-ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
+ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1
+ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1
+ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3
+ATI FireGL .*ATI.*Fire.*GL.* 4 1 1 4.2
ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 0 0
-ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
-ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
-ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
+ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 0 0
+ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 0 0
+ATI FirePro M7820 .*ATI.*FirePro.*M78.* 5 1 1 4.2
ATI FireMV .*ATI.*FireMV.* 0 1 1 1.3
-ATI Generic .*ATI.*Generic.* 0 0 0 0
-ATI Hercules 9800 .*ATI.*Hercules.* 9800.* 1 1 0 0
+ATI Generic .*ATI.*Generic.* 0 0 0 0
+ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0
ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0
-ATI M52 .*ATI.*M52.* 1 1 0 0
-ATI M54 .*ATI.*M54.* 1 1 0 0
-ATI M56 .*ATI.*M56.* 1 1 0 0
-ATI M71 .*ATI.*M71.* 1 1 0 0
-ATI M72 .*ATI.*M72.* 1 1 0 0
-ATI M76 .*ATI.*M76.* 3 1 0 0
+ATI M52 .*ATI.*M52.* 1 1 0 0
+ATI M54 .*ATI.*M54.* 1 1 0 0
+ATI M56 .*ATI.*M56.* 1 1 0 0
+ATI M71 .*ATI.*M71.* 1 1 0 0
+ATI M72 .*ATI.*M72.* 1 1 0 0
+ATI M76 .*ATI.*M76.* 3 1 0 0
ATI Radeon HD 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2
ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2
ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2
@@ -124,12 +124,12 @@ ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0
ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2
ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2
ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2
-ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3
-ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
-ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
-ATI Mobility Radeon 9800 .*ATI.*Mobility.* 98.* 1 1 0 0
-ATI Mobility Radeon 9700 .*ATI.*Mobility.* 97.* 0 1 1 2.1
-ATI Mobility Radeon 9600 .*ATI.*Mobility.* 96.* 1 1 1 2.1
+ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3
+ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3
+ATI Mobility Radeon 8xxx .*ATI.*Mobility.*Radeon 8.* 0 1 0 0
+ATI Mobility Radeon 9800 .*ATI.*Mobility.*98.* 1 1 0 0
+ATI Mobility Radeon 9700 .*ATI.*Mobility.*97.* 0 1 1 2.1
+ATI Mobility Radeon 9600 .*ATI.*Mobility.*96.* 1 1 1 2.1
ATI Mobility Radeon HD 530v .*ATI.*Mobility.*HD *530v.* 1 1 1 3.3
ATI Mobility Radeon HD 540v .*ATI.*Mobility.*HD *540v.* 1 1 1 3.3
ATI Mobility Radeon HD 545v .*ATI.*Mobility.*HD *545v.* 2 1 1 4
@@ -176,7 +176,7 @@ ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4
ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0
ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3
ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0
-ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
+ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4
ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0
ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4
@@ -202,128 +202,128 @@ ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2
ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2
ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2
ATI Radeon HD 6900 .*ATI.*Radeon HD *69.. 5 1 1 4.2
-ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
-ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
-ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
-ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
-ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
-ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
-ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
-ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
-ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
-ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
-ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
-ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
-ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
-ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
-ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
-ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
-ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
+ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0
+ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1
+ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4
+ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3
+ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0
+ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2
+ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0
+ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3
+ATI Radeon 9100 .*ATI.*Radeon 91.. 0 1 0 0
+ATI Radeon 9200 .*ATI.*Radeon 92.. 0 1 1 1.3
+ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1
+ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1
+ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0
+ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1
+ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0
+ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0
+ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0
ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 0 0
-ATI RS880M .*ATI.*RS880M 1 1 0 0
-ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
-ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
+ATI RS880M .*ATI.*RS880M 1 1 0 0
+ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0
+ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0
ATI Radeon X300 .*ATI.*Radeon *X3.* 1 1 1 2.1
-ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
-ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
+ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0
+ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1
ATI Radeon X600 .*ATI.*Radeon ?X6.* 1 1 1 2.1
-ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
-ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
-ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
-ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
-ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
-ATI R300 (9700) .*R300.* 0 1 1 2.1
-ATI R350 (9800) .*R350.* 1 1 0 0
-ATI R580 (X1900) .*R580.* 3 1 0 0
-ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
-ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
-ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
-ATI RV350 (9600) .*RV350.* 0 1 0 0
-ATI RV370 (X300) .*RV370.* 0 1 0 0
-ATI RV410 (X700) .*RV410.* 1 1 0 0
-ATI RV515 .*RV515.* 1 1 0 0
-ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
-ATI RV380 .*RV380.* 0 1 0 0
-ATI RV530 .*RV530.* 1 1 0 0
-ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
-ATI RX700 .*RX700.* 1 1 0 0
-AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
-AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
-AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
-AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
+ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1
+ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1
+ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0
+ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1
+ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0
+ATI R300 (9700) .*R300.* 0 1 1 2.1
+ATI R350 (9800) .*R350.* 1 1 0 0
+ATI R580 (X1900) .*R580.* 3 1 0 0
+ATI RC410 (Xpress 200) .*RC410.* 0 0 0 0
+ATI RS48x (Xpress 200x) .*RS48.* 0 0 0 0
+ATI RS600 (Xpress 3200) .*RS600.* 0 0 0 0
+ATI RV350 (9600) .*RV350.* 0 1 0 0
+ATI RV370 (X300) .*RV370.* 0 1 0 0
+ATI RV410 (X700) .*RV410.* 1 1 0 0
+ATI RV515 .*RV515.* 1 1 0 0
+ATI RV570 (X1900 GT/PRO) .*RV570.* 3 1 0 0
+ATI RV380 .*RV380.* 0 1 0 0
+ATI RV530 .*RV530.* 1 1 0 0
+ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0
+ATI RX700 .*RX700.* 1 1 0 0
+AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0
+AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1
+AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0
+AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 0 0
AMD CEDAR (HD 5450) .*(AMD|ATI).*Cedar.* 2 1 0 0
-AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
-AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
-AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
-AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
+AMD CYPRESS (HD 5800) .*(AMD|ATI).*Cypress.* 3 1 0 0
+AMD HEMLOCK (HD 5970) .*(AMD|ATI).*Hemlock.* 3 1 0 0
+AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0
+AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0
AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 0
AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0
-AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
-AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
-AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
-AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
-AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
+AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1
+AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2
+AMD RV610 (HD 2400) .*RV610.* 1 1 0 0
+AMD RV620 (HD 3400) .*RV620.* 1 1 0 0
+AMD RV630 (HD 2600) .*RV630.* 2 1 0 0
AMD RV635 (HD 3600) .*RV635.* 3 1 0 0
-AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
-AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
-AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
-AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
+AMD RV670 (HD 3800) .*RV670.* 3 1 0 0
+AMD R680 (HD 3870 X2) .*R680.* 3 1 0 0
+AMD R700 (HD 4800 X2) .*R700.* 3 1 0 0
+AMD RV710 (HD 4300) .*RV710.* 0 1 1 1.4
AMD RV730 (HD 4600) .*RV730.* 3 1 0 0
-AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
-AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
-AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
-ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
-ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
-ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
+AMD RV740 (HD 4700) .*RV740.* 3 1 0 0
+AMD RV770 (HD 4800) .*RV770.* 3 1 0 0
+AMD RV790 (HD 4800) .*RV790.* 3 1 0 0
+ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3
+ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0
+ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0
ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.1
-ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
+ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0
-ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0
-ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0
-ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
-ATI R300 (9700) .*R300.* 0 1 1 2.1
+ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0
+ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0
+ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2
+ATI R300 (9700) .*R300.* 0 1 1 2.1
ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2
-Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
-Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
-Intel 830M .*Intel.*830M 0 0 0 0
-Intel 845G .*Intel.*845G 0 0 1 1.4
-Intel 855GM .*Intel.*855GM 0 0 1 1.4
-Intel 865G .*Intel.*865G 0 0 1 1.4
-Intel 900 .*Intel.*900.*900 0 0 0 0
-Intel 915GM .*Intel.*915GM 0 0 1 1.4
-Intel 915G .*Intel.*915G 0 0 1 1.4
-Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
-Intel 945G .*Intel.*945G.* 0 1 1 1.4
-Intel 950 .*Intel.*950.* 0 1 1 1.4
-Intel 965 .*Intel.*965.* 0 1 1 2.1
-Intel G33 .*Intel.*G33.* 1 0 1 1.4
-Intel G41 .*Intel.*G41.* 1 1 1 2.1
-Intel G45 .*Intel.*G45.* 1 1 1 2.1
-Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
-Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
-Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
-Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
-Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
-Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
-Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4
-Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
-Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4
+Intel X3100 .*Intel.*X3100.* 1 1 1 2.1
+Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3
+Intel 830M .*Intel.*830M 0 0 0 0
+Intel 845G .*Intel.*845G 0 0 1 1.4
+Intel 855GM .*Intel.*855GM 0 0 1 1.4
+Intel 865G .*Intel.*865G 0 0 1 1.4
+Intel 900 .*Intel.*900.*900 0 0 0 0
+Intel 915GM .*Intel.*915GM 0 0 1 1.4
+Intel 915G .*Intel.*915G 0 0 1 1.4
+Intel 945GM .*Intel.*945GM.* 0 1 1 1.4
+Intel 945G .*Intel.*945G.* 0 1 1 1.4
+Intel 950 .*Intel.*950.* 0 1 1 1.4
+Intel 965 .*Intel.*965.* 0 1 1 2.1
+Intel G33 .*Intel.*G33.* 1 0 1 1.4
+Intel G41 .*Intel.*G41.* 1 1 1 2.1
+Intel G45 .*Intel.*G45.* 1 1 1 2.1
+Intel Bear Lake .*Intel.*Bear Lake.* 1 0 1 1.4
+Intel Broadwater .*Intel.*Broadwater.* 0 0 1 1.4
+Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3
+Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2
+Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2
+Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1
+Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4
+Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1
+Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4
Intel HD2000 .*Intel.*HD2000.* 2 1 0 0
Intel HD3000 .*Intel.*HD3000.* 3 1 0 0
-Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
-Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
-Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
-Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
-Intel Montara .*Intel.*Montara.* 0 0 1 1.3
-Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
-Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
-Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
-Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
-Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
-Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
-Matrox .*Matrox.* 0 0 0 0
+Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4
+Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1
+Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1
+Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0
+Intel Montara .*Intel.*Montara.* 0 0 1 1.3
+Intel Pineview .*Intel.*Pineview.* 0 1 1 1.4
+Intel Springdale .*Intel.*Springdale.* 0 0 1 1.3
+Intel Grantsdale .*Intel.*Grantsdale.* 1 1 0 0
+Intel Q45/Q43 .*Intel.*Q4.* 1 1 1 2.1
+Intel B45/B43 .*Intel.*B4.* 1 1 1 2.1
+Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0
+Matrox .*Matrox.* 0 0 0 0
Mesa .*Mesa.* 1 0 1 2.1
-Gallium .*Gallium.* 1 1 1 2.1
+Gallium .*Gallium.* 1 1 1 2.1
NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3
NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3
NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3
@@ -380,14 +380,14 @@ NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0
NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2
NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0
NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0
-NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
+NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3
NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 3.3
NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0
-NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3
-NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3
-NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3
-NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3
+NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3
+NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3
+NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3
+NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3
NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3
NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3
NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3
@@ -397,12 +397,12 @@ NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3
NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3
NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3
NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3
-NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3
-NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3
+NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3
+NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3
NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3
NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3
NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0
-NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3
+NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3
NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2
NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.2
NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2
@@ -429,125 +429,125 @@ NVIDIA GTX 660 .*NVIDIA .*GTX *66.* 5 1 0 4.3
NVIDIA GTX 670 .*NVIDIA .*GTX *67.* 5 1 1 4.2
NVIDIA GTX 680 .*NVIDIA .*GTX *68.* 5 1 1 4.2
NVIDIA GTX 690 .*NVIDIA .*GTX *69.* 5 1 1 4.2
-NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
-NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
-NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
-NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
-NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
-NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
-NVIDIA GeForce .*GeForce 256.* 0 0 0 0
-NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
+NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2
+NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0
+NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0
+NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0
+NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0
+NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0
+NVIDIA GeForce .*GeForce 256.* 0 0 0 0
+NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5
NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1
NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0
-NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
+NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0
NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0
NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0
NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0
-NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
-NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
-NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
-NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
-NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
-NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
-NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
-NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
-NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
-NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
-NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
-NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
-NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
-NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
+NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2
+NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1
+NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1
+NVIDIA GeForce 6600 .*NVIDIA .*GeForce 66.* 2 1 1 2.1
+NVIDIA GeForce 6700 .*NVIDIA .*GeForce 67.* 2 1 1 2.1
+NVIDIA GeForce 6800 .*NVIDIA .*GeForce 68.* 1 1 1 2.1
+NVIDIA GeForce 7000 .*NVIDIA .*GeForce 70.* 1 1 1 2.1
+NVIDIA GeForce 7100 .*NVIDIA .*GeForce 71.* 1 1 1 2.1
+NVIDIA GeForce 7200 .*NVIDIA .*GeForce 72.* 1 1 0 0
+NVIDIA GeForce 7300 .*NVIDIA .*GeForce 73.* 1 1 1 2.1
+NVIDIA GeForce 7500 .*NVIDIA .*GeForce 75.* 2 1 1 2.1
+NVIDIA GeForce 7600 .*NVIDIA .*GeForce 76.* 2 1 1 2.1
+NVIDIA GeForce 7800 .*NVIDIA .*GeForce 78.* 2 1 1 2.1
+NVIDIA GeForce 7900 .*NVIDIA .*GeForce 79.* 3 1 1 2.1
NVIDIA GeForce 8100 .*NVIDIA .*GeForce 81.* 1 1 0 0
NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3
NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1
-NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
+NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 1 1 1 3.3
-NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
-NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
+NVIDIA GeForce 8400 .*NVIDIA .*GeForce 84.* 2 1 1 3.3
+NVIDIA GeForce 8500 .*NVIDIA .*GeForce 85.* 2 1 1 3.3
NVIDIA GeForce 8600M .*NVIDIA .*GeForce 8600M.* 2 1 1 3.3
-NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
+NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3
-NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
+NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3
-NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
+NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0
-NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
+NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1
-NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
+NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3
-NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
+NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3
-NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
+NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3
-NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
+NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3
-NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
+NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3
NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 2 1 1 3.3
-NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
-NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
-NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
-NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
-NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
-NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
-NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
-NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
-NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
-NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
+NVIDIA GeForce 9800 .*NVIDIA .*GeForce 98.* 3 1 1 3.3
+NVIDIA GeForce FX 5100 .*NVIDIA .*GeForce FX 51.* 0 1 0 0
+NVIDIA GeForce FX 5200 .*NVIDIA .*GeForce FX 52.* 0 1 0 2.1
+NVIDIA GeForce FX 5300 .*NVIDIA .*GeForce FX 53.* 0 1 0 0
+NVIDIA GeForce FX 5500 .*NVIDIA .*GeForce FX 55.* 0 1 1 2.1
+NVIDIA GeForce FX 5600 .*NVIDIA .*GeForce FX 56.* 1 1 1 2.1
+NVIDIA GeForce FX 5700 .*NVIDIA .*GeForce FX 57.* 0 1 1 2.1
+NVIDIA GeForce FX 5800 .*NVIDIA .*GeForce FX 58.* 1 1 0 0
+NVIDIA GeForce FX 5900 .*NVIDIA .*GeForce FX 59.* 1 1 1 2.1
+NVIDIA GeForce FX Go5100 .*NVIDIA .*GeForce FX Go51.* 0 1 0 0
NVIDIA GeForce FX Go5200 .*NVIDIA .*GeForce FX Go52.* 0 1 0 0
-NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
-NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
-NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
-NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
-NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
-NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
-NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
-NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
+NVIDIA GeForce FX Go5300 .*NVIDIA .*GeForce FX Go53.* 0 1 0 0
+NVIDIA GeForce FX Go5500 .*NVIDIA .*GeForce FX Go55.* 0 1 0 0
+NVIDIA GeForce FX Go5600 .*NVIDIA .*GeForce FX Go56.* 0 1 1 2.1
+NVIDIA GeForce FX Go5700 .*NVIDIA .*GeForce FX Go57.* 1 1 1 1.5
+NVIDIA GeForce FX Go5800 .*NVIDIA .*GeForce FX Go58.* 1 1 0 0
+NVIDIA GeForce FX Go5900 .*NVIDIA .*GeForce FX Go59.* 1 1 0 0
+NVIDIA GeForce FX Go5xxx .*NVIDIA .*GeForce FX Go.* 0 1 0 0
+NVIDIA GeForce Go 6100 .*NVIDIA .*GeForce Go 61.* 0 1 1 2.1
NVIDIA GeForce Go 6200 .*NVIDIA .*GeForce Go 62.* 0 1 0 0
NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2
-NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
-NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
-NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
-NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
+NVIDIA GeForce Go 6500 .*NVIDIA .*GeForce Go 65.* 1 1 0 0
+NVIDIA GeForce Go 6600 .*NVIDIA .*GeForce Go 66.* 0 1 1 2.1
+NVIDIA GeForce Go 6700 .*NVIDIA .*GeForce Go 67.* 1 1 0 0
+NVIDIA GeForce Go 6800 .*NVIDIA .*GeForce Go 68.* 0 1 1 2.1
NVIDIA GeForce Go 7200 .*NVIDIA .*GeForce Go 72.* 1 1 0 0
-NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
-NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
-NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
-NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
-NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
-NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
-NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
-NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
-NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
-NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
-NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0
-NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3
-NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
-NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
-NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
-NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
-NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
+NVIDIA GeForce Go 7300 LE .*NVIDIA .*GeForce Go 73.*LE.* 1 1 0 0
+NVIDIA GeForce Go 7300 .*NVIDIA .*GeForce Go 73.* 1 1 1 2.1
+NVIDIA GeForce Go 7400 .*NVIDIA .*GeForce Go 74.* 1 1 1 2.1
+NVIDIA GeForce Go 7600 .*NVIDIA .*GeForce Go 76.* 1 1 1 2.1
+NVIDIA GeForce Go 7700 .*NVIDIA .*GeForce Go 77.* 0 1 1 2.1
+NVIDIA GeForce Go 7800 .*NVIDIA .*GeForce Go 78.* 2 1 0 0
+NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1
+NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0
+NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0
+NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0
+NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0
+NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3
+NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0
+NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0
+NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0
+NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0
+NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0
NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 0
NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0
NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3
-NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
-NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
-NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
-NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
-NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
-NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
-NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
-NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
-NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
+NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0
+NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0
+NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0
+NVIDIA NV36 .*NVIDIA .*NV36.* 1 1 0 0
+NVIDIA NV41 .*NVIDIA .*NV41.* 1 1 0 0
+NVIDIA NV43 .*NVIDIA .*NV43.* 1 1 0 0
+NVIDIA NV44 .*NVIDIA .*NV44.* 1 1 0 0
+NVIDIA nForce .*NVIDIA .*nForce.* 0 0 0 3.3
+NVIDIA MCP51 .*NVIDIA .*MCP51.* 1 1 0 0
NVIDIA MCP61 .*NVIDIA .*MCP61.* 1 1 0 0
-NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
-NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
-NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
-NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
-NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
-NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
-NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
+NVIDIA MCP67 .*NVIDIA .*MCP67.* 1 1 0 0
+NVIDIA MCP68 .*NVIDIA .*MCP68.* 1 1 0 0
+NVIDIA MCP73 .*NVIDIA .*MCP73.* 1 1 0 0
+NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0
+NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0
+NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0
+NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0
NVIDIA Quadro2 .*Quadro2.* 0 1 0 0
NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2
NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2
@@ -555,12 +555,12 @@ NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0
NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0
NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2
NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0
-NVIDIA Quadro 6000 .*Quadro.* 6000.* 3 1 0 0
-NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3
+NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 0 0
+NVIDIA Quadro 400 .*Quadro.*400.* 2 1 0 3.3
NVIDIA Quadro 600 .*Quadro.*600.* 2 1 0 3.3
NVIDIA Quadro4 .*Quadro4.* 0 1 0 0
-NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
-NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
+NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
+NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0
NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1
NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0
@@ -574,7 +574,7 @@ NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2
NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0
NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3
NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0
-NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3
+NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3
NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 1 3.3
NVIDIA Quadro NVS 300M .*NVIDIA .*NVS *300M.* 2 1 0 0
NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0
@@ -583,16 +583,16 @@ NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0
NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1
NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0
NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2
-NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
+NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0
NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0
-S3 .*S3 Graphics.* 0 0 1 1.4
-SiS SiS.* 0 0 1 1.5
-Trident Trident.* 0 0 0 0
-Tungsten Graphics Tungsten.* 0 0 0 0
-XGI XGI.* 0 0 0 0
-VIA VIA.* 0 0 0 0
-Apple Generic Apple.*Generic.* 0 0 0 0
-Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
-Humper Humper.* 0 1 1 2.1
-PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
+S3 .*S3 Graphics.* 0 0 1 1.4
+SiS SiS.* 0 0 1 1.5
+Trident Trident.* 0 0 0 0
+Tungsten Graphics Tungsten.* 0 0 0 0
+XGI XGI.* 0 0 0 0
+VIA VIA.* 0 0 0 0
+Apple Generic Apple.*Generic.* 0 0 0 0
+Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0
+Humper Humper.* 0 1 1 2.1
+PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3e94c5edf7..8ec74bb268 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -754,7 +754,7 @@ void LLAgent::setFlying(BOOL fly)
}
if( !was_flying )
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
+ add(LLStatViewer::FLY, 1);
}
setControlFlags(AGENT_CONTROL_FLY);
}
@@ -2830,10 +2830,10 @@ BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */
if (!ignore_god_mode && isGodlike())
return true;
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
+ U32 count = mGroups.size();
+ for(U32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
return TRUE;
}
@@ -2850,12 +2850,12 @@ BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const
// GP_NO_POWERS can also mean no power is enough to grant an ability.
if (GP_NO_POWERS == power) return FALSE;
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
+ U32 count = mGroups.size();
+ for(U32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- return (BOOL)((mGroups.get(i).mPowers & power) > 0);
+ return (BOOL)((mGroups[i].mPowers & power) > 0);
}
}
return FALSE;
@@ -2871,12 +2871,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const
if (isGodlike())
return GP_ALL_POWERS;
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
+ U32 count = mGroups.size();
+ for(U32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- return (mGroups.get(i).mPowers);
+ return (mGroups[i].mPowers);
}
}
@@ -2885,12 +2885,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const
BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const
{
- S32 count = mGroups.count();
+ S32 count = mGroups.size();
for(S32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- data = mGroups.get(i);
+ data = mGroups[i];
return TRUE;
}
}
@@ -2899,12 +2899,12 @@ BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const
S32 LLAgent::getGroupContribution(const LLUUID& group_id) const
{
- S32 count = mGroups.count();
+ S32 count = mGroups.size();
for(S32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- S32 contribution = mGroups.get(i).mContribution;
+ S32 contribution = mGroups[i].mContribution;
return contribution;
}
}
@@ -2913,12 +2913,12 @@ S32 LLAgent::getGroupContribution(const LLUUID& group_id) const
BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)
{
- S32 count = mGroups.count();
+ S32 count = mGroups.size();
for(S32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- mGroups.get(i).mContribution = contribution;
+ mGroups[i].mContribution = contribution;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("SetGroupContribution");
msg->nextBlock("AgentData");
@@ -2936,13 +2936,13 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)
BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile)
{
- S32 count = mGroups.count();
+ S32 count = mGroups.size();
for(S32 i = 0; i < count; ++i)
{
- if(mGroups.get(i).mID == group_id)
+ if(mGroups[i].mID == group_id)
{
- mGroups.get(i).mAcceptNotices = accept_notices;
- mGroups.get(i).mListInProfile = list_in_profile;
+ mGroups[i].mAcceptNotices = accept_notices;
+ mGroups[i].mListInProfile = list_in_profile;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage("SetGroupAcceptNotices");
msg->nextBlock("AgentData");
@@ -2962,7 +2962,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO
BOOL LLAgent::canJoinGroups() const
{
- return mGroups.count() < gMaxAgentGroups;
+ return (S32)mGroups.size() < gMaxAgentGroups;
}
LLQuaternion LLAgent::getHeadRotation()
@@ -3792,7 +3792,7 @@ bool LLAgent::teleportCore(bool is_local)
gAgentCamera.resetView(FALSE);
// local logic
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
+ add(LLStatViewer::TELEPORT, 1);
if (is_local)
{
gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
@@ -4109,7 +4109,7 @@ void LLAgent::setTeleportState(ETeleportState state)
case TELEPORT_ARRIVING:
// First two position updates after a teleport tend to be weird
- LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
+ //LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
// Let the interested parties know we've teleported.
LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
@@ -4317,7 +4317,7 @@ void LLAgent::sendAgentSetAppearance()
return;
}
-
+
LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
//dumpAvatarTEs( "sendAgentSetAppearance()" );
@@ -4425,7 +4425,7 @@ void LLAgent::sendAgentSetAppearance()
}
}
-// llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
+ //llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
sendReliableMessage();
}
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f5f26f69d8..4153fbbfff 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -35,6 +35,7 @@
#include "llcoordframe.h" // for mFrameAgent
#include "llavatarappearancedefines.h"
#include "llpermissionsflags.h"
+#include "lldarray.h"
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
@@ -251,6 +252,7 @@ public:
const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; }
void setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; }
+
private:
std::set<U64> mRegionsVisited; // Stat - what distinct regions has the avatar been to?
F64 mDistanceTraveled; // Stat - how far has the avatar moved?
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 488a134aa2..d02817df7b 100755
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -337,7 +337,7 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
LLVector3 agent_at_axis = gAgent.getAtAxis();
agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector());
agent_at_axis.normalize();
- gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f)));
+ gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f)));
}
setFocusOnAvatar(TRUE, ANIMATE);
@@ -1070,8 +1070,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
- if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
- (root_at * last_at_axis > 0.95f))
+ if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f
+ && (root_at * last_at_axis > 0.95f))
{
LLVector3 vel = gAgentAvatarp->getVelocity();
if (vel.magVecSquared() > 4.f)
@@ -1126,13 +1126,14 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
}
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Camera");
+
//-----------------------------------------------------------------------------
// updateCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::updateCamera()
{
- static LLFastTimer::DeclareTimer ftm("Camera");
- LLFastTimer t(ftm);
+ LLFastTimer t(FTM_UPDATE_CAMERA);
// - changed camera_skyward to the new global "mCameraUpVector"
mCameraUpVector = LLVector3::z_axis;
@@ -1234,7 +1235,7 @@ void LLAgentCamera::updateCamera()
gAgentCamera.clearPanKeys();
// lerp camera focus offset
- mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
+ mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
if ( mCameraMode == CAMERA_MODE_FOLLOW )
{
@@ -1352,7 +1353,7 @@ void LLAgentCamera::updateCamera()
{
const F32 SMOOTHING_HALF_LIFE = 0.02f;
- F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
+ F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
if (!mFocusObject) // we differentiate on avatar mode
{
@@ -1382,7 +1383,7 @@ void LLAgentCamera::updateCamera()
}
- mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE));
+ mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE));
// llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
@@ -1796,7 +1797,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
if (mTargetCameraDistance != mCurrentCameraDistance)
{
- F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
+ F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
}
@@ -1813,7 +1814,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
if (isAgentAvatarValid())
{
LLVector3d camera_lag_d;
- F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
+ F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE);
LLVector3 target_lag;
LLVector3 vel = gAgent.getVelocity();
@@ -1858,7 +1859,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
else
{
- mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f));
+ mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f));
}
camera_lag_d.setVec(mCameraLag);
@@ -2267,22 +2268,22 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
gFocusMgr.setKeyboardFocus( NULL );
gFocusMgr.setMouseCapture( NULL );
- // Remove any pitch or rotation from the avatar
- LLVector3 at = gAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
+ // Remove any pitch or rotation from the avatar
+ LLVector3 at = gAgent.getAtAxis();
+ at.mV[VZ] = 0.f;
+ at.normalize();
+ gAgent.resetAxes(at);
- gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
- gAgent.setCustomAnim(TRUE);
- gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
- LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
+ gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+ gAgent.setCustomAnim(TRUE);
+ gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+ LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
- if (turn_motion)
- {
- // delay camera animation long enough to play through turn animation
- setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
- }
+ if (turn_motion)
+ {
+ // delay camera animation long enough to play through turn animation
+ setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
+ }
}
LLVector3 agent_at = gAgent.getAtAxis();
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 1edbbe2a2e..e158dc7505 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -39,6 +39,7 @@
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
+#include "lllocaltextureobject.h"
#include "llmd5.h"
#include "llnotificationsutil.h"
#include "lloutfitobserver.h"
@@ -62,15 +63,15 @@ using namespace LLAvatarAppearanceDefines;
// Callback to wear and start editing an item that has just been created.
void wear_and_edit_cb(const LLUUID& inv_item)
- {
- if (inv_item.isNull()) return;
-
- // Request editing the item after it gets worn.
- gAgentWearables.requestEditingWearable(inv_item);
-
- // Wear it.
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
- }
+{
+ if (inv_item.isNull()) return;
+
+ // Request editing the item after it gets worn.
+ gAgentWearables.requestEditingWearable(inv_item);
+
+ // Wear it.
+ LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
+}
///////////////////////////////////////////////////////////////////////////////
@@ -180,10 +181,10 @@ void LLAgentWearables::initClass()
}
void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
-{
+{
llassert(avatar);
- avatar->outputRezTiming("Sending wearables request");
- sendAgentWearablesRequest();
+ avatar->outputRezTiming("Sending wearables request");
+ sendAgentWearablesRequest();
setAvatarAppearance(avatar);
}
@@ -706,7 +707,7 @@ LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::ETyp
}
const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
- {
+{
return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));
}
@@ -714,39 +715,39 @@ const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType
BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
{
return (gAgentWearables.getWearableCount(type) > 0);
- }
-
+}
+
// virtual
void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
- {
+{
if (isAgentAvatarValid())
{
const BOOL upload_result = removed;
gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
-}
+ }
LLWearableData::wearableUpdated(wearable, removed);
if (!removed)
-{
+ {
LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);
viewer_wearable->refreshName();
- // Hack pt 2. If the wearable we just loaded has definition version 24,
- // then force a re-save of this wearable after slamming the version number to 22.
- // This number was incorrectly incremented for internal builds before release, and
- // this fix will ensure that the affected wearables are re-saved with the right version number.
- // the versions themselves are compatible. This code can be removed before release.
- if( wearable->getDefinitionVersion() == 24 )
- {
- wearable->setDefinitionVersion(22);
- U32 index = getWearableIndex(wearable);
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( wearable->getDefinitionVersion() == 24 )
+ {
+ wearable->setDefinitionVersion(22);
+ U32 index = getWearableIndex(wearable);
llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
- saveWearable(wearable->getType(),index,TRUE);
- }
+ saveWearable(wearable->getType(),index,TRUE);
+ }
checkWearableAgainstInventory(viewer_wearable);
-}
+ }
}
BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
@@ -965,8 +966,8 @@ public:
llinfos << "All items created" << llendl;
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
- mItemsToLink,
- link_waiter);
+ mItemsToLink,
+ link_waiter);
}
void addPendingWearable(LLViewerWearable *wearable)
{
@@ -1496,12 +1497,12 @@ void LLAgentWearables::queryWearableCache()
// virtual
void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
{
- // Add some garbage into the hash so that it becomes invalid.
- if (isAgentAvatarValid())
- {
- hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
- }
- }
+ // Add some garbage into the hash so that it becomes invalid.
+ if (isAgentAvatarValid())
+ {
+ hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
+ }
+}
// User has picked "remove from avatar" from a menu.
// static
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 46252afbde..862b428e48 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -34,6 +34,7 @@
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llviewerinventory.h"
+#include "llhttpclient.h"
class LLWearableHoldingPattern;
class LLInventoryCallback;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f92274dbbd..733c9cc9df 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -61,7 +61,8 @@
#include "llcalc.h"
#include "llconversationlog.h"
#include "lltexturestats.h"
-#include "lltexturestats.h"
+#include "lltrace.h"
+#include "lltracethreadrecorder.h"
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
@@ -96,6 +97,7 @@
#include "llupdaterservice.h"
#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
+#include "llscenemonitor.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -294,7 +296,7 @@ LLPumpIO* gServicePump = NULL;
U64 gFrameTime = 0;
F32 gFrameTimeSeconds = 0.f;
-F32 gFrameIntervalSeconds = 0.f;
+LLUnit<F32, LLUnits::Seconds> gFrameIntervalSeconds = 0.f;
F32 gFPSClamped = 10.f; // Pretend we start at target rate.
F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
@@ -625,7 +627,7 @@ public:
while (!LLAppViewer::instance()->isQuitting())
{
- LLFastTimer::writeLog(os);
+ LLTrace::TimeBlock::writeLog(os);
os.flush();
ms_sleep(32);
}
@@ -723,7 +725,6 @@ bool LLAppViewer::init()
// into the log files during normal startup until AFTER
// we run the "program crashed last time" error handler below.
//
- LLFastTimer::reset();
// initialize LLWearableType translation bridge.
// Memory will be cleaned up in ::cleanupClass()
@@ -745,7 +746,7 @@ bool LLAppViewer::init()
initLoggingAndGetLastDuration();
processMarkerFiles();
-
+
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
@@ -1250,10 +1251,12 @@ static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
-LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);
+LLFastTimer::DeclareTimer FTM_FRAME("Frame");
bool LLAppViewer::mainLoop()
{
+ llinfos << "***********************Entering main_loop***********************" << llendflush;
+
mMainloopTimeout = new LLWatchdogTimeout();
//-------------------------------------------
@@ -1290,7 +1293,11 @@ bool LLAppViewer::mainLoop()
while (!LLApp::isExiting())
{
LLFastTimer _(FTM_FRAME);
- LLFastTimer::nextFrame();
+ LLTrace::TimeBlock::processTimes();
+ LLTrace::get_frame_recording().nextPeriod();
+ LLTrace::TimeBlock::logStats();
+
+ LLTrace::getUIThreadRecorder().pullFromSlaveThreads();
//clear call stack records
llclearcallstacks;
@@ -1407,7 +1414,6 @@ bool LLAppViewer::mainLoop()
LLFloaterSnapshot::update(); // take snapshots
gGLActive = FALSE;
}
-
}
pingMainloopTimeout("Main:Sleep");
@@ -1462,20 +1468,9 @@ bool LLAppViewer::mainLoop()
{
S32 work_pending = 0;
S32 io_pending = 0;
- F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f);
- {
- LLFastTimer ftm(FTM_TEXTURE_CACHE);
- work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- }
- {
- LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- }
- {
- LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
- }
+ work_pending += updateTextureThreads(max_time);
{
LLFastTimer ftm(FTM_VFS);
@@ -1588,11 +1583,29 @@ bool LLAppViewer::mainLoop()
destroyMainloopTimeout();
- llinfos << "Exiting main_loop" << llendflush;
+ llinfos << "***********************Exiting main_loop***********************" << llendflush;
return true;
}
+S32 LLAppViewer::updateTextureThreads(F32 max_time)
+{
+ S32 work_pending = 0;
+ {
+ LLFastTimer ftm(FTM_TEXTURE_CACHE);
+ work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ }
+ {
+ LLFastTimer ftm(FTM_DECODE);
+ work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ }
+ {
+ LLFastTimer ftm(FTM_DECODE);
+ work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+ }
+ return work_pending;
+}
+
void LLAppViewer::flushVFSIO()
{
while (1)
@@ -1616,12 +1629,15 @@ bool LLAppViewer::cleanup()
// workaround for DEV-35406 crash on shutdown
LLEventPumps::instance().reset();
+ //dump scene loading monitor results
+ LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+
if (LLFastTimerView::sAnalyzePerformance)
{
llinfos << "Analyzing performance" << llendl;
- std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
- std::string current_name = LLFastTimer::sLogName + ".slp";
- std::string report_name = LLFastTimer::sLogName + "_report.csv";
+ std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp";
+ std::string current_name = LLTrace::TimeBlock::sLogName + ".slp";
+ std::string report_name = LLTrace::TimeBlock::sLogName + "_report.csv";
LLFastTimerView::doAnalysis(
gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
@@ -1729,7 +1745,7 @@ bool LLAppViewer::cleanup()
gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
- gAudiop->shutdown();
+ gAudiop->shutdown();
delete gAudiop;
gAudiop = NULL;
@@ -1975,9 +1991,9 @@ bool LLAppViewer::cleanup()
{
llinfos << "Analyzing performance" << llendl;
- std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
- std::string current_name = LLFastTimer::sLogName + ".slp";
- std::string report_name = LLFastTimer::sLogName + "_report.csv";
+ std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp";
+ std::string current_name = LLTrace::TimeBlock::sLogName + ".slp";
+ std::string report_name = LLTrace::TimeBlock::sLogName + "_report.csv";
LLFastTimerView::doAnalysis(
gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name),
@@ -2102,10 +2118,10 @@ bool LLAppViewer::initThreads()
enable_threads && true,
app_metrics_qa_mode);
- if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
+ if (LLTrace::TimeBlock::sLog || LLTrace::TimeBlock::sMetricLog)
{
- LLFastTimer::sLogLock = new LLMutex(NULL);
- mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName);
+ LLTrace::TimeBlock::setLogLock(new LLMutex(NULL));
+ mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::TimeBlock::sLogName);
mFastTimerLogThread->start();
}
@@ -2558,13 +2574,13 @@ bool LLAppViewer::initConfiguration()
if (clp.hasOption("logperformance"))
{
- LLFastTimer::sLog = TRUE;
- LLFastTimer::sLogName = std::string("performance");
+ LLTrace::TimeBlock::sLog = true;
+ LLTrace::TimeBlock::sLogName = std::string("performance");
}
if (clp.hasOption("logmetrics"))
{
- LLFastTimer::sMetricLog = TRUE ;
+ LLTrace::TimeBlock::sMetricLog = true ;
// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test
// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)
std::string test_name = clp.getOption("logmetrics")[0];
@@ -2572,11 +2588,11 @@ bool LLAppViewer::initConfiguration()
if (test_name == "")
{
llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl;
- LLFastTimer::sLogName = DEFAULT_METRIC_NAME;
+ LLTrace::TimeBlock::sLogName = DEFAULT_METRIC_NAME;
}
else
{
- LLFastTimer::sLogName = test_name;
+ LLTrace::TimeBlock::sLogName = test_name;
}
}
@@ -2987,26 +3003,26 @@ namespace {
{
LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL;
- // truncate version at the rightmost '.'
- std::string version_short(data["version"]);
- size_t short_length = version_short.rfind('.');
- if (short_length != std::string::npos)
- {
- version_short.resize(short_length);
- }
+ // truncate version at the rightmost '.'
+ std::string version_short(data["version"]);
+ size_t short_length = version_short.rfind('.');
+ if (short_length != std::string::npos)
+ {
+ version_short.resize(short_length);
+ }
- LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
- relnotes_url.setArg("[VERSION_SHORT]", version_short);
+ LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
+ relnotes_url.setArg("[VERSION_SHORT]", version_short);
- // *TODO thread the update service's response through to this point
- std::string const & channel = LLVersionInfo::getChannel();
- boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
+ // *TODO thread the update service's response through to this point
+ std::string const & channel = LLVersionInfo::getChannel();
+ boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
- relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
- relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
+ relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
+ relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
substitutions["INFO_URL"] = relnotes_url.getString();
}
-
+
LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
}
@@ -3473,9 +3489,9 @@ void LLAppViewer::handleViewerCrash()
if (gDirUtilp)
{
std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- gLLErrorActivated
- ? LLERROR_MARKER_FILE_NAME
- : ERROR_MARKER_FILE_NAME);
+ gLLErrorActivated
+ ? LLERROR_MARKER_FILE_NAME
+ : ERROR_MARKER_FILE_NAME);
LLAPRFile crash_marker_file ;
crash_marker_file.open(crash_marker_file_name, LL_APR_WB);
if (crash_marker_file.getFileHandle())
@@ -3486,7 +3502,7 @@ void LLAppViewer::handleViewerCrash()
else
{
LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;
- }
+ }
}
else
{
@@ -3625,7 +3641,7 @@ void LLAppViewer::processMarkerFiles()
}
if (mSecondInstance)
- {
+ {
LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL;
}
else if (marker_is_same_version)
@@ -3639,7 +3655,7 @@ void LLAppViewer::processMarkerFiles()
{
LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
}
- }
+ }
else // marker did not exist... last exec (if any) did not freeze
{
// Create the marker file for this execution & lock it; it will be deleted on a clean exit
@@ -3693,12 +3709,12 @@ void LLAppViewer::processMarkerFiles()
{
gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
+ }
+ else
+ {
gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
- }
+ }
}
else
{
@@ -3711,20 +3727,20 @@ void LLAppViewer::processMarkerFiles()
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
if (markerIsSameVersion(error_marker_file))
- {
+ {
if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
- {
+ {
gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
- }
}
else
{
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ }
+ else
+ {
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
}
LLAPRFile::remove(error_marker_file);
@@ -3736,30 +3752,30 @@ void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
if (!mSecondInstance)
{
LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL;
- if (mMarkerFile.getFileHandle())
- {
+ if (mMarkerFile.getFileHandle())
+ {
LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
- mMarkerFile.close() ;
- LLAPRFile::remove( mMarkerFileName );
- }
- else
- {
+ mMarkerFile.close();
+ LLAPRFile::remove( mMarkerFileName );
+ }
+ else
+ {
LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
- }
- if (!leave_logout_marker)
+ }
+ if (!leave_logout_marker)
+ {
+ if (mLogoutMarkerFile.getFileHandle())
{
- if (mLogoutMarkerFile.getFileHandle())
- {
LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
- mLogoutMarkerFile.close();
- }
- else
- {
+ mLogoutMarkerFile.close();
+ }
+ else
+ {
LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
- }
- LLAPRFile::remove( mLogoutMarkerFileName );
}
+ LLAPRFile::remove( mLogoutMarkerFileName );
}
+}
else
{
LL_WARNS("MarkerFile") << "leaving markers because this is a second instance" << LL_ENDL;
@@ -4017,7 +4033,7 @@ U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
// format changes. JC
- const U32 INDRA_OBJECT_CACHE_VERSION = 14;
+ const U32 INDRA_OBJECT_CACHE_VERSION = 15;
return INDRA_OBJECT_CACHE_VERSION;
}
@@ -4274,6 +4290,14 @@ void LLAppViewer::purgeCache()
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
}
+//purge cache immediately, do not wait until the next login.
+void LLAppViewer::purgeCacheImmediate()
+{
+ LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
+ LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+}
+
std::string LLAppViewer::getSecondLifeTitle() const
{
return LLTrans::getString("APP_NAME");
@@ -4458,6 +4482,8 @@ static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");
static LLFastTimer::DeclareTimer FTM_NETWORK("Network");
static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network");
static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager");
+static LLFastTimer::DeclareTimer FTM_AGENT_POSITION("Agent Position");
+static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("HUD Effects");
///////////////////////////////////////////////////////
// idle()
@@ -4476,7 +4502,7 @@ void LLAppViewer::idle()
LLFrameTimer::updateFrameCount();
LLEventTimer::updateClass();
LLNotificationsUI::LLToast::updateClass();
- LLCriticalDamp::updateInterpolants();
+ LLSmoothInterpolation::updateInterpolants();
LLMortician::updateClass();
LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify()
@@ -4501,6 +4527,7 @@ void LLAppViewer::idle()
{
if (gRenderStartTime.getElapsedTimeF32() > qas)
{
+ llinfos << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << llendl;
LLAppViewer::instance()->forceQuit();
}
}
@@ -4599,21 +4626,12 @@ void LLAppViewer::idle()
llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
gObjectList.mNumDeadObjectUpdates = 0;
}
- if (gObjectList.mNumUnknownKills)
- {
- llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
- gObjectList.mNumUnknownKills = 0;
- }
if (gObjectList.mNumUnknownUpdates)
{
llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
gObjectList.mNumUnknownUpdates = 0;
}
- // ViewerMetrics FPS piggy-backing on the debug timer.
- // The 5-second interval is nice for this purpose. If the object debug
- // bit moves or is disabled, please give this a suitable home.
- LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
}
}
@@ -4694,8 +4712,7 @@ void LLAppViewer::idle()
{
// Handle pending gesture processing
- static LLFastTimer::DeclareTimer ftm("Agent Position");
- LLFastTimer t(ftm);
+ LLFastTimer t(FTM_AGENT_POSITION);
LLGestureMgr::instance().update();
gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
@@ -4742,8 +4759,7 @@ void LLAppViewer::idle()
//
{
- static LLFastTimer::DeclareTimer ftm("HUD Effects");
- LLFastTimer t(ftm);
+ LLFastTimer t(FTM_HUD_EFFECTS);
LLSelectMgr::getInstance()->updateEffects();
LLHUDManager::getInstance()->cleanupEffects();
LLHUDManager::getInstance()->sendEffects();
@@ -5147,7 +5163,7 @@ void LLAppViewer::idleNetwork()
gPrintMessagesThisFrame = FALSE;
}
}
- LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
+ add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
@@ -5226,6 +5242,7 @@ void LLAppViewer::disconnectViewer()
{
LLWorld::getInstance()->destroyClass();
}
+ LLVOCache::deleteSingleton();
// call all self-registered classes
LLDestroyClassList::instance().fireCallbacks();
@@ -5392,7 +5409,7 @@ void LLAppViewer::handleLoginComplete()
void LLAppViewer::launchUpdater()
{
- LLSD query_map = LLSD::emptyMap();
+ LLSD query_map = LLSD::emptyMap();
query_map["os"] = gPlatform;
// *TODO change userserver to be grid on both viewer and sim, since
@@ -5554,17 +5571,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)
{
if (0 != region_handle)
{
- LLViewerAssetStatsFF::set_region_main(region_handle);
- if (LLAppViewer::sTextureFetch)
- {
- // Send a region update message into 'thread1' to get the new region.
- LLAppViewer::sTextureFetch->commandSetRegion(region_handle);
- }
- else
- {
- // No 'thread1', a.k.a. TextureFetch, so update directly
- LLViewerAssetStatsFF::set_region_thread1(region_handle);
- }
+ LLViewerAssetStatsFF::set_region(region_handle);
}
}
@@ -5575,7 +5582,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)
*/
void LLAppViewer::metricsSend(bool enable_reporting)
{
- if (! gViewerAssetStatsMain)
+ if (! gViewerAssetStats)
return;
if (LLAppViewer::sTextureFetch)
@@ -5588,7 +5595,10 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Make a copy of the main stats to send into another thread.
// Receiving thread takes ownership.
- LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain));
+ LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats));
+ main_stats->stop();
+
+ main_stats->updateStats();
// Send a report request into 'thread1' to get the rest of the data
// and provide some additional parameters while here.
@@ -5607,6 +5617,6 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Reset even if we can't report. Rather than gather up a huge chunk of
// data, we'll keep to our sampling interval and retain the data
// resolution in time.
- gViewerAssetStatsMain->reset();
+ gViewerAssetStats->reset();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cd91ae8b2b..68e9ebeff3 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -32,6 +32,7 @@
#include "llsys.h" // for LLOSInfo
#include "lltimer.h"
#include "llappcorehttp.h"
+#include "llunit.h"
class LLCommandLineParser;
class LLFrameTimer;
@@ -169,6 +170,8 @@ public:
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
void purgeCache(); // Clear the local cache.
+ void purgeCacheImmediate(); //clear local cache immediately.
+ S32 updateTextureThreads(F32 max_time);
// mute/unmute the system's master audio
virtual void setMasterSystemAudioMute(bool mute);
@@ -333,7 +336,7 @@ extern LLPumpIO* gServicePump;
extern U64 gFrameTime; // The timestamp of the most-recently-processed frame
extern F32 gFrameTimeSeconds; // Loses msec precision after ~4.5 hours...
-extern F32 gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds
+extern LLUnit<F32, LLUnits::Seconds> gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds
extern F32 gFPSClamped; // Frames per second, smoothed, weighted toward last frame
extern F32 gFrameDTClamped;
extern U64 gStartTime;
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 3cf3c739d9..b7cdcb058b 100755
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -29,11 +29,12 @@
#ifdef INCLUDE_VLD
#include "vld.h"
#endif
+#include "llwin32headers.h"
-#include "llappviewerwin32.h"
+#include "llwindowwin32.h" // *FIX: for setting gIconResource.
+#include "llappviewerwin32.h"
-#include "llwindowwin32.h" // *FIX: for setting gIconResource.
#include "llgl.h"
#include "res/resource.h" // *FIX: for setting gIconResource.
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 14583e402d..3da77857c6 100755
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -32,13 +32,10 @@
#include "llcallingcard.h"
-#include <vector>
#include <algorithm>
-//#include <iterator>
#include "indra_constants.h"
-#include "llavatarnamecache.h"
-#include "llcachename.h"
+//#include "llcachename.h"
#include "llstl.h"
#include "lltimer.h"
#include "lluuid.h"
@@ -46,19 +43,14 @@
#include "llagent.h"
#include "llavatarnamecache.h"
-#include "llbutton.h"
#include "llinventoryobserver.h"
#include "llinventorymodel.h"
#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "llresmgr.h"
#include "llslurl.h"
#include "llimview.h"
#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
-#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llavataractions.h"
@@ -105,8 +97,6 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
LLAvatarTracker::LLAvatarTracker() :
mTrackingData(NULL),
mTrackedAgentValid(false),
- //mInventory(NULL),
- //mInventoryObserver(NULL),
mModifyMask(0x0)
{
}
@@ -641,11 +631,11 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
payload["from_id"] = agent_id;
if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
{
- LLNotificationsUtil::add("GrantedModifyRights",args, payload);
+ LLNotifications::instance().add("GrantedModifyRights",args, payload);
}
else
{
- LLNotificationsUtil::add("RevokedModifyRights",args, payload);
+ LLNotifications::instance().add("RevokedModifyRights",args, payload);
}
}
(mBuddyInfo[agent_id])->setRightsFrom(new_rights);
@@ -729,7 +719,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
if (online)
{
notification =
- LLNotificationsUtil::add("FriendOnlineOffline",
+ LLNotifications::instance().add("FriendOnlineOffline",
args,
payload.with("respond_on_mousedown", TRUE),
boost::bind(&LLAvatarActions::startIM, agent_id));
@@ -737,7 +727,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
else
{
notification =
- LLNotificationsUtil::add("FriendOnlineOffline", args, payload);
+ LLNotifications::instance().add("FriendOnlineOffline", args, payload);
}
// If there's an open IM session with this agent, send a notification there too.
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 7d0331757b..b883941963 100755
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -618,24 +618,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
send_chat_from_viewer(utf8_out_text, type, channel);
}
-/*
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ChatFromViewer);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ChatData);
- msg->addStringFast(_PREHASH_Message, utf8_out_text);
- msg->addU8Fast(_PREHASH_Type, type);
- msg->addS32("Channel", channel);
-
- gAgent.sendReliableMessage();
-
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-*/
void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
{
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 4588424474..d70d575eab 100755
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -424,8 +424,6 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
{
LLSD args;
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index aeecf054b8..1264f05d77 100755
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -40,7 +40,7 @@
#include "llsceneview.h"
#include "llviewertexture.h"
#include "llfloaterreg.h"
-
+#include "llscenemonitor.h"
//
// Globals
//
@@ -66,6 +66,7 @@ LLDebugView::~LLDebugView()
gDebugView = NULL;
gTextureView = NULL;
gSceneView = NULL;
+ gSceneMonitorView = NULL;
}
void LLDebugView::init()
@@ -99,6 +100,13 @@ void LLDebugView::init()
addChild(gSceneView);
gSceneView->setRect(rect);
+ gSceneMonitorView = new LLSceneMonitorView(r);
+ gSceneMonitorView->setFollowsTop();
+ gSceneMonitorView->setFollowsLeft();
+ gSceneMonitorView->setVisible(FALSE);
+ addChild(gSceneMonitorView);
+ gSceneMonitorView->setRect(rect);
+
r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),
(S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f));
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index d7d9f82910..6fd0897919 100755
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -27,7 +27,6 @@
#include "llviewerprecompiledheaders.h"
#include "lldirpicker.h"
-//#include "llviewermessage.h"
#include "llworld.h"
#include "llviewerwindow.h"
#include "llkeyboard.h"
@@ -36,6 +35,7 @@
#include "lltrans.h"
#include "llwindow.h" // beforeDialog()
#include "llviewercontrol.h"
+#include "llwin32headerslean.h"
#if LL_LINUX || LL_SOLARIS
# include "llfilepicker.h"
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index 682f9d6476..2299341aba 100755
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -46,11 +46,6 @@
#endif
-// Need commdlg.h for OPENDIRNAMEA
-#ifdef LL_WINDOWS
-#include <commdlg.h>
-#endif
-
class LLFilePicker;
class LLDirPicker
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8c9fd4152a..628f7f7bfb 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -49,6 +49,7 @@
#include "llspatialpartition.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
+#include "llvocache.h"
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
@@ -58,6 +59,7 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
extern bool gShiftFrame;
+LLTrace::MemStatHandle LLDrawable::sMemStat("LLDrawable");
////////////////////////
@@ -75,43 +77,70 @@ extern bool gShiftFrame;
//
// static
-U32 LLDrawable::sCurVisible = 0;
U32 LLDrawable::sNumZombieDrawables = 0;
F32 LLDrawable::sCurPixelAngle = 0;
-LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
+LLDynamicArray<LLPointer<LLDrawable>, 32 > LLDrawable::sDeadList;
#define FORCE_INVISIBLE_AREA 16.f
// static
void LLDrawable::incrementVisible()
{
- sCurVisible++;
+ LLViewerOctreeEntryData::incrementVisible();
sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();
}
-void LLDrawable::init()
+LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
+ : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
+ mVObjp(vobj)
+{
+ init(new_entry);
+}
+
+void LLDrawable::init(bool new_entry)
{
// mXform
mParent = NULL;
mRenderType = 0;
mCurrentScale = LLVector3(1,1,1);
mDistanceWRTCamera = 0.0f;
- mPositionGroup.clear();
- mExtents[0].clear();
- mExtents[1].clear();
-
mState = 0;
- mVObjp = NULL;
+
// mFaces
- mSpatialGroupp = NULL;
- mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.
mRadius = 0.f;
+ mGeneration = -1;
+ mSpatialBridge = NULL;
+
+ LLViewerOctreeEntry* entry = NULL;
+ LLVOCacheEntry* vo_entry = NULL;
+ if(!new_entry && mVObjp && getRegion() != NULL)
+ {
+ vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID());
+ if(vo_entry)
+ {
+ entry = vo_entry->getEntry();
+ }
+ }
+ setOctreeEntry(entry);
+ if(vo_entry)
+ {
+ if(!entry)
+ {
+ vo_entry->setOctreeEntry(mEntry);
+ }
+ else if(vo_entry->getNumOfChildren() > 0)
+ {
+ getRegion()->addVisibleCacheEntry(vo_entry); //to load all children.
+ }
- mGeneration = -1;
- mBinRadius = 1.f;
- mBinIndex = -1;
+ getRegion()->addActiveCacheEntry(vo_entry);
- mSpatialBridge = NULL;
+ llassert(!vo_entry->getGroup()); //not in the object cache octree.
+ }
+
+ llassert(!vo_entry || vo_entry->getEntry() == mEntry);
+
+ initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
// static
@@ -155,6 +184,7 @@ void LLDrawable::markDead()
llwarns << "Warning! Marking dead multiple times!" << llendl;
return;
}
+ setState(DEAD);
if (mSpatialBridge)
{
@@ -165,7 +195,6 @@ void LLDrawable::markDead()
sNumZombieDrawables++;
// We're dead. Free up all of our references to other objects
- setState(DEAD);
cleanupReferences();
// sDeadList.put(this);
}
@@ -219,6 +248,8 @@ void LLDrawable::cleanupReferences()
gPipeline.unlinkDrawable(this);
+ removeFromOctree();
+
{
LLFastTimer t(FTM_DEREF_DRAWABLE);
// Cleanup references to other objects
@@ -227,6 +258,21 @@ void LLDrawable::cleanupReferences()
}
}
+void LLDrawable::removeFromOctree()
+{
+ if(!mEntry)
+ {
+ return;
+ }
+
+ mEntry->removeData(this);
+ if(mEntry->hasVOCacheEntry())
+ {
+ getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this);
+ }
+ mEntry = NULL;
+}
+
void LLDrawable::cleanupDeadDrawables()
{
/*
@@ -254,7 +300,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
-static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true);
+static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face");
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
@@ -482,6 +528,12 @@ void LLDrawable::makeActive()
}
updatePartition();
}
+ else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does...
+ {
+ mParent->makeActive();
+ //NOTE: linked set will now NEVER become static
+ mParent->setState(LLDrawable::ACTIVE_CHILD);
+ }
llassert(isAvatar() || isRoot() || mParent->isActive());
}
@@ -561,7 +613,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
if (damped && isVisible())
{
- F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
+ F32 lerp_amt = llclamp(LLSmoothInterpolation::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);
LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);
dist_squared = dist_vec_squared(new_pos, target_pos);
@@ -776,7 +828,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVOVolume* volume = getVOVolume();
if (volume)
{
- if (getSpatialGroup())
+ if (getGroup())
{
pos.set(getPositionGroup().getF32ptr());
}
@@ -894,9 +946,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
}
- mExtents[0].add(shift_vector);
- mExtents[1].add(shift_vector);
- mPositionGroup.add(shift_vector);
+ shift(shift_vector);
}
else if (mSpatialBridge)
{
@@ -904,9 +954,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
}
else if (isAvatar())
{
- mExtents[0].add(shift_vector);
- mExtents[1].add(shift_vector);
- mPositionGroup.add(shift_vector);
+ shift(shift_vector);
}
mVObjp->onShift(shift_vector);
@@ -918,40 +966,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const
return mXform.getPositionW();
}
-const LLVector4a* LLDrawable::getSpatialExtents() const
-{
- return mExtents;
-}
-
-void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max)
-{
- mExtents[0].load3(min.mV);
- mExtents[1].load3(max.mV);
-}
-
-void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
-{
- mExtents[0] = min;
- mExtents[1] = max;
-}
-
-void LLDrawable::setPositionGroup(const LLVector4a& pos)
-{
- mPositionGroup = pos;
-}
-
void LLDrawable::updateSpatialExtents()
{
if (mVObjp)
{
- mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]);
+ const LLVector4a* exts = getSpatialExtents();
+ LLVector4a extents[2];
+ extents[0] = exts[0];
+ extents[1] = exts[1];
+
+ mVObjp->updateSpatialExtents(extents[0], extents[1]);
+ setSpatialExtents(extents[0], extents[1]);
}
updateBinRadius();
if (mSpatialBridge.notNull())
{
- mPositionGroup.splat(0.f);
+ getGroupPosition().splat(0.f);
}
}
@@ -960,11 +992,11 @@ void LLDrawable::updateBinRadius()
{
if (mVObjp.notNull())
{
- mBinRadius = llmin(mVObjp->getBinRadius(), 256.f);
+ setBinRadius(llmin(mVObjp->getBinRadius(), 256.f));
}
else
{
- mBinRadius = llmin(getRadius()*4.f, 256.f);
+ setBinRadius(llmin(getRadius()*4.f, 256.f));
}
}
@@ -998,26 +1030,56 @@ void LLDrawable::updateUVMinMax()
{
}
-LLSpatialGroup* LLDrawable::getSpatialGroup() const
+//virtual
+bool LLDrawable::isVisible() const
+{
+ if (LLViewerOctreeEntryData::isVisible())
{
- llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
- return mSpatialGroupp;
+ return true;
}
-void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
- //precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this
- llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this));
+ LLviewerOctreeGroup* group = mEntry->getGroup();
+ if (group && group->isVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ return true;
+ }
+ }
- //precondition: groupp MUST be null or groupp MUST contain this
- llassert(!groupp || groupp->hasElement(this));
+ return false;
+}
-/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
+//virtual
+bool LLDrawable::isRecentlyVisible() const
+{
+ //currently visible or visible in the previous frame.
+ bool vis = LLViewerOctreeEntryData::isRecentlyVisible();
+
+ if(!vis)
{
- mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY);
- }*/
+ LLviewerOctreeGroup* group = getGroup();
+ if (group && group->isRecentlyVisible())
+ {
+ LLViewerOctreeEntryData::setVisible();
+ vis = TRUE ;
+ }
+ }
+
+ return vis ;
+}
+
+void LLDrawable::setGroup(LLviewerOctreeGroup *groupp)
+ {
+ LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup();
+
+ //precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this
+ //llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this));
- if (mSpatialGroupp != groupp && getVOVolume())
+ //precondition: groupp MUST be null or groupp MUST contain this
+ llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this));
+
+ if (cur_groupp != groupp && getVOVolume())
{ //NULL out vertex buffer references for volumes on spatial group change to maintain
//requirement that every face vertex buffer is either NULL or points to a vertex buffer
//contained by its drawable's spatial group
@@ -1033,10 +1095,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1
//postcondition: if next group is NOT NULL, binIndex must not be -1
- llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 :
- getBinIndex() != -1);
+ //llassert(groupp == NULL ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) :
+ // (getEntry() && getEntry()->getBinIndex() != -1));
- mSpatialGroupp = groupp;
+ LLViewerOctreeEntryData::setGroup(groupp);
}
LLSpatialPartition* LLDrawable::getSpatialPartition()
@@ -1055,11 +1117,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
{
if (mVObjp->isHUDAttachment())
{
- setSpatialBridge(new LLHUDBridge(this));
+ setSpatialBridge(new LLHUDBridge(this, getRegion()));
}
else
{
- setSpatialBridge(new LLVolumeBridge(this));
+ setSpatialBridge(new LLVolumeBridge(this, getRegion()));
}
}
return mSpatialBridge->asPartition();
@@ -1078,89 +1140,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
-const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
-//static
-S32 LLDrawable::getMinVisFrameRange()
-{
- return MIN_VIS_FRAME_RANGE ;
-}
-
-BOOL LLDrawable::isRecentlyVisible() const
-{
- //currently visible or visible in the previous frame.
- BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
-
- if(!vis)
- {
- LLSpatialGroup* group = getSpatialGroup();
- if (group && group->isRecentlyVisible())
- {
- mVisible = sCurVisible;
- vis = TRUE ;
- }
- }
-
- return vis ;
-}
-
-BOOL LLDrawable::isVisible() const
+//virtual
+U32 LLDrawable::getMinFrameRange() const
{
- if (mVisible == sCurVisible)
- {
- return TRUE;
- }
-
-#if 0
- //disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result.
- //should be safe to just always ask the spatial group for visibility.
- if (isActive())
- {
- if (isRoot())
- {
- LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() :
- getSpatialGroup();
- if (group && group->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
- else
- {
- if (getParent()->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
- }
- else
-#endif
- {
- LLSpatialGroup* group = getSpatialGroup();
- if (group && group->isVisible())
- {
- mVisible = sCurVisible;
- return TRUE;
- }
- }
+ const U32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
- return FALSE;
+ return MIN_VIS_FRAME_RANGE ;
}
//=======================================
// Spatial Partition Bridging Drawable
//=======================================
-LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
-: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
+LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
+ LLDrawable(root->getVObj(), true),
+ LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
{
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
- mBinIndex = -1;
-
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1181,10 +1180,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
LLSpatialBridge::~LLSpatialBridge()
{
+ if(mEntry)
+ {
LLSpatialGroup* group = getSpatialGroup();
if (group)
{
- group->mSpatialPartition->remove(this, group);
+ group->getSpatialPartition()->remove(this, group);
+ }
}
//delete octree here so listeners will still be able to access bridge specific state
@@ -1206,8 +1208,9 @@ void LLSpatialBridge::updateSpatialExtents()
root->rebound();
}
+ const LLVector4a* root_bounds = root->getBounds();
LLVector4a offset;
- LLVector4a size = root->mBounds[1];
+ LLVector4a size = root_bounds[1];
//VECTORIZE THIS
LLMatrix4a mat;
@@ -1219,7 +1222,7 @@ void LLSpatialBridge::updateSpatialExtents()
LLVector4a center;
mat.affineTransform(t, center);
- mat.rotate(root->mBounds[0], offset);
+ mat.rotate(root_bounds[0], offset);
center.add(offset);
LLVector4a v[4];
@@ -1241,12 +1244,9 @@ void LLSpatialBridge::updateSpatialExtents()
scale.mul(size);
mat.rotate(scale, v[3]);
-
- LLVector4a& newMin = mExtents[0];
- LLVector4a& newMax = mExtents[1];
-
+ LLVector4a newMin;
+ LLVector4a newMax;
newMin = newMax = center;
-
for (U32 i = 0; i < 4; i++)
{
LLVector4a delta;
@@ -1259,19 +1259,21 @@ void LLSpatialBridge::updateSpatialExtents()
newMin.setMin(newMin, min);
newMax.setMax(newMax, max);
}
+ setSpatialExtents(newMin, newMax);
LLVector4a diagonal;
diagonal.setSub(newMax, newMin);
mRadius = diagonal.getLength3().getF32() * 0.5f;
- mPositionGroup.setAdd(newMin,newMax);
- mPositionGroup.mul(0.5f);
+ LLVector4a& pos = getGroupPosition();
+ pos.setAdd(newMin,newMax);
+ pos.mul(0.5f);
updateBinRadius();
}
void LLSpatialBridge::updateBinRadius()
{
- mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f);
+ setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));
}
LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
@@ -1305,7 +1307,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
{
- mVisible = sCurVisible;
+ LLViewerOctreeEntryData::setVisible();
#if 0 && !LL_RELEASE_FOR_DOWNLOAD
//crazy paranoid rules checking
@@ -1340,21 +1342,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,
#endif
}
-class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable>
+class LLOctreeMarkNotCulled: public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { }
- virtual void traverse(const LLOctreeNode<LLDrawable>* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
group->setVisible();
- LLOctreeTraveler<LLDrawable>::traverse(node);
+ OctreeTraveler::traverse(node);
}
- void visit(const LLOctreeNode<LLDrawable>* branch)
+ void visit(const OctreeNode* branch)
{
gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera);
}
@@ -1398,7 +1400,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
}
if (!group ||
- LLDrawable::getCurrentFrame() - av->mVisible > 1 ||
+ LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||
impostor ||
!loaded)
{
@@ -1412,16 +1414,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
group->rebound();
LLVector4a center;
- center.setAdd(mExtents[0], mExtents[1]);
+ const LLVector4a* exts = getSpatialExtents();
+ center.setAdd(exts[0], exts[1]);
center.mul(0.5f);
LLVector4a size;
- size.setSub(mExtents[1], mExtents[0]);
+ size.setSub(exts[1], exts[0]);
size.mul(0.5f);
if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||
LLPipeline::sImpostorRender ||
(camera_in.AABBInFrustumNoFarClip(center, size) &&
- AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
+ AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))
{
if (!LLPipeline::sImpostorRender &&
!LLPipeline::sShadowRender &&
@@ -1536,9 +1539,7 @@ BOOL LLSpatialBridge::updateMove()
void LLSpatialBridge::shiftPos(const LLVector4a& vec)
{
- mExtents[0].add(vec);
- mExtents[1].add(vec);
- mPositionGroup.add(vec);
+ LLDrawable::shift(vec);
}
void LLSpatialBridge::cleanupReferences()
@@ -1546,11 +1547,8 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
- /*
-
- DON'T DO THIS -- this should happen through octree destruction
+ mDrawable->setGroup(NULL);
- mDrawable->setSpatialGroup(NULL);
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1561,10 +1559,10 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
- drawable->setSpatialGroup(NULL);
+ drawable->setGroup(NULL);
+ }
}
}
- }*/
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1633,8 +1631,8 @@ void LLDrawable::updateFaceSize(S32 idx)
}
}
-LLBridgePartition::LLBridgePartition()
-: LLSpatialPartition(0, FALSE, 0)
+LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
+: LLSpatialPartition(0, FALSE, 0, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
@@ -1642,8 +1640,8 @@ LLBridgePartition::LLBridgePartition()
mSlopRatio = 0.25f;
}
-LLHUDBridge::LLHUDBridge(LLDrawable* drawablep)
-: LLVolumeBridge(drawablep)
+LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+: LLVolumeBridge(drawablep, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_HUD;
mPartitionType = LLViewerRegion::PARTITION_HUD;
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index c3f6d77edc..b7c5aeb5a8 100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -42,6 +42,7 @@
#include "llviewerobject.h"
#include "llrect.h"
#include "llappviewer.h" // for gFrameTimeSeconds
+#include "llvieweroctree.h"
class LLCamera;
class LLDrawPool;
@@ -59,10 +60,12 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
LL_ALIGN_PREFIX(16)
-class LLDrawable : public LLRefCount
+class LLDrawable
+: public LLViewerOctreeEntryData,
+ public LLTrace::MemTrackable<LLDrawable>
{
public:
- LLDrawable(const LLDrawable& rhs)
+ LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs)
{
*this = rhs;
}
@@ -75,17 +78,7 @@ public:
static void initClass();
- void* operator new(size_t size)
- {
- return ll_aligned_malloc_16(size);
- }
-
- void operator delete(void* ptr)
- {
- ll_aligned_free_16(ptr);
- }
-
- LLDrawable() { init(); }
+ LLDrawable(LLViewerObject *vobj, bool new_entry = false);
void markDead(); // Mark this drawable as dead
BOOL isDead() const { return isState(DEAD); }
@@ -93,11 +86,9 @@ public:
BOOL isLight() const;
- BOOL isVisible() const;
- BOOL isRecentlyVisible() const;
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
-
+ LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();}
LLViewerRegion* getRegion() const { return mVObjp->getRegion(); }
const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }
LLPointer<LLViewerObject>& getVObj() { return mVObjp; }
@@ -110,16 +101,12 @@ public:
const LLVector3& getPosition() const { return mXform.getPosition(); }
const LLVector3& getWorldPosition() const { return mXform.getPositionW(); }
const LLVector3 getPositionAgent() const;
- const LLVector4a& getPositionGroup() const { return mPositionGroup; }
const LLVector3& getScale() const { return mCurrentScale; }
void setScale(const LLVector3& scale) { mCurrentScale = scale; }
const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); }
const LLQuaternion& getRotation() const { return mXform.getRotation(); }
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
- F32 getBinRadius() const { return mBinRadius; }
- S32 getBinIndex() const { return mBinIndex; }
- void setBinIndex(S32 index) const { mBinIndex = index; }
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
LLXformMatrix* getXform() { return &mXform; }
@@ -152,7 +139,7 @@ public:
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
void mergeFaces(LLDrawable* src);
- void init();
+ void init(bool new_entry);
void destroy();
void update();
@@ -183,8 +170,12 @@ public:
BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; }
void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); }
+ bool isVisible() const;
+ bool isRecentlyVisible() const;
+
virtual void cleanupReferences();
+ void setGroup(LLviewerOctreeGroup* group);
void setRadius(const F32 radius);
F32 getRadius() const { return mRadius; }
F32 getVisibilityRadius() const;
@@ -194,11 +185,6 @@ public:
const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;
virtual void updateSpatialExtents();
virtual void updateBinRadius();
- const LLVector4a* getSpatialExtents() const;
- void setSpatialExtents(const LLVector3& min, const LLVector3& max);
- void setSpatialExtents(const LLVector4a& min, const LLVector4a& max);
-
- void setPositionGroup(const LLVector4a& pos);
void setRenderType(S32 type) { mRenderType = type; }
BOOL isRenderType(S32 type) { return mRenderType == type; }
@@ -207,10 +193,14 @@ public:
// Debugging methods
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
- void setSpatialGroup(LLSpatialGroup *groupp);
- LLSpatialGroup *getSpatialGroup() const;
LLSpatialPartition* getSpatialPartition();
+ virtual U32 getMinFrameRange()const;
+ void removeFromOctree();
+
+ void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
+ LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
+
// Statics
static void incrementVisible();
static void cleanupDeadDrawables();
@@ -294,10 +284,6 @@ public:
ACTIVE_CHILD = 0x40000000,
} EDrawableFlags;
-private: //aligned members
- LL_ALIGN_16(LLVector4a mExtents[2]);
- LL_ALIGN_16(LLVector4a mPositionGroup);
-
public:
LLXformMatrix mXform;
@@ -306,13 +292,8 @@ public:
F32 mDistanceWRTCamera;
- static S32 getCurrentFrame() { return sCurVisible; }
- static S32 getMinVisFrameRange();
-
- void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
- LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }
-
static F32 sCurPixelAngle; //current pixels per radian
+ static LLTrace::MemStatHandle sMemStat;
private:
typedef std::vector<LLFace*> face_list_t;
@@ -321,21 +302,15 @@ private:
S32 mRenderType;
LLPointer<LLViewerObject> mVObjp;
face_list_t mFaces;
- LLSpatialGroup* mSpatialGroupp;
LLPointer<LLDrawable> mSpatialBridge;
- mutable U32 mVisible;
F32 mRadius;
- F32 mBinRadius;
- mutable S32 mBinIndex;
S32 mGeneration;
LLVector3 mCurrentScale;
- static U32 sCurVisible; // Counter for what value of mVisible means currently visible
-
static U32 sNumZombieDrawables;
- static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
+ static LLDynamicArray<LLPointer<LLDrawable>, 32> sDeadList;
} LL_ALIGN_POSTFIX(16);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index c832e1401d..0fed6d1d17 100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -191,7 +191,7 @@ void LLDrawPoolAlpha::render(S32 pass)
{
gGL.setColorMask(true, true);
}
-
+
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
@@ -288,7 +288,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (group->mSpatialPartition->mRenderByGroup &&
+ if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -326,15 +326,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
LLSpatialGroup* group = *i;
llassert(group);
- llassert(group->mSpatialPartition);
+ llassert(group->getSpatialPartition());
- if (group->mSpatialPartition->mRenderByGroup &&
+ if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
// All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
- group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
+ group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
+ group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -349,14 +349,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
LLRenderPass::applyModelMatrix(params);
-
+
LLMaterial* mat = NULL;
if (deferred_render && !LLPipeline::sUnderWaterRender)
{
mat = params.mMaterial;
}
-
+
if (params.mFullbright)
{
// Turn off lighting if it hasn't already been so.
@@ -421,7 +421,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLGLSLShader::bindNoShader();
current_shader = NULL;
}
-
+
if (use_shaders && mat)
{
// We have a material. Supply the appropriate data here.
@@ -471,7 +471,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
}
- else
+ else
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTexture.notNull())
{
@@ -482,7 +482,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
else
{
- gGL.getTexUnit(0)->bind(params.mTexture, TRUE);
+ gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
}
if (params.mTextureMatrix)
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 075299386e..c3afe63bdd 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -463,7 +463,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
if (pass == 0)
{
- avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
+ avatarp->renderSkinned();
}
else
{
@@ -905,10 +905,10 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightProgram;
- }
+ sVertexProgram = &gSkinnedObjectFullbrightProgram;
}
}
+ }
else
{
if (LLPipeline::sUnderWaterRender)
@@ -1006,10 +1006,10 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
else
{
- sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
- }
+ sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
}
}
+ }
else
{
if (LLPipeline::sUnderWaterRender)
@@ -1381,7 +1381,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
case 10: p = 5; break;
case 11: p = 9; break;
case 12: p = 13; break;
- }
+ }
{
LLGLEnable blend(GL_BLEND);
@@ -1430,7 +1430,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if( !single_avatar || (avatarp == single_avatar) )
{
- avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
+ avatarp->renderSkinned();
}
}
@@ -1743,12 +1743,12 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
}
else
{
- gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
+ gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
sVertexProgram->setMinimumAlpha(0.f);
- if (normal_channel > -1)
- {
- LLDrawPoolBump::bindBumpMap(face, normal_channel);
- }
+ if (normal_channel > -1)
+ {
+ LLDrawPoolBump::bindBumpMap(face, normal_channel);
+ }
}
if (face->mTextureMatrix)
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 5ddc15df42..9a5743919d 100755
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -463,7 +463,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
gGL.getTexUnit(0)->bind(mHBTex[dr]);
- LLOverrideFaceColor override(this, face->getFaceColor().mV);
+ LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
face->renderIndexed();
}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index f021f4ed0f..94f06eb1d0 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -209,7 +209,7 @@ void LLFace::destroy()
}
setDrawInfo(NULL);
-
+
mDrawablep = NULL;
mVObjp = NULL;
}
@@ -313,14 +313,14 @@ void LLFace::dirtyTexture()
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
- { //dirty texture on an alpha object should be treated as an LoD update
- LLVOVolume* vobj = drawablep->getVOVolume();
- if (vobj)
- {
- vobj->mLODChanged = TRUE;
- }
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
- }
+ { //dirty texture on an alpha object should be treated as an LoD update
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj)
+ {
+ vobj->mLODChanged = TRUE;
+ }
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
+ }
}
}
@@ -348,7 +348,7 @@ void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
if (ch == LLRender::DIFFUSE_MAP)
{
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
}
setTexture(ch, new_texture) ;
@@ -947,7 +947,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
planarProjection(tc, volume_normal, center, volume_position);
- }
+ }
}
if (mTextureMatrix) // if we have a texture matrix, use it
@@ -1288,7 +1288,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{ //decide if shiny goes in alpha channel of color
if (tep &&
getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
- {
+ {
LLMaterial* mat = tep->getMaterialParams().get();
bool shiny_in_alpha = false;
@@ -1309,15 +1309,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
if (shiny_in_alpha)
- {
+ {
- GLfloat alpha[4] =
- {
- 0.00f,
- 0.25f,
- 0.5f,
- 0.75f
- };
+ GLfloat alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
llassert(tep->getShiny() <= 3);
color.mV[3] = U8 (alpha[tep->getShiny()] * 255);
@@ -1621,8 +1621,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool tex_anim = false;
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
+ LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
+ tex_mode = vobj->mTexAnimMode;
if (vobj->mTextureAnimp)
{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
@@ -1645,7 +1645,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
do_xform = false;
}
-
+
if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
{ //don't override texture transform during tc bake
tex_mode = 0;
@@ -1666,7 +1666,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
bool do_tex_mat = tex_mode && mTextureMatrix;
-
+
if (!do_bump)
{ //not bump mapped, might be able to do a cheap update
mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount);
@@ -1783,9 +1783,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
else
{ //bump mapped or has material, just do the whole expensive loop
LLFastTimer t(FTM_FACE_TEX_DEFAULT);
-
- std::vector<LLVector2> bump_tc;
+ std::vector<LLVector2> bump_tc;
+
if (mat && !mat->getNormalID().isNull())
{ //writing out normal and specular texture coordinates, not bump offsets
do_bump = false;
@@ -1842,45 +1842,45 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
+ LLVector4a& center = *(vf.mCenter);
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a vec = vf.mPositions[i];
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
+ vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
- {
+ {
planarProjection(tc, norm, center, vec);
- }
- }
+ }
+ }
- if (tex_mode && mTextureMatrix)
- {
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- }
- else
- {
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- }
+ if (tex_mode && mTextureMatrix)
+ {
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ }
+ else
+ {
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ }
*dst++ = tc;
- if (do_bump)
- {
- bump_tc.push_back(tc);
- }
+ if (do_bump)
+ {
+ bump_tc.push_back(tc);
}
}
+ }
if (map_range)
{
@@ -1898,7 +1898,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a binorm;
binorm.setCross3(vf.mNormals[i], tangent);
binorm.mul(tangent.getF32ptr()[3]);
-
+
LLMatrix4a tangent_to_object;
tangent_to_object.setRows(tangent, binorm, vf.mNormals[i]);
LLVector4a t;
@@ -2029,9 +2029,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4Logical mask;
mask.clear();
mask.setElement<3>();
-
+
for (S32 i = 0; i < num_vertices; i++)
- {
+ {
LLVector4a tangent_out;
mat_normal.rotate(vf.mTangents[i], tangent_out);
tangent_out.normalize3fast();
@@ -2104,7 +2104,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U glow4u = LLColor4U(0,0,0,glow);
U32 glow32 = glow4u.mAll;
-
+
U32 vec[4];
vec[0] = vec[1] = vec[2] = vec[3] = glow32;
@@ -2249,7 +2249,7 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
dist *= 16.f;
}
- lookAt.normalize3fast();
+ lookAt.normalize3fast() ;
//get area of circle around node
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
@@ -2349,8 +2349,6 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
return 0.f ;
}
- //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ;
-
S32 i = 0 ;
for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);
i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 0687544d53..c4832b67cd 100755
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -28,7 +28,6 @@
#define LL_LLFACE_H
#include "llstrider.h"
-
#include "llrender.h"
#include "v2math.h"
#include "v3math.h"
@@ -37,7 +36,6 @@
#include "v4coloru.h"
#include "llquaternion.h"
#include "xform.h"
-#include "lldarrayptr.h"
#include "llvertexbuffer.h"
#include "llviewertexture.h"
#include "lldrawable.h"
@@ -49,6 +47,8 @@ class LLTextureEntry;
class LLVertexProgram;
class LLViewerTexture;
class LLGeometryManager;
+class LLTextureAtlasSlot;
+class LLDrawInfo;
const F32 MIN_ALPHA_SIZE = 1024.f;
const F32 MIN_TEX_ANIM_SIZE = 512.f;
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index fbf72b1a85..d3a97fde0e 100755
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -30,12 +30,14 @@
#include "llviewerwindow.h"
#include "llrect.h"
+#include "llcombobox.h"
#include "llerror.h"
#include "llgl.h"
#include "llimagepng.h"
#include "llrender.h"
#include "llrendertarget.h"
#include "lllocalcliprect.h"
+#include "lllayoutstack.h"
#include "llmath.h"
#include "llfontgl.h"
#include "llsdserialize.h"
@@ -46,7 +48,6 @@
#include "llviewertexturelist.h"
#include "llui.h"
#include "llviewercontrol.h"
-#include "llstat.h"
#include "llfasttimer.h"
#include "lltreeiterators.h"
@@ -55,24 +56,25 @@
//////////////////////////////////////////////////////////////////////////////
-static const S32 MAX_VISIBLE_HISTORY = 10;
-static const S32 LINE_GRAPH_HEIGHT = 240;
+using namespace LLTrace;
-//static const int FTV_DISPLAY_NUM = (sizeof(ft_display_table)/sizeof(ft_display_table[0]));
-static S32 FTV_NUM_TIMERS;
-const S32 FTV_MAX_DEPTH = 8;
+static const S32 MAX_VISIBLE_HISTORY = 12;
+static const S32 LINE_GRAPH_HEIGHT = 240;
+static const S32 MIN_BAR_HEIGHT = 3;
+static const S32 RUNNING_AVERAGE_WIDTH = 100;
+static const S32 NUM_FRAMES_HISTORY = 256;
-std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse)
+std::vector<TimeBlock*> ft_display_idx; // line of table entry for display purposes (for collapse)
-typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t;
+typedef LLTreeDFSIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_iterator_t;
BOOL LLFastTimerView::sAnalyzePerformance = FALSE;
-static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+static timer_tree_iterator_t begin_timer_tree(TimeBlock& id)
{
return timer_tree_iterator_t(&id,
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
- boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+ boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),
+ boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));
}
static timer_tree_iterator_t end_timer_tree()
@@ -80,37 +82,61 @@ static timer_tree_iterator_t end_timer_tree()
return timer_tree_iterator_t();
}
+S32 get_depth(const TimeBlock* blockp)
+{
+ S32 depth = 0;
+ TimeBlock* timerp = blockp->getParent();
+ while(timerp)
+ {
+ depth++;
+ if (timerp->getParent() == timerp) break;
+ timerp = timerp->getParent();
+ }
+ return depth;
+}
+
LLFastTimerView::LLFastTimerView(const LLSD& key)
: LLFloater(key),
- mHoverTimer(NULL)
+ mHoverTimer(NULL),
+ mDisplayMode(0),
+ mDisplayType(DISPLAY_TIME),
+ mScrollIndex(0),
+ mHoverID(NULL),
+ mHoverBarIndex(-1),
+ mStatsIndex(-1),
+ mPauseHistory(false),
+ mRecording(NUM_FRAMES_HISTORY)
+{
+ mTimerBarRows.resize(NUM_FRAMES_HISTORY);
+}
+
+LLFastTimerView::~LLFastTimerView()
{
- mDisplayMode = 0;
- mAvgCountTotal = 0;
- mMaxCountTotal = 0;
- mDisplayCenter = ALIGN_CENTER;
- mDisplayCalls = 0;
- mDisplayHz = 0;
- mScrollIndex = 0;
- mHoverID = NULL;
- mHoverBarIndex = -1;
- FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
- mPrintStats = -1;
}
void LLFastTimerView::onPause()
{
- LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
+ setPauseState(!mPauseHistory);
+}
+
+void LLFastTimerView::setPauseState(bool pause_state)
+{
+ if (pause_state == mPauseHistory) return;
+
// reset scroll to bottom when unpausing
- if (!LLFastTimer::sPauseHistory)
+ if (!pause_state)
{
- mScrollIndex = 0;
- LLFastTimer::sResetHistory = true;
+
getChild<LLButton>("pause_btn")->setLabel(getString("pause"));
}
else
{
+ mScrollIndex = 0;
+
getChild<LLButton>("pause_btn")->setLabel(getString("run"));
}
+
+ mPauseHistory = pause_state;
}
BOOL LLFastTimerView::postBuild()
@@ -126,13 +152,13 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
if (mHoverTimer )
{
// right click collapses timers
- if (!mHoverTimer->getCollapsed())
+ if (!mHoverTimer->getTreeNode().mCollapsed)
{
- mHoverTimer->setCollapsed(true);
+ mHoverTimer->getTreeNode().mCollapsed = true;
}
else if (mHoverTimer->getParent())
{
- mHoverTimer->getParent()->setCollapsed(true);
+ mHoverTimer->getParent()->getTreeNode().mCollapsed = true;
}
return TRUE;
}
@@ -140,15 +166,15 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
- mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx;
+ mStatsIndex = mScrollIndex + bar_idx;
return TRUE;
}
return LLFloater::handleRightMouseDown(x, y, mask);
}
-LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
+TimeBlock* LLFastTimerView::getLegendID(S32 y)
{
- S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5;
+ S32 idx = (mLegendRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight() + 2);
if (idx >= 0 && idx < (S32)ft_display_idx.size())
{
@@ -160,11 +186,11 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)
{
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
+ for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
it != end_timer_tree();
++it)
{
- (*it)->setCollapsed(false);
+ (*it)->getTreeNode().mCollapsed = false;
}
return TRUE;
}
@@ -173,52 +199,23 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (x < mBarRect.mLeft)
{
- LLFastTimer::NamedTimer* idp = getLegendID(y);
+ TimeBlock* idp = getLegendID(y);
if (idp)
{
- idp->setCollapsed(!idp->getCollapsed());
+ idp->getTreeNode().mCollapsed = !idp->getTreeNode().mCollapsed;
}
}
else if (mHoverTimer)
{
//left click drills down by expanding timers
- mHoverTimer->setCollapsed(false);
- }
- else if (mask & MASK_ALT)
- {
- if (mask & MASK_CONTROL)
- {
- mDisplayHz = !mDisplayHz;
- }
- else
- {
- mDisplayCalls = !mDisplayCalls;
- }
- }
- else if (mask & MASK_SHIFT)
- {
- if (++mDisplayMode > 3)
- mDisplayMode = 0;
- }
- else if (mask & MASK_CONTROL)
- {
- mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
+ mHoverTimer->getTreeNode().mCollapsed = false;
}
else if (mGraphRect.pointInRect(x, y))
{
gFocusMgr.setMouseCapture(this);
return TRUE;
}
- //else
- //{
- // // pause/unpause
- // LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
- // // reset scroll to bottom when unpausing
- // if (!LLFastTimer::sPauseHistory)
- // {
- // mScrollIndex = 0;
- // }
- //}
+
return LLFloater::handleMouseDown(x, y, mask);
}
@@ -236,17 +233,21 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
if (hasMouseCapture())
{
F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f);
- mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
- mScrollIndex = llclamp( mScrollIndex, 0, LLFastTimer::getLastFrameIndex());
+ mScrollIndex = llround( lerp * (F32)(mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
+ mScrollIndex = llclamp( mScrollIndex, 0, (S32)mRecording.getNumRecordedPeriods());
return TRUE;
}
mHoverTimer = NULL;
mHoverID = NULL;
- if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
+ if(mPauseHistory && mBarRect.pointInRect(x, y))
{
- mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1,
- MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()));
+ //const S32 bars_top = mBarRect.mTop;
+ const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
+
+ mHoverBarIndex = llmin((bars_top - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1,
+ (S32)mRecording.getNumRecordedPeriods() - 1,
+ MAX_VISIBLE_HISTORY);
if (mHoverBarIndex == 0)
{
return TRUE;
@@ -256,40 +257,50 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
mHoverBarIndex = 0;
}
- S32 i = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != end_timer_tree();
- ++it, ++i)
+ TimerBarRow& row = mHoverBarIndex == 0 ? mAverageTimerRow : mTimerBarRows[mScrollIndex + mHoverBarIndex - 1];
+
+ TimerBar* hover_bar = NULL;
+ LLUnit<F32, LLUnits::Seconds> mouse_time_offset = ((F32)(x - mBarRect.mLeft) / (F32)mBarRect.getWidth()) * mTotalTimeDisplay;
+ for (int bar_index = 0, end_index = LLInstanceTracker<LLTrace::TimeBlock>::instanceCount();
+ bar_index < end_index;
+ ++bar_index)
{
- // is mouse over bar for this timer?
- if (x > mBarStart[mHoverBarIndex][i] &&
- x < mBarEnd[mHoverBarIndex][i])
+ TimerBar& bar = row.mBars[bar_index];
+ if (bar.mSelfStart > mouse_time_offset)
+ {
+ break;
+ }
+ if (bar.mSelfEnd > mouse_time_offset)
{
- mHoverID = (*it);
- if (mHoverTimer != *it)
+ hover_bar = &bar;
+ if (bar.mTimeBlock->getTreeNode().mCollapsed)
+ {
+ // stop on first collapsed timeblock, since we can't select any children
+ break;
+ }
+ }
+ }
+
+ if (hover_bar)
+ {
+ mHoverID = hover_bar->mTimeBlock;
+ if (mHoverTimer != mHoverID)
{
// could be that existing tooltip is for a parent and is thus
// covering region for this new timer, go ahead and unblock
// so we can create a new tooltip
LLToolTipMgr::instance().unblockToolTips();
- mHoverTimer = (*it);
- }
-
- mToolTipRect.set(mBarStart[mHoverBarIndex][i],
- mBarRect.mBottom + llround(((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex + 1)) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))),
- mBarEnd[mHoverBarIndex][i],
- mBarRect.mBottom + llround((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))));
- }
-
- if ((*it)->getCollapsed())
- {
- it.skipDescendants();
+ mHoverTimer = mHoverID;
+ mToolTipRect.set(mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth(),
+ row.mTop,
+ mBarRect.mLeft + (hover_bar->mSelfEnd / mTotalTimeDisplay) * mBarRect.getWidth(),
+ row.mBottom);
}
}
}
else if (x < mBarRect.mLeft)
{
- LLFastTimer::NamedTimer* timer_id = getLegendID(y);
+ TimeBlock* timer_id = getLegendID(y);
if (timer_id)
{
mHoverID = timer_id;
@@ -300,9 +311,24 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
}
+static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicRecording& frame_recording)
+{
+ std::string tooltip;
+ if (history_index == 0)
+ {
+ // by default, show average number of call
+ tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<F64, LLUnits::Milliseconds>(frame_recording.getPeriodMean (timer, RUNNING_AVERAGE_WIDTH)).value(), (S32)frame_recording.getPeriodMean(timer.callCount(), RUNNING_AVERAGE_WIDTH));
+ }
+ else
+ {
+ tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<F64, LLUnits::Milliseconds>(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount()));
+ }
+ return tooltip;
+}
+
BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
{
- if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
+ if(mPauseHistory && mBarRect.pointInRect(x, y))
{
// tooltips for timer bars
if (mHoverTimer)
@@ -310,8 +336,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
LLRect screen_rect;
localRectToScreen(mToolTipRect, &screen_rect);
+ std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, mRecording);
+
LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex))
+ .message(tooltip)
.sticky_rect(screen_rect)
.delay_time(0.f));
@@ -323,10 +351,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
// tooltips for timer legend
if (x < mBarRect.mLeft)
{
- LLFastTimer::NamedTimer* idp = getLegendID(y);
+ TimeBlock* idp = getLegendID(y);
if (idp)
{
- LLToolTipMgr::instance().show(idp->getToolTip());
+ LLToolTipMgr::instance().show(get_tooltip(*idp, 0, mRecording));
return TRUE;
}
@@ -338,706 +366,83 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- LLFastTimer::sPauseHistory = TRUE;
+ setPauseState(true);
mScrollIndex = llclamp( mScrollIndex + clicks,
0,
- llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
+ llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY));
return TRUE;
}
-static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true);
+static TimeBlock FTM_RENDER_TIMER("Timers");
+static const S32 MARGIN = 10;
+static const S32 LEGEND_WIDTH = 220;
-static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors;
+static std::vector<LLColor4> sTimerColors;
void LLFastTimerView::draw()
{
LLFastTimer t(FTM_RENDER_TIMER);
- std::string tdesc;
-
- F64 clock_freq = (F64)LLFastTimer::countsPerSecond();
- F64 iclock_freq = 1000.0 / clock_freq;
-
- S32 margin = 10;
- S32 height = getRect().getHeight();
- S32 width = getRect().getWidth();
-
- LLRect new_rect;
- new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
- setRect(new_rect);
-
- S32 left, top, right, bottom;
- S32 x, y, barw, barh, dx, dy;
- S32 texth;
- LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");
-
- // Draw the window background
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
-
- S32 xleft = margin;
- S32 ytop = margin;
-
- // Draw some help
+ if (!mPauseHistory)
{
-
- x = xleft;
- y = height - ytop;
- texth = (S32)LLFontGL::getFontMonospace()->getLineHeight();
-
- char modedesc[][32] = {
- "2 x Average ",
- "Max ",
- "Recent Max ",
- "100 ms "
- };
- char centerdesc[][32] = {
- "Left ",
- "Centered ",
- "Ordered "
- };
-
- tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-
- x = xleft, y -= (texth + 2);
- tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
- y -= (texth + 2);
-
- LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"),
- 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
- y -= (texth + 2);
+ mRecording.appendRecording(LLTrace::get_frame_recording().getLastRecording());
+ mTimerBarRows.pop_back();
+ mTimerBarRows.push_front(TimerBarRow());
}
- S32 histmax = llmin(LLFastTimer::getLastFrameIndex()+1, MAX_VISIBLE_HISTORY);
+ mDisplayMode = llclamp(getChild<LLComboBox>("time_scale_combo")->getCurrentIndex(), 0, 3);
+ mDisplayType = (EDisplayType)llclamp(getChild<LLComboBox>("metric_combo")->getCurrentIndex(), 0, 2);
- // Draw the legend
- xleft = margin;
- ytop = y;
+ generateUniqueColors();
- y -= (texth + 2);
-
- sTimerColors[&getFrameTimer()] = LLColor4::grey;
-
- F32 hue = 0.f;
+ LLView::drawChildren();
+ //getChild<LLLayoutStack>("timer_bars_stack")->updateLayout();
+ //getChild<LLLayoutStack>("legend_stack")->updateLayout();
+ LLView* bars_panel = getChildView("bars_panel");
+ bars_panel->localRectToOtherView(bars_panel->getLocalRect(), &mBarRect, this);
- for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != timer_tree_iterator_t();
- ++it)
- {
- LLFastTimer::NamedTimer* idp = (*it);
+ LLView* lines_panel = getChildView("lines_panel");
+ lines_panel->localRectToOtherView(lines_panel->getLocalRect(), &mGraphRect, this);
- const F32 HUE_INCREMENT = 0.23f;
- hue = fmodf(hue + HUE_INCREMENT, 1.f);
- // saturation increases with depth
- F32 saturation = clamp_rescale((F32)idp->getDepth(), 0.f, 3.f, 0.f, 1.f);
- // lightness alternates with depth
- F32 lightness = idp->getDepth() % 2 ? 0.5f : 0.6f;
+ LLView* legend_panel = getChildView("legend");
+ legend_panel->localRectToOtherView(legend_panel->getLocalRect(), &mLegendRect, this);
- LLColor4 child_color;
- child_color.setHSL(hue, saturation, lightness);
-
- sTimerColors[idp] = child_color;
- }
-
- const S32 LEGEND_WIDTH = 220;
- {
- LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin));
- S32 cur_line = 0;
- ft_display_idx.clear();
- std::map<LLFastTimer::NamedTimer*, S32> display_line;
- for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != timer_tree_iterator_t();
- ++it)
- {
- LLFastTimer::NamedTimer* idp = (*it);
- display_line[idp] = cur_line;
- ft_display_idx.push_back(idp);
- cur_line++;
-
- x = xleft;
-
- left = x; right = x + texth;
- top = y; bottom = y - texth;
- S32 scale_offset = 0;
- if (idp == mHoverID)
- {
- scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
- }
- gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, sTimerColors[idp]);
-
- F32 ms = 0;
- S32 calls = 0;
- if (mHoverBarIndex > 0 && mHoverID)
- {
- S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex;
- U64 ticks = idp->getHistoricalCount(hidx);
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)idp->getHistoricalCalls(hidx);
- }
- else
- {
- U64 ticks = idp->getCountAverage();
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)idp->getCallAverage();
- }
-
- if (mDisplayCalls)
- {
- tdesc = llformat("%s (%d)",idp->getName().c_str(),calls);
- }
- else
- {
- tdesc = llformat("%s [%.1f]",idp->getName().c_str(),ms);
- }
- dx = (texth+4) + idp->getDepth()*8;
-
- LLColor4 color = LLColor4::white;
- if (idp->getDepth() > 0)
- {
- S32 line_start_y = (top + bottom) / 2;
- S32 line_end_y = line_start_y + ((texth + 2) * (cur_line - display_line[idp->getParent()])) - texth;
- gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
- S32 line_x = x + (texth + 4) + ((idp->getDepth() - 1) * 8);
- gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
- if (idp->getCollapsed() && !idp->getChildren().empty())
- {
- gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
- }
- }
-
- x += dx;
- BOOL is_child_of_hover_item = (idp == mHoverID);
- LLFastTimer::NamedTimer* next_parent = idp->getParent();
- while(!is_child_of_hover_item && next_parent)
- {
- is_child_of_hover_item = (mHoverID == next_parent);
- if (next_parent->getParent() == next_parent) break;
- next_parent = next_parent->getParent();
- }
-
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0,
- x, y,
- color,
- LLFontGL::LEFT, LLFontGL::TOP,
- is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL);
-
- y -= (texth + 2);
-
- if (idp->getCollapsed())
- {
- it.skipDescendants();
- }
- }
- }
-
- xleft += LEGEND_WIDTH + 8;
- // ytop = ytop;
-
- // update rectangle that includes timer bars
- mBarRect.mLeft = xleft;
- mBarRect.mRight = getRect().getWidth();
- mBarRect.mTop = ytop - (LLFontGL::getFontMonospace()->getLineHeight() + 4);
- mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT;
-
- y = ytop;
- barh = (ytop - margin - LINE_GRAPH_HEIGHT) / (MAX_VISIBLE_HISTORY + 2);
- dy = barh>>2; // spacing between bars
- if (dy < 1) dy = 1;
- barh -= dy;
- barw = width - xleft - margin;
-
- // Draw the history bars
- if (LLFastTimer::getLastFrameIndex() >= 0)
- {
- LLLocalClipRect clip(LLRect(xleft, ytop, getRect().getWidth() - margin, margin));
-
- U64 totalticks;
- if (!LLFastTimer::sPauseHistory)
- {
- U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex);
-
- if (LLFastTimer::getCurFrameIndex() >= 10)
- {
- U64 framec = LLFastTimer::getCurFrameIndex();
- U64 avg = (U64)mAvgCountTotal;
- mAvgCountTotal = (avg*framec + ticks) / (framec + 1);
- if (ticks > mMaxCountTotal)
- {
- mMaxCountTotal = ticks;
- }
- }
-
- if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100)
- {
- LLFastTimer::sResetHistory = true;
- }
-
- if (LLFastTimer::getCurFrameIndex() < 10 || LLFastTimer::sResetHistory)
- {
- mAvgCountTotal = ticks;
- mMaxCountTotal = ticks;
- LLFastTimer::sResetHistory = false;
- }
- }
-
- if (mDisplayMode == 0)
- {
- totalticks = mAvgCountTotal*2;
- }
- else if (mDisplayMode == 1)
- {
- totalticks = mMaxCountTotal;
- }
- else if (mDisplayMode == 2)
- {
- // Calculate the max total ticks for the current history
- totalticks = 0;
- for (S32 j=0; j<histmax; j++)
- {
- U64 ticks = getFrameTimer().getHistoricalCount(j);
-
- if (ticks > totalticks)
- totalticks = ticks;
- }
- }
- else
- {
- totalticks = (U64)(clock_freq * .1); // 100 ms
- }
-
- // Draw MS ticks
- {
- U32 ms = (U32)((F64)totalticks * iclock_freq) ;
-
- tdesc = llformat("%.1f ms |", (F32)ms*.25f);
- x = xleft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tdesc);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
-
- tdesc = llformat("%.1f ms |", (F32)ms*.50f);
- x = xleft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tdesc);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
-
- tdesc = llformat("%.1f ms |", (F32)ms*.75f);
- x = xleft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tdesc);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
-
- tdesc = llformat( "%d ms |", ms);
- x = xleft + barw - LLFontGL::getFontMonospace()->getWidth(tdesc);
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
- }
-
- // Draw borders
- {
+ // Draw the window background
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4f(0.5f,0.5f,0.5f,0.5f);
-
- S32 by = y + 2;
-
- y -= ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
+ gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f));
- //heading
- gl_rect_2d(xleft-5, by, getRect().getWidth()-5, y+5, FALSE);
-
- //tree view
- gl_rect_2d(5, by, xleft-10, 5, FALSE);
-
- by = y + 5;
- //average bar
- gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-5, FALSE);
-
- by -= barh*2+dy;
-
- //current frame bar
- gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-2, FALSE);
-
- by -= barh+dy+1;
-
- //history bars
- gl_rect_2d(xleft-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE);
-
- by = LINE_GRAPH_HEIGHT-barh-dy-7;
-
- //line graph
- mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
-
- gl_rect_2d(mGraphRect, FALSE);
- }
-
- mBarStart.clear();
- mBarEnd.clear();
-
- // Draw bars for each history entry
- // Special: -1 = show running average
- gGL.getTexUnit(0)->bind(box_imagep->getImage());
- for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++)
- {
- mBarStart.push_back(std::vector<S32>());
- mBarEnd.push_back(std::vector<S32>());
- int sublevel_dx[FTV_MAX_DEPTH];
- int sublevel_left[FTV_MAX_DEPTH];
- int sublevel_right[FTV_MAX_DEPTH];
- S32 tidx;
- if (j >= 0)
- {
- tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex;
- }
- else
- {
- tidx = -1;
- }
-
- x = xleft;
+ drawHelp(getRect().getHeight() - MARGIN);
+ drawLegend();
- // draw the bars for each stat
- std::vector<S32> xpos;
- std::vector<S32> deltax;
- xpos.push_back(xleft);
-
- LLFastTimer::NamedTimer* prev_id = NULL;
-
- S32 i = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != end_timer_tree();
- ++it, ++i)
- {
- LLFastTimer::NamedTimer* idp = (*it);
- F32 frac = tidx == -1
- ? (F32)idp->getCountAverage() / (F32)totalticks
- : (F32)idp->getHistoricalCount(tidx) / (F32)totalticks;
-
- dx = llround(frac * (F32)barw);
- S32 prev_delta_x = deltax.empty() ? 0 : deltax.back();
- deltax.push_back(dx);
-
- int level = idp->getDepth() - 1;
-
- while ((S32)xpos.size() > level + 1)
- {
- xpos.pop_back();
- }
- left = xpos.back();
-
- if (level == 0)
- {
- sublevel_left[level] = xleft;
- sublevel_dx[level] = dx;
- sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
- }
- else if (prev_id && prev_id->getDepth() < idp->getDepth())
- {
- U64 sublevelticks = 0;
-
- for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren();
- it != prev_id->endChildren();
- ++it)
- {
- sublevelticks += (tidx == -1)
- ? (*it)->getCountAverage()
- : (*it)->getHistoricalCount(tidx);
- }
-
- F32 subfrac = (F32)sublevelticks / (F32)totalticks;
- sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f);
-
- if (mDisplayCenter == ALIGN_CENTER)
- {
- left += (prev_delta_x - sublevel_dx[level])/2;
- }
- else if (mDisplayCenter == ALIGN_RIGHT)
- {
- left += (prev_delta_x - sublevel_dx[level]);
- }
-
- sublevel_left[level] = left;
- sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
- }
-
- right = left + dx;
- xpos.back() = right;
- xpos.push_back(left);
-
- mBarStart.back().push_back(left);
- mBarEnd.back().push_back(right);
-
- top = y;
- bottom = y - barh;
-
- if (right > left)
- {
- //U32 rounded_edges = 0;
- LLColor4 color = sTimerColors[idp];//*ft_display_table[i].color;
- S32 scale_offset = 0;
-
- BOOL is_child_of_hover_item = (idp == mHoverID);
- LLFastTimer::NamedTimer* next_parent = idp->getParent();
- while(!is_child_of_hover_item && next_parent)
- {
- is_child_of_hover_item = (mHoverID == next_parent);
- if (next_parent->getParent() == next_parent) break;
- next_parent = next_parent->getParent();
- }
+ //mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8;
+ //mBarRect.mTop = y;
+ //mBarRect.mRight = getRect().getWidth() - MARGIN;
+ //mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT;
+
+ drawBars();
+ drawLineGraph();
+ printLineStats();
+ LLView::draw();
- if (idp == mHoverID)
- {
- scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f);
- //color = lerp(color, LLColor4::black, -0.4f);
- }
- else if (mHoverID != NULL && !is_child_of_hover_item)
- {
- color = lerp(color, LLColor4::grey, 0.8f);
+ mAllTimeMax = llmax(mAllTimeMax, mRecording.getLastRecording().getSum(FTM_FRAME));
+ mHoverID = NULL;
+ mHoverBarIndex = -1;
}
- gGL.color4fv(color.mV);
- F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
- F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
- gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment);
-
- }
-
- if ((*it)->getCollapsed())
- {
- it.skipDescendants();
- }
-
- prev_id = idp;
- }
- y -= (barh + dy);
- if (j < 0)
- y -= barh;
- }
-
- //draw line graph history
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLLocalClipRect clip(mGraphRect);
-
- //normalize based on last frame's maximum
- static U64 last_max = 0;
- static F32 alpha_interp = 0.f;
- U64 max_ticks = llmax(last_max, (U64) 1);
- F32 ms = (F32)((F64)max_ticks * iclock_freq);
-
- //display y-axis range
- std::string tdesc;
- if (mDisplayCalls)
- tdesc = llformat("%d calls", (int)max_ticks);
- else if (mDisplayHz)
- tdesc = llformat("%d Hz", (int)max_ticks);
- else
- tdesc = llformat("%4.2f ms", ms);
-
- x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5;
- y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight();
-
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white,
- LLFontGL::LEFT, LLFontGL::TOP);
-
- //highlight visible range
- {
- S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
- S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
-
- F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
-
- F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
- F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
-
- gGL.color4f(0.5f,0.5f,0.5f,0.3f);
- gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom);
-
- if (mHoverBarIndex >= 0)
+void LLFastTimerView::onOpen(const LLSD& key)
{
- S32 bar_frame = first_frame - mHoverBarIndex;
- F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
-
- gGL.color4f(0.5f,0.5f,0.5f,1);
-
- gGL.begin(LLRender::LINES);
- gGL.vertex2i((S32)bar, mGraphRect.mBottom);
- gGL.vertex2i((S32)bar, mGraphRect.mTop);
- gGL.end();
- }
- }
-
- U64 cur_max = 0;
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != end_timer_tree();
+ setPauseState(false);
+ mRecording.reset();
+ mRecording.appendPeriodicRecording(LLTrace::get_frame_recording());
+ for(std::deque<TimerBarRow>::iterator it = mTimerBarRows.begin(), end_it = mTimerBarRows.end();
+ it != end_it;
++it)
{
- LLFastTimer::NamedTimer* idp = (*it);
-
- //fatten highlighted timer
- if (mHoverID == idp)
- {
- gGL.flush();
- glLineWidth(3);
- }
-
- const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV;
-
- F32 alpha = 1.f;
-
- if (mHoverID != NULL &&
- idp != mHoverID)
- { //fade out non-highlighted timers
- if (idp->getParent() != mHoverID)
- {
- alpha = alpha_interp;
+ delete []it->mBars;
+ it->mBars = NULL;
}
- }
-
- gGL.color4f(col[0], col[1], col[2], alpha);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex());
- j < LLFastTimer::NamedTimer::HISTORY_NUM;
- j++)
- {
- U64 ticks = idp->getHistoricalCount(j);
-
- if (mDisplayHz)
- {
- F64 tc = (F64) (ticks+1) * iclock_freq;
- tc = 1000.f/tc;
- ticks = llmin((U64) tc, (U64) 1024);
- }
- else if (mDisplayCalls)
- {
- ticks = (S32)idp->getHistoricalCalls(j);
}
- if (alpha == 1.f)
- {
- //normalize to highlighted timer
- cur_max = llmax(cur_max, ticks);
- }
- F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
- F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks;
- gGL.vertex2f(x,y);
- gGL.vertex2f(x,mGraphRect.mBottom);
- }
- gGL.end();
-
- if (mHoverID == idp)
- {
- gGL.flush();
- glLineWidth(1);
- }
-
- if (idp->getCollapsed())
- {
- //skip hidden timers
- it.skipDescendants();
- }
- }
-
- //interpolate towards new maximum
- last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f));
- if (last_max - cur_max <= 1 || cur_max - last_max <= 1)
- {
- last_max = cur_max;
- }
- F32 alpha_target = last_max > cur_max ?
- llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :
- llmin((F32) cur_max/ (F32) last_max - 1.f,1.f);
- alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f));
-
- if (mHoverID != NULL)
- {
- x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
- y = mGraphRect.mBottom + 8;
-
- LLFontGL::getFontMonospace()->renderUTF8(
- mHoverID->getName(),
- 0,
- x, y,
- LLColor4::white,
- LLFontGL::LEFT, LLFontGL::BOTTOM);
- }
- }
- }
-
- // Output stats for clicked bar to log
- if (mPrintStats >= 0)
- {
- std::string legend_stat;
- bool first = true;
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != end_timer_tree();
- ++it)
- {
- LLFastTimer::NamedTimer* idp = (*it);
-
- if (!first)
- {
- legend_stat += ", ";
- }
- first = false;
- legend_stat += idp->getName();
-
- if (idp->getCollapsed())
- {
- it.skipDescendants();
- }
- }
- llinfos << legend_stat << llendl;
-
- std::string timer_stat;
- first = true;
- for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer());
- it != end_timer_tree();
- ++it)
- {
- LLFastTimer::NamedTimer* idp = (*it);
-
- if (!first)
- {
- timer_stat += ", ";
- }
- first = false;
-
- U64 ticks;
- if (mPrintStats > 0)
- {
- ticks = idp->getHistoricalCount(mPrintStats);
- }
- else
- {
- ticks = idp->getCountAverage();
- }
- F32 ms = (F32)((F64)ticks * iclock_freq);
-
- timer_stat += llformat("%.1f",ms);
-
- if (idp->getCollapsed())
- {
- it.skipDescendants();
- }
- }
- llinfos << timer_stat << llendl;
- mPrintStats = -1;
- }
-
- mHoverID = NULL;
- mHoverBarIndex = -1;
-
- LLView::draw();
-}
-
-F64 LLFastTimerView::getTime(const std::string& name)
-{
- const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name);
- if (timerp)
- {
- return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond();
- }
- return 0.0;
-}
void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch)
{
@@ -1445,7 +850,7 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target
LLSD current = analyzePerformanceLogDefault(target_is);
target_is.close();
- //output comparision
+ //output comparison
std::ofstream os(output.c_str());
LLSD::Real session_time = current["SessionTime"].asReal();
@@ -1533,13 +938,13 @@ void LLFastTimerView::outputAllMetrics()
//static
void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)
{
- if(LLFastTimer::sLog)
+ if(TimeBlock::sLog)
{
doAnalysisDefault(baseline, target, output) ;
return ;
}
- if(LLFastTimer::sMetricLog)
+ if(TimeBlock::sMetricLog)
{
LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;
return ;
@@ -1550,9 +955,710 @@ void LLFastTimerView::onClickCloseBtn()
setVisible(false);
}
-LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer()
+void LLFastTimerView::printLineStats()
{
- return FTM_FRAME.getNamedTimer();
+ // Output stats for clicked bar to log
+ if (mStatsIndex >= 0)
+ {
+ std::string legend_stat;
+ bool first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
+ it != end_timer_tree();
+ ++it)
+ {
+ TimeBlock* idp = (*it);
+
+ if (!first)
+ {
+ legend_stat += ", ";
+ }
+ first = false;
+ legend_stat += idp->getName();
+
+ if (idp->getTreeNode().mCollapsed)
+ {
+ it.skipDescendants();
+ }
+ }
+ llinfos << legend_stat << llendl;
+
+ std::string timer_stat;
+ first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
+ it != end_timer_tree();
+ ++it)
+ {
+ TimeBlock* idp = (*it);
+
+ if (!first)
+ {
+ timer_stat += ", ";
+ }
+ first = false;
+
+ LLUnit<F32, LLUnits::Seconds> ticks;
+ if (mStatsIndex == 0)
+ {
+ ticks = mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH);
+ }
+ else
+ {
+ ticks = mRecording.getPrevRecording(mStatsIndex).getSum(*idp);
+ }
+ LLUnit<F32, LLUnits::Milliseconds> ms = ticks;
+
+ timer_stat += llformat("%.1f",ms.value());
+
+ if (idp->getTreeNode().mCollapsed)
+ {
+ it.skipDescendants();
+ }
+ }
+ llinfos << timer_stat << llendl;
+ mStatsIndex = -1;
+ }
}
+static LLFastTimer::DeclareTimer FTM_DRAW_LINE_GRAPH("Draw line graph");
+
+void LLFastTimerView::drawLineGraph()
+{
+ LLFastTimer _(FTM_DRAW_LINE_GRAPH);
+ //draw line graph history
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLLocalClipRect clip(mGraphRect);
+
+ //normalize based on last frame's maximum
+ static LLUnit<F32, LLUnits::Seconds> max_time = 0.000001;
+ static U32 max_calls = 0;
+ static F32 alpha_interp = 0.f;
+
+ //highlight visible range
+ {
+ S32 first_frame = mRecording.getNumRecordedPeriods() - mScrollIndex;
+ S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
+
+ F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording.getNumRecordedPeriods()-1);
+
+ F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame;
+ F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame;
+
+ gGL.color4f(0.5f,0.5f,0.5f,0.3f);
+ gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom);
+
+ if (mHoverBarIndex > 0)
+ {
+ S32 bar_frame = first_frame - (mScrollIndex + mHoverBarIndex) - 1;
+ F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame;
+
+ gGL.color4f(0.5f,0.5f,0.5f,1);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i((S32)bar, mGraphRect.mBottom);
+ gGL.vertex2i((S32)bar, mGraphRect.mTop);
+ gGL.end();
+ }
+ }
+
+ LLUnit<F32, LLUnits::Seconds> cur_max = 0;
+ U32 cur_max_calls = 0;
+ for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
+ it != end_timer_tree();
+ ++it)
+ {
+ TimeBlock* idp = (*it);
+
+ //fatten highlighted timer
+ if (mHoverID == idp)
+ {
+ gGL.flush();
+ glLineWidth(3);
+ }
+
+ llassert(idp->getIndex() < sTimerColors.size());
+ const F32 * col = sTimerColors[idp->getIndex()].mV;// ft_display_table[idx].color->mV;
+
+ F32 alpha = 1.f;
+ bool is_hover_timer = true;
+
+ if (mHoverID != NULL &&
+ mHoverID != idp)
+ { //fade out non-highlighted timers
+ if (idp->getParent() != mHoverID)
+ {
+ alpha = alpha_interp;
+ is_hover_timer = false;
+ }
+ }
+
+ gGL.color4f(col[0], col[1], col[2], alpha);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ 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--)
+ {
+ LLTrace::Recording& recording = mRecording.getPrevRecording(j);
+ LLUnit<F32, LLUnits::Seconds> time = llmax(recording.getSum(*idp), LLUnit<F64, LLUnits::Seconds>(0.000001));
+ U32 calls = recording.getSum(idp->callCount());
+
+ if (is_hover_timer)
+ {
+ //normalize to highlighted timer
+ cur_max = llmax(cur_max, time);
+ cur_max_calls = llmax(cur_max_calls, calls);
+ }
+ F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1);
+ F32 y;
+ switch(mDisplayType)
+{
+ case DISPLAY_TIME:
+ y = mGraphRect.mBottom + time.value() * time_scale_factor;
+ break;
+ case DISPLAY_CALLS:
+ y = mGraphRect.mBottom + (F32)calls * call_scale_factor;
+ break;
+ case DISPLAY_HZ:
+ y = mGraphRect.mBottom + (1.f / time.value()) * hz_scale_factor;
+ break;
+ }
+ gGL.vertex2f(x,y);
+ gGL.vertex2f(x,mGraphRect.mBottom);
+}
+ gGL.end();
+
+ if (mHoverID == idp)
+ {
+ gGL.flush();
+ glLineWidth(1);
+ }
+
+ if (idp->getTreeNode().mCollapsed)
+ {
+ //skip hidden timers
+ it.skipDescendants();
+ }
+ }
+
+ //interpolate towards new maximum
+ max_time = lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f));
+ if (llabs((max_time - cur_max).value()) <= 1)
+ {
+ max_time = llmax(LLUnit<F32, LLUnits::Microseconds>(1), LLUnit<F32, LLUnits::Microseconds>(cur_max));
+ }
+
+ max_calls = llround(lerp((F32)max_calls, (F32) cur_max_calls, LLSmoothInterpolation::getInterpolant(0.1f)));
+ if (llabs((S32)(max_calls - cur_max_calls)) <= 1)
+ {
+ max_calls = cur_max_calls;
+ }
+
+ // TODO: make sure alpha is correct in DisplayHz mode
+ F32 alpha_target = (max_time > cur_max)
+ ? llmin(max_time / cur_max - 1.f,1.f)
+ : llmin(cur_max/ max_time - 1.f,1.f);
+ alpha_interp = lerp(alpha_interp, alpha_target, LLSmoothInterpolation::getInterpolant(0.1f));
+
+ if (mHoverID != NULL)
+ {
+ S32 x = (mGraphRect.mRight + mGraphRect.mLeft)/2;
+ S32 y = mGraphRect.mBottom + 8;
+
+ LLFontGL::getFontMonospace()->renderUTF8(
+ mHoverID->getName(),
+ 0,
+ x, y,
+ LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::BOTTOM);
+ }
+
+ //display y-axis range
+ std::string axis_label;
+ switch(mDisplayType)
+ {
+ case DISPLAY_TIME:
+ axis_label = llformat("%4.2f ms", LLUnit<F32, LLUnits::Milliseconds>(max_time).value());
+ break;
+ case DISPLAY_CALLS:
+ axis_label = llformat("%d calls", (int)max_calls);
+ break;
+ case DISPLAY_HZ:
+ axis_label = llformat("%4.2f Hz", max_time.value() ? 1.f / max_time.value() : 0.f);
+ break;
+ }
+
+ LLFontGL* font = LLFontGL::getFontMonospace();
+ S32 x = mGraphRect.mRight - font->getWidth(axis_label)-5;
+ S32 y = mGraphRect.mTop - font->getLineHeight();;
+
+ font->renderUTF8(axis_label, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
+}
+
+void LLFastTimerView::drawLegend()
+{
+ // draw legend
+ S32 dx;
+ S32 x = mLegendRect.mLeft;
+ S32 y = mLegendRect.mTop;
+ const S32 TEXT_HEIGHT = (S32)LLFontGL::getFontMonospace()->getLineHeight();
+
+ {
+ LLLocalClipRect clip(mLegendRect);
+ S32 cur_line = 0;
+ ft_display_idx.clear();
+ std::map<TimeBlock*, S32> display_line;
+ for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
+ it != timer_tree_iterator_t();
+ ++it)
+ {
+ TimeBlock* idp = (*it);
+ display_line[idp] = cur_line;
+ ft_display_idx.push_back(idp);
+ cur_line++;
+
+ x = MARGIN;
+
+ LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT);
+ S32 scale_offset = 0;
+ if (idp == mHoverID)
+ {
+ scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
+ }
+ bar_rect.stretch(scale_offset);
+ llassert(idp->getIndex() < sTimerColors.size());
+ gl_rect_2d(bar_rect, sTimerColors[idp->getIndex()]);
+
+ LLUnit<F32, LLUnits::Milliseconds> ms = 0;
+ S32 calls = 0;
+ if (mHoverBarIndex > 0 && mHoverID)
+ {
+ S32 hidx = mScrollIndex + mHoverBarIndex;
+ ms = mRecording.getPrevRecording(hidx).getSum(*idp);
+ calls = mRecording.getPrevRecording(hidx).getSum(idp->callCount());
+ }
+ else
+ {
+ ms = LLUnit<F64, LLUnits::Seconds>(mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH));
+ calls = (S32)mRecording.getPeriodMean(idp->callCount(), RUNNING_AVERAGE_WIDTH);
+ }
+
+ std::string timer_label;
+ switch(mDisplayType)
+ {
+ case DISPLAY_TIME:
+ timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value());
+ break;
+ case DISPLAY_CALLS:
+ timer_label = llformat("%s (%d)",idp->getName().c_str(),calls);
+ break;
+ case DISPLAY_HZ:
+ timer_label = llformat("%.1f", ms.value() ? (1.f / ms.value()) : 0.f);
+ break;
+ }
+ dx = (TEXT_HEIGHT+4) + get_depth(idp)*8;
+
+ LLColor4 color = LLColor4::white;
+ if (get_depth(idp) > 0)
+ {
+ S32 line_start_y = bar_rect.getCenterY();
+ S32 line_end_y = line_start_y + ((TEXT_HEIGHT + 2) * (cur_line - display_line[idp->getParent()])) - TEXT_HEIGHT;
+ gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
+ S32 line_x = x + (TEXT_HEIGHT + 4) + ((get_depth(idp) - 1) * 8);
+ gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
+ if (idp->getTreeNode().mCollapsed && !idp->getChildren().empty())
+ {
+ gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
+ }
+ }
+
+ x += dx;
+ BOOL is_child_of_hover_item = (idp == mHoverID);
+ TimeBlock* next_parent = idp->getParent();
+ while(!is_child_of_hover_item && next_parent)
+ {
+ is_child_of_hover_item = (mHoverID == next_parent);
+ if (next_parent->getParent() == next_parent) break;
+ next_parent = next_parent->getParent();
+ }
+
+ LLFontGL::getFontMonospace()->renderUTF8(timer_label, 0,
+ x, y,
+ color,
+ LLFontGL::LEFT, LLFontGL::TOP,
+ is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL);
+
+ y -= (TEXT_HEIGHT + 2);
+
+ if (idp->getTreeNode().mCollapsed)
+ {
+ it.skipDescendants();
+ }
+ }
+ }
+}
+
+void LLFastTimerView::generateUniqueColors()
+{
+ // generate unique colors
+ {
+ sTimerColors.resize(LLTrace::TimeBlock::getNumIndices());
+ sTimerColors[FTM_FRAME.getIndex()] = LLColor4::grey;
+
+ F32 hue = 0.f;
+
+ for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);
+ it != timer_tree_iterator_t();
+ ++it)
+ {
+ TimeBlock* idp = (*it);
+
+ const F32 HUE_INCREMENT = 0.23f;
+ hue = fmodf(hue + HUE_INCREMENT, 1.f);
+ // saturation increases with depth
+ F32 saturation = clamp_rescale((F32)get_depth(idp), 0.f, 3.f, 0.f, 1.f);
+ // lightness alternates with depth
+ F32 lightness = get_depth(idp) % 2 ? 0.5f : 0.6f;
+
+ LLColor4 child_color;
+ child_color.setHSL(hue, saturation, lightness);
+
+ llassert(idp->getIndex() < sTimerColors.size());
+ sTimerColors[idp->getIndex()] = child_color;
+ }
+ }
+}
+
+void LLFastTimerView::drawHelp( S32 y )
+{
+ // Draw some help
+ const S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight();
+
+ y -= (texth + 2);
+ y -= (texth + 2);
+
+ LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts]"),
+ 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
+}
+
+void LLFastTimerView::drawTicks()
+{
+ // Draw MS ticks
+ {
+ LLUnit<U32, LLUnits::Milliseconds> ms = mTotalTimeDisplay;
+ std::string tick_label;
+ S32 x;
+ S32 barw = mBarRect.getWidth();
+
+ tick_label = llformat("%.1f ms |", (F32)ms.value()*.25f);
+ x = mBarRect.mLeft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tick_label);
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::TOP);
+
+ tick_label = llformat("%.1f ms |", (F32)ms.value()*.50f);
+ x = mBarRect.mLeft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tick_label);
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::TOP);
+
+ tick_label = llformat("%.1f ms |", (F32)ms.value()*.75f);
+ x = mBarRect.mLeft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tick_label);
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::TOP);
+
+ tick_label = llformat( "%d ms |", (U32)ms.value());
+ x = mBarRect.mLeft + barw - LLFontGL::getFontMonospace()->getWidth(tick_label);
+ LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::TOP);
+ }
+}
+
+void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32 dy )
+{
+ // Draw borders
+ {
+ S32 by = y + 6 + (S32)LLFontGL::getFontMonospace()->getLineHeight();
+
+ //heading
+ gl_rect_2d(x_start-5, by, getRect().getWidth()-5, y+5, LLColor4::grey, FALSE);
+
+ //tree view
+ gl_rect_2d(5, by, x_start-10, 5, LLColor4::grey, FALSE);
+
+ by = y + 5;
+ //average bar
+ gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-5, LLColor4::grey, FALSE);
+
+ by -= bar_height*2+dy;
+
+ //current frame bar
+ gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-2, LLColor4::grey, FALSE);
+
+ by -= bar_height+dy+1;
+
+ //history bars
+ gl_rect_2d(x_start-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-bar_height-dy-2, LLColor4::grey, FALSE);
+
+ by = LINE_GRAPH_HEIGHT-dy;
+
+ //line graph
+ //mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5);
+
+ gl_rect_2d(mGraphRect, FALSE);
+ }
+}
+
+void LLFastTimerView::updateTotalTime()
+{
+ switch(mDisplayMode)
+ {
+ case 0:
+ mTotalTimeDisplay = mRecording.getPeriodMean(FTM_FRAME, RUNNING_AVERAGE_WIDTH)*2;
+ break;
+ case 1:
+ mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME);
+ break;
+ case 2:
+ // Calculate the max total ticks for the current history
+ mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME, 20);
+ break;
+ default:
+ mTotalTimeDisplay = LLUnit<F32, LLUnits::Milliseconds>(100);
+ break;
+ }
+
+ mTotalTimeDisplay = LLUnit<F32, LLUnits::Milliseconds>(llceil(mTotalTimeDisplay.getAs<LLUnits::Milliseconds>() / 20.f) * 20.f);
+}
+
+void LLFastTimerView::drawBars()
+{
+ LLLocalClipRect clip(mBarRect);
+
+ S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2);
+ const S32 vpad = llmax(1, bar_height / 4); // spacing between bars
+ bar_height -= vpad;
+
+ updateTotalTime();
+ if (mTotalTimeDisplay <= 0.0) return;
+
+ drawTicks();
+ const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
+ drawBorders(bars_top, mBarRect.mLeft, bar_height, vpad);
+
+ // Draw bars for each history entry
+ // Special: 0 = show running average
+ LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square");
+
+ const S32 image_width = bar_image->getTextureWidth();
+ const S32 image_height = bar_image->getTextureHeight();
+
+ gGL.getTexUnit(0)->bind(bar_image->getImage());
+ {
+ const S32 histmax = (S32)mRecording.getNumRecordedPeriods();
+
+ // update widths
+ if (!mPauseHistory)
+ {
+ U32 bar_index = 0;
+ if (!mAverageTimerRow.mBars)
+ {
+ mAverageTimerRow.mBars = new TimerBar[LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()];
+ }
+ updateTimerBarWidths(&FTM_FRAME, mAverageTimerRow, -1, bar_index);
+ updateTimerBarOffsets(&FTM_FRAME, mAverageTimerRow);
+
+ for (S32 history_index = 1; history_index <= histmax; history_index++)
+ {
+ llassert(history_index <= mTimerBarRows.size());
+ TimerBarRow& row = mTimerBarRows[history_index - 1];
+ bar_index = 0;
+ if (!row.mBars)
+ {
+ row.mBars = new TimerBar[LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()];
+ updateTimerBarWidths(&FTM_FRAME, row, history_index, bar_index);
+ updateTimerBarOffsets(&FTM_FRAME, row);
+ }
+ }
+ }
+
+ // draw bars
+ LLRect frame_bar_rect;
+ frame_bar_rect.setLeftTopAndSize(mBarRect.mLeft,
+ bars_top,
+ llround((mAverageTimerRow.mBars[0].mTotalTime / mTotalTimeDisplay) * mBarRect.getWidth()),
+ bar_height);
+ mAverageTimerRow.mTop = frame_bar_rect.mTop;
+ mAverageTimerRow.mBottom = frame_bar_rect.mBottom;
+ drawBar(frame_bar_rect, mAverageTimerRow, image_width, image_height);
+ frame_bar_rect.translate(0, -(bar_height + vpad + bar_height));
+
+ for(S32 bar_index = mScrollIndex; bar_index < llmin(histmax, mScrollIndex + MAX_VISIBLE_HISTORY); ++bar_index)
+ {
+ llassert(bar_index < mTimerBarRows.size());
+ TimerBarRow& row = mTimerBarRows[bar_index];
+ row.mTop = frame_bar_rect.mTop;
+ row.mBottom = frame_bar_rect.mBottom;
+ frame_bar_rect.mRight = frame_bar_rect.mLeft
+ + llround((row.mBars[0].mTotalTime / mTotalTimeDisplay) * mBarRect.getWidth());
+ drawBar(frame_bar_rect, row, image_width, image_height);
+
+ frame_bar_rect.translate(0, -(bar_height + vpad));
+ }
+
+ }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+}
+
+static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths");
+
+LLUnit<F32, LLUnits::Seconds> LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, U32& bar_index)
+{
+ LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS);
+ const LLUnit<F32, LLUnits::Seconds> self_time = history_index == -1
+ ? mRecording.getPeriodMean(time_block->selfTime(), RUNNING_AVERAGE_WIDTH)
+ : mRecording.getPrevRecording(history_index).getSum(time_block->selfTime());
+
+ LLUnit<F32, LLUnits::Seconds> full_time = self_time;
+
+ // reserve a spot for this bar to be rendered before its children
+ // even though we don't know its size yet
+ TimerBar& timer_bar = row.mBars[bar_index];
+ bar_index++;
+
+ for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it)
+ {
+ full_time += updateTimerBarWidths(*it, row, history_index, bar_index);
+ }
+
+ timer_bar.mTotalTime = full_time;
+ timer_bar.mSelfTime = self_time;
+ timer_bar.mTimeBlock = time_block;
+
+ return full_time;
+}
+
+static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions");
+
+S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 timer_bar_index)
+{
+ LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS);
+
+ TimerBar& timer_bar = row.mBars[timer_bar_index];
+ const LLUnit<F32, LLUnits::Seconds> bar_time = timer_bar.mTotalTime - timer_bar.mSelfTime;
+ timer_bar.mChildrenStart = timer_bar.mSelfStart + timer_bar.mSelfTime / 2;
+ timer_bar.mChildrenEnd = timer_bar.mChildrenStart + timer_bar.mTotalTime - timer_bar.mSelfTime;
+
+ if (timer_bar_index == 0)
+ {
+ timer_bar.mSelfStart = 0.f;
+ timer_bar.mSelfEnd = bar_time;
+ }
+
+ //now loop through children and figure out portion of bar image covered by each bar, now that we know the
+ //sum of all children
+ F32 bar_fraction_start = 0.f;
+ TimerBar* last_child_timer_bar = NULL;
+
+ bool first_child = true;
+ for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren();
+ it != end_it;
+ ++it)
+ {
+ timer_bar_index++;
+
+ TimerBar& child_timer_bar = row.mBars[timer_bar_index];
+ TimeBlock* child_time_block = *it;
+
+ if (last_child_timer_bar)
+ {
+ last_child_timer_bar->mLastChild = false;
+ }
+ child_timer_bar.mLastChild = true;
+ last_child_timer_bar = &child_timer_bar;
+
+ child_timer_bar.mFirstChild = first_child;
+ if (first_child)
+ {
+ first_child = false;
+ }
+
+ child_timer_bar.mStartFraction = bar_fraction_start;
+ child_timer_bar.mEndFraction = bar_time > 0
+ ? bar_fraction_start + child_timer_bar.mTotalTime / bar_time
+ : 1.f;
+ child_timer_bar.mSelfStart = timer_bar.mChildrenStart
+ + child_timer_bar.mStartFraction
+ * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
+ child_timer_bar.mSelfEnd = timer_bar.mChildrenStart
+ + child_timer_bar.mEndFraction
+ * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart);
+
+ timer_bar_index = updateTimerBarOffsets(child_time_block, row, timer_bar_index);
+
+ bar_fraction_start = child_timer_bar.mEndFraction;
+ }
+ return timer_bar_index;
+}
+
+S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, bool visible, S32 bar_index)
+{
+ TimerBar& timer_bar = row.mBars[bar_index];
+ LLTrace::TimeBlock* time_block = timer_bar.mTimeBlock;
+
+ hovered |= mHoverID == time_block;
+
+ // animate scale of bar when hovering over that particular timer
+ if (visible && (F32)bar_rect.getWidth() * (timer_bar.mEndFraction - timer_bar.mStartFraction) > 2.f)
+ {
+ LLRect render_rect(bar_rect);
+ S32 scale_offset = 0;
+ if (mHoverID == time_block)
+ {
+ scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f);
+ render_rect.mTop += scale_offset;
+ render_rect.mBottom -= scale_offset;
+ }
+
+ llassert(time_block->getIndex() < sTimerColors.size());
+ LLColor4 color = sTimerColors[time_block->getIndex()];
+ if (!hovered) color = lerp(color, LLColor4::grey, 0.2f);
+ gGL.color4fv(color.mV);
+ gl_segmented_rect_2d_fragment_tex(render_rect,
+ image_width, image_height,
+ 16,
+ timer_bar.mStartFraction, timer_bar.mEndFraction);
+ }
+
+ LLRect children_rect;
+ children_rect.mLeft = llround(timer_bar.mChildrenStart / mTotalTimeDisplay * (F32)mBarRect.getWidth()) + mBarRect.mLeft;
+ children_rect.mRight = llround(timer_bar.mChildrenEnd / mTotalTimeDisplay * (F32)mBarRect.getWidth()) + mBarRect.mLeft;
+
+ if (bar_rect.getHeight() > MIN_BAR_HEIGHT)
+ {
+ // shrink as we go down a level
+ children_rect.mTop = bar_rect.mTop - 1;
+ children_rect.mBottom = bar_rect.mBottom + 1;
+ }
+ else
+ {
+ children_rect.mTop = bar_rect.mTop;
+ children_rect.mBottom = bar_rect.mBottom;
+ }
+
+ bool children_visible = visible && !time_block->getTreeNode().mCollapsed;
+
+ bar_index++;
+ const U32 num_bars = LLInstanceTracker<LLTrace::TimeBlock>::instanceCount();
+ if (bar_index < num_bars && row.mBars[bar_index].mFirstChild)
+ {
+ bool is_last = false;
+ do
+ {
+ is_last = row.mBars[bar_index].mLastChild;
+ bar_index = drawBar(children_rect, row, image_width, image_height, hovered, children_visible, bar_index);
+ }
+ while(!is_last && bar_index < num_bars);
+ }
+
+ return bar_index;
+}
diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h
index 5766cfa0b0..9d88bb2d3f 100755
--- a/indra/newview/llfasttimerview.h
+++ b/indra/newview/llfasttimerview.h
@@ -29,11 +29,15 @@
#include "llfloater.h"
#include "llfasttimer.h"
+#include "llunit.h"
+#include "lltracerecording.h"
+#include <deque>
class LLFastTimerView : public LLFloater
{
public:
LLFastTimerView(const LLSD&);
+ ~LLFastTimerView();
BOOL postBuild();
static BOOL sAnalyzePerformance;
@@ -46,7 +50,6 @@ private:
static LLSD analyzePerformanceLogDefault(std::istream& is) ;
static void exportCharts(const std::string& base, const std::string& target);
void onPause();
- LLFastTimer::NamedTimer& getFrameTimer();
public:
@@ -58,40 +61,87 @@ public:
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual void draw();
+ virtual void onOpen(const LLSD& key);
+ LLTrace::TimeBlock* getLegendID(S32 y);
- LLFastTimer::NamedTimer* getLegendID(S32 y);
- F64 getTime(const std::string& name);
-
-protected:
- virtual void onClickCloseBtn();
private:
- typedef std::vector<std::vector<S32> > bar_positions_t;
- bar_positions_t mBarStart;
- bar_positions_t mBarEnd;
- S32 mDisplayMode;
+ virtual void onClickCloseBtn();
+ void drawTicks();
+ void drawLineGraph();
+ void drawLegend();
+ void drawHelp(S32 y);
+ void drawBorders( S32 y, const S32 x_start, S32 barh, S32 dy);
+ void drawBars();
+
+ void printLineStats();
+ void generateUniqueColors();
+ void updateTotalTime();
+
+ struct TimerBar
+ {
+ TimerBar()
+ : mTotalTime(0),
+ mSelfTime(0),
+ mStartFraction(0.f),
+ mEndFraction(1.f),
+ mFirstChild(false),
+ mLastChild(false)
+ {}
+ LLUnit<F32, LLUnits::Seconds> mTotalTime,
+ mSelfTime,
+ mChildrenStart,
+ mChildrenEnd,
+ mSelfStart,
+ mSelfEnd;
+ LLTrace::TimeBlock* mTimeBlock;
+ bool mVisible,
+ mFirstChild,
+ mLastChild;
+ F32 mStartFraction,
+ mEndFraction;
+ };
+
+ struct TimerBarRow
+ {
+ TimerBarRow()
+ : mBottom(0),
+ mTop(0),
+ mBars(NULL)
+ {}
+ S32 mBottom,
+ mTop;
+ TimerBar* mBars;
+ };
+
+ LLUnit<F32, LLUnits::Seconds> updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, U32& bar_index);
+ S32 updateTimerBarOffsets(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 timer_bar_index = 0);
+ S32 drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered = false, bool visible = true, S32 bar_index = 0);
+ void setPauseState(bool pause_state);
+
+ std::deque<TimerBarRow> mTimerBarRows;
+ TimerBarRow mAverageTimerRow;
- typedef enum child_alignment
+ enum EDisplayType
{
- ALIGN_LEFT,
- ALIGN_CENTER,
- ALIGN_RIGHT,
- ALIGN_COUNT
- } ChildAlignment;
-
- ChildAlignment mDisplayCenter;
- S32 mDisplayCalls;
- S32 mDisplayHz;
- U64 mAvgCountTotal;
- U64 mMaxCountTotal;
- LLRect mBarRect;
- S32 mScrollIndex;
- LLFastTimer::NamedTimer* mHoverID;
- LLFastTimer::NamedTimer* mHoverTimer;
- LLRect mToolTipRect;
- S32 mHoverBarIndex;
- LLFrameTimer mHighlightTimer;
- S32 mPrintStats;
- LLRect mGraphRect;
+ DISPLAY_TIME,
+ DISPLAY_CALLS,
+ DISPLAY_HZ
+ } mDisplayType;
+ bool mPauseHistory;
+ LLUnit<F64, LLUnits::Seconds> mAllTimeMax,
+ mTotalTimeDisplay;
+ S32 mScrollIndex,
+ mHoverBarIndex,
+ mStatsIndex;
+ S32 mDisplayMode;
+ LLTrace::TimeBlock* mHoverID;
+ LLTrace::TimeBlock* mHoverTimer;
+ LLRect mToolTipRect,
+ mGraphRect,
+ mBarRect,
+ mLegendRect;
+ LLFrameTimer mHighlightTimer;
+ LLTrace::PeriodicRecording mRecording;
};
#endif
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 4f602f63f1..4d7b81304a 100755
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -50,6 +50,7 @@
// Need commdlg.h for OPENFILENAMEA
#ifdef LL_WINDOWS
+#include "llwin32headers.h"
#include <commdlg.h>
#endif
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81..93502daac7 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -296,7 +296,8 @@ LLSD LLFloaterAbout::getInfo()
if (gPacketsIn > 0)
{
- info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent();
+ LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecording();
+ info["PACKETS_LOST"] = cur_frame.getSum(LLStatViewer::PACKETS_LOST);
info["PACKETS_IN"] = F32(gPacketsIn);
info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
}
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 113aa9a8f2..76773f914d 100755
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -405,11 +405,11 @@ void LLFloaterAvatarPicker::drawFrustum()
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
{
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
}
else
{
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
}
}
}
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 048837acfe..317bdd8d46 100755
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -37,6 +37,7 @@
#include "lluictrlfactory.h"
#include "llviewerobjectlist.h"
#include "llvoavatarself.h"
+#include "lllocaltextureobject.h"
using namespace LLAvatarAppearanceDefines;
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 42857b2aa2..84e2956b29 100755
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -202,7 +202,7 @@ public:
virtual void draw();
virtual BOOL canClose();
- void onVisibilityChange ( const LLSD& new_visibility );
+ void onVisibilityChanged ( const LLSD& new_visibility );
};
@@ -1008,7 +1008,7 @@ BOOL LLFloaterBuyLandUI::canClose()
return can_close;
}
-void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility )
+void LLFloaterBuyLandUI::onVisibilityChanged ( const LLSD& new_visibility )
{
if (new_visibility.asBoolean())
{
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index a03425649f..6aebe85e7a 100755
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -529,11 +529,11 @@ void LLFloaterColorPicker::draw()
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
{
mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),
- LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
}
else
{
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));
}
mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 56b0c15cb9..2287277acf 100755
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -328,7 +328,7 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
void LLFloaterIMNearbyChat::show()
{
openFloater(getKey());
- }
+}
bool LLFloaterIMNearbyChat::isChatVisible() const
{
@@ -841,7 +841,7 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32
gAgent.sendReliableMessage();
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+ add(LLStatViewer::CHAT_COUNT, 1);
}
class LLChatCommandHandler : public LLCommandHandler
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 8ec85e1160..6116f693e6 100755..100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -41,6 +41,7 @@
#include "llchicletbar.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llfloaterreg.h"
+#include "llhttpclient.h"
#include "llfloateravatarpicker.h"
#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "llinventoryfunctions.h"
@@ -52,6 +53,7 @@
#include "lltrans.h"
#include "llchathistory.h"
#include "llnotifications.h"
+#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "lltransientfloatermgr.h"
#include "llinventorymodel.h"
@@ -170,7 +172,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)
}
}
-void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility)
+void LLFloaterIMSession::onVisibilityChanged(const LLSD& new_visibility)
{
bool visible = new_visibility.asBoolean();
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index a0e0171b34..84abb2435a 100755..100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -62,7 +62,7 @@ public:
void initIMSession(const LLUUID& session_id);
void initIMFloater();
-
+
// LLView overrides
/*virtual*/ BOOL postBuild();
/*virtual*/ void setMinimized(BOOL b);
@@ -107,7 +107,7 @@ public:
// called when docked floater's position has been set by chiclet
void setPositioned(bool b) { mPositioned = b; };
- void onVisibilityChange(const LLSD& new_visibility);
+ void onVisibilityChanged(const LLSD& new_visibility);
bool enableGearMenuItem(const LLSD& userdata);
void GearDoToSelected(const LLSD& userdata);
bool checkGearMenuItem(const LLSD& userdata);
@@ -142,10 +142,10 @@ private:
/*virtual*/ void onTearOffClicked();
/*virtual*/ void onClickCloseBtn();
-
+
// Update the window title and input field help text
/*virtual*/ void updateSessionName(const std::string& name);
-
+
bool dropPerson(LLUUID* person_id, bool drop);
BOOL isInviteAllowed() const;
@@ -161,7 +161,7 @@ private:
bool canAddSelectedToChat(const uuid_vec_t& uuids);
void onCallButtonClicked();
-
+
void boundVoiceChannel();
// Add the "User is typing..." indicator.
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index d0c22d25f2..b71ab4c53b 100755
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -33,7 +33,7 @@
#include "llerror.h"
#include "llrect.h"
#include "llstring.h"
-#include "llstat.h"
+#include "lltrace.h"
// project includes
#include "lluictrlfactory.h"
@@ -42,6 +42,22 @@
#include "llviewerjoystick.h"
#include "llcheckboxctrl.h"
+static LLTrace::SampleStatHandle<> sJoystickAxis1("Joystick axis 1"),
+ sJoystickAxis2("Joystick axis 2"),
+ sJoystickAxis3("Joystick axis 3"),
+ sJoystickAxis4("Joystick axis 4"),
+ sJoystickAxis5("Joystick axis 5"),
+ sJoystickAxis6("Joystick axis 6");
+static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =
+{
+ &sJoystickAxis1,
+ &sJoystickAxis2,
+ &sJoystickAxis3,
+ &sJoystickAxis4,
+ &sJoystickAxis5,
+ &sJoystickAxis6
+};
+
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
: LLFloater(data)
{
@@ -61,7 +77,7 @@ void LLFloaterJoystick::draw()
for (U32 i = 0; i < 6; i++)
{
F32 value = joystick->getJoystickAxis(i);
- mAxisStats[i]->addValue(value * gFrameIntervalSeconds);
+ sample(*sJoystickAxes[i], value * gFrameIntervalSeconds.value());
if (mAxisStatsBar[i])
{
F32 minbar, maxbar;
@@ -69,7 +85,7 @@ void LLFloaterJoystick::draw()
if (llabs(value) > maxbar)
{
F32 range = llabs(value);
- mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f);
+ mAxisStatsBar[i]->setRange(-range, range, range * 0.25f);
}
}
}
@@ -85,13 +101,12 @@ BOOL LLFloaterJoystick::postBuild()
for (U32 i = 0; i < 6; i++)
{
std::string stat_name(llformat("Joystick axis %d", i));
- mAxisStats[i] = new LLStat(stat_name, 4);
std::string axisname = llformat("axis%d", i);
mAxisStatsBar[i] = getChild<LLStatBar>(axisname);
if (mAxisStatsBar[i])
{
- mAxisStatsBar[i]->setStat(mAxisStats[i]);
- mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f);
+ mAxisStatsBar[i]->setStat(stat_name);
+ mAxisStatsBar[i]->setRange(-range, range, range * 0.25f);
}
}
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index dfdb108ff8..9c3752540d 100755
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -84,7 +84,6 @@ private:
LLCheckBoxCtrl *mCheckFlycamEnabled;
// stats view
- LLStat* mAxisStats[6];
LLStatBar* mAxisStatsBar[6];
};
diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp
deleted file mode 100755
index 68b1770bb2..0000000000
--- a/indra/newview/llfloaterlagmeter.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/**
- * @file llfloaterlagmeter.cpp
- * @brief The "Lag-o-Meter" floater used to tell users what is causing lag.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterlagmeter.h"
-
-#include "lluictrlfactory.h"
-#include "llviewerstats.h"
-#include "llviewertexture.h"
-#include "llviewercontrol.h"
-#include "llappviewer.h"
-
-#include "lltexturefetch.h"
-
-#include "llbutton.h"
-#include "llfocusmgr.h"
-#include "lltextbox.h"
-
-const std::string LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga";
-const std::string LAG_WARNING_IMAGE_NAME = "lag_status_warning.tga";
-const std::string LAG_GOOD_IMAGE_NAME = "lag_status_good.tga";
-
-LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key)
- : LLFloater(key)
-{
- mCommitCallbackRegistrar.add("LagMeter.ClickShrink", boost::bind(&LLFloaterLagMeter::onClickShrink, this));
-}
-
-BOOL LLFloaterLagMeter::postBuild()
-{
- // Don't let this window take keyboard focus -- it's confusing to
- // lose arrow-key driving when testing lag.
- setIsChrome(TRUE);
-
- // were we shrunk last time?
- if (isShrunk())
- {
- onClickShrink();
- }
-
- mClientButton = getChild<LLButton>("client_lagmeter");
- mClientText = getChild<LLTextBox>("client_text");
- mClientCause = getChild<LLTextBox>("client_lag_cause");
-
- mNetworkButton = getChild<LLButton>("network_lagmeter");
- mNetworkText = getChild<LLTextBox>("network_text");
- mNetworkCause = getChild<LLTextBox>("network_lag_cause");
-
- mServerButton = getChild<LLButton>("server_lagmeter");
- mServerText = getChild<LLTextBox>("server_text");
- mServerCause = getChild<LLTextBox>("server_lag_cause");
-
- std::string config_string = getString("client_frame_rate_critical_fps", mStringArgs);
- mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() );
- config_string = getString("client_frame_rate_warning_fps", mStringArgs);
- mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() );
-
- config_string = getString("network_packet_loss_critical_pct", mStringArgs);
- mNetworkPacketLossCritical = (float)atof( config_string.c_str() );
- config_string = getString("network_packet_loss_warning_pct", mStringArgs);
- mNetworkPacketLossWarning = (float)atof( config_string.c_str() );
-
- config_string = getString("network_ping_critical_ms", mStringArgs);
- mNetworkPingCritical = (float)atof( config_string.c_str() );
- config_string = getString("network_ping_warning_ms", mStringArgs);
- mNetworkPingWarning = (float)atof( config_string.c_str() );
- config_string = getString("server_frame_rate_critical_fps", mStringArgs);
-
- mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() );
- config_string = getString("server_frame_rate_warning_fps", mStringArgs);
- mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() );
- config_string = getString("server_single_process_max_time_ms", mStringArgs);
- mServerSingleProcessMaxTime = (float)atof( config_string.c_str() );
-
-// mShrunk = false;
- config_string = getString("max_width_px", mStringArgs);
- mMaxWidth = atoi( config_string.c_str() );
- config_string = getString("min_width_px", mStringArgs);
- mMinWidth = atoi( config_string.c_str() );
-
- mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps");
- mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps");
-
- mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct");
- mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct");
-
- mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms");
- mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms");
-
- mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps");
- mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps");
-
-// childSetAction("minimize", onClickShrink, this);
- updateControls(isShrunk()); // if expanded append colon to the labels (EXT-4079)
-
- return TRUE;
-}
-LLFloaterLagMeter::~LLFloaterLagMeter()
-{
- // save shrunk status for next time
-// gSavedSettings.setBOOL("LagMeterShrunk", mShrunk);
- // expand so we save the large window rectangle
- if (isShrunk())
- {
- onClickShrink();
- }
-}
-
-void LLFloaterLagMeter::draw()
-{
- determineClient();
- determineNetwork();
- determineServer();
-
- LLFloater::draw();
-}
-
-void LLFloaterLagMeter::determineClient()
-{
- F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
- bool find_cause = false;
-
- if (!gFocusMgr.getAppHasFocus())
- {
- mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
- mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
- mClientCause->setText( LLStringUtil::null );
- }
- else if(client_frame_time >= mClientFrameTimeCritical)
- {
- mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
- mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
- find_cause = true;
- }
- else if(client_frame_time >= mClientFrameTimeWarning)
- {
- mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
- mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
- find_cause = true;
- }
- else
- {
- mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
- mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
- mClientCause->setText( LLStringUtil::null );
- }
-
- if(find_cause)
- {
- if(gSavedSettings.getF32("RenderFarClip") > 128)
- {
- mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) );
- }
- else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)
- {
- mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
- }
- else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes)
- {
- mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
- }
- else
- {
- mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) );
- }
- }
-}
-
-void LLFloaterLagMeter::determineNetwork()
-{
- F32 packet_loss = LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean();
- F32 ping_time = LLViewerStats::getInstance()->mSimPingStat.getMean();
- bool find_cause_loss = false;
- bool find_cause_ping = false;
-
- // *FIXME: We can't blame a large ping time on anything in
- // particular if the frame rate is low, because a low frame
- // rate is a sure recipe for bad ping times right now until
- // the network handlers are de-synched from the rendering.
- F32 client_frame_time_ms = 1000.0f * LLViewerStats::getInstance()->mFPSStat.getMeanDuration();
-
- if(packet_loss >= mNetworkPacketLossCritical)
- {
- mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
- mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) );
- find_cause_loss = true;
- }
- else if(ping_time >= mNetworkPingCritical)
- {
- mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
- if (client_frame_time_ms < mNetworkPingCritical)
- {
- mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) );
- find_cause_ping = true;
- }
- }
- else if(packet_loss >= mNetworkPacketLossWarning)
- {
- mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
- mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) );
- find_cause_loss = true;
- }
- else if(ping_time >= mNetworkPingWarning)
- {
- mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
- if (client_frame_time_ms < mNetworkPingWarning)
- {
- mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) );
- find_cause_ping = true;
- }
- }
- else
- {
- mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
- mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) );
- }
-
- if(find_cause_loss)
- {
- mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) );
- }
- else if(find_cause_ping)
- {
- mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) );
- }
- else
- {
- mNetworkCause->setText( LLStringUtil::null );
- }
-}
-
-void LLFloaterLagMeter::determineServer()
-{
- F32 sim_frame_time = LLViewerStats::getInstance()->mSimFrameMsec.getCurrent();
- bool find_cause = false;
-
- if(sim_frame_time >= mServerFrameTimeCritical)
- {
- mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
- mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) );
- find_cause = true;
- }
- else if(sim_frame_time >= mServerFrameTimeWarning)
- {
- mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
- mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) );
- find_cause = true;
- }
- else
- {
- mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
- mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) );
- mServerCause->setText( LLStringUtil::null );
- }
-
- if(find_cause)
- {
- if(LLViewerStats::getInstance()->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime)
- {
- mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) );
- }
- else if(LLViewerStats::getInstance()->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime)
- {
- mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) );
- }
- else if(LLViewerStats::getInstance()->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime)
- {
- mServerCause->setText( getString("server_net_cause_msg", mStringArgs) );
- }
- else if(LLViewerStats::getInstance()->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime)
- {
- mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) );
- }
- else if(LLViewerStats::getInstance()->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime)
- {
- mServerCause->setText( getString("server_images_cause_msg", mStringArgs) );
- }
- else
- {
- mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) );
- }
- }
-}
-
-void LLFloaterLagMeter::updateControls(bool shrink)
-{
-// LLFloaterLagMeter * self = (LLFloaterLagMeter*)data;
-
- LLButton * button = getChild<LLButton>("minimize");
- S32 delta_width = mMaxWidth -mMinWidth;
- LLRect r = getRect();
-
- if(!shrink)
- {
- setTitle(getString("max_title_msg", mStringArgs) );
- // make left edge appear to expand
- r.translate(-delta_width, 0);
- setRect(r);
- reshape(mMaxWidth, getRect().getHeight());
-
- getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) + ":");
- getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) + ":");
- getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) + ":");
-
- // usually "<<"
- button->setLabel( getString("smaller_label", mStringArgs) );
- }
- else
- {
- setTitle( getString("min_title_msg", mStringArgs) );
- // make left edge appear to collapse
- r.translate(delta_width, 0);
- setRect(r);
- reshape(mMinWidth, getRect().getHeight());
-
- getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) );
- getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) );
- getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) );
-
- // usually ">>"
- button->setLabel( getString("bigger_label", mStringArgs) );
- }
- // Don't put keyboard focus on the button
- button->setFocus(FALSE);
-
-// self->mClientText->setVisible(self->mShrunk);
-// self->mClientCause->setVisible(self->mShrunk);
-// self->getChildView("client_help")->setVisible( self->mShrunk);
-
-// self->mNetworkText->setVisible(self->mShrunk);
-// self->mNetworkCause->setVisible(self->mShrunk);
-// self->getChildView("network_help")->setVisible( self->mShrunk);
-
-// self->mServerText->setVisible(self->mShrunk);
-// self->mServerCause->setVisible(self->mShrunk);
-// self->getChildView("server_help")->setVisible( self->mShrunk);
-
-// self->mShrunk = !self->mShrunk;
-}
-
-BOOL LLFloaterLagMeter::isShrunk()
-{
- return gSavedSettings.getBOOL("LagMeterShrunk");
-}
-
-void LLFloaterLagMeter::onClickShrink() // toggle "LagMeterShrunk"
-{
- bool shrunk = isShrunk();
- updateControls(!shrunk);
- gSavedSettings.setBOOL("LagMeterShrunk", !shrunk);
-}
diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h
deleted file mode 100755
index eef6955601..0000000000
--- a/indra/newview/llfloaterlagmeter.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file llfloaterlagmeter.h
- * @brief The "Lag-o-Meter" floater used to tell users what is causing lag.
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LLFLOATERLAGMETER_H
-#define LLFLOATERLAGMETER_H
-
-#include "llfloater.h"
-
-class LLTextBox;
-
-class LLFloaterLagMeter : public LLFloater
-{
- friend class LLFloaterReg;
-
-public:
- /*virtual*/ void draw();
- /*virtual*/ BOOL postBuild();
-private:
-
- LLFloaterLagMeter(const LLSD& key);
- /*virtual*/ ~LLFloaterLagMeter();
- void determineClient();
- void determineNetwork();
- void determineServer();
- void updateControls(bool shrink);
- BOOL isShrunk();
-
- void onClickShrink();
-
- bool mShrunk;
- S32 mMaxWidth, mMinWidth;
-
- F32 mClientFrameTimeCritical;
- F32 mClientFrameTimeWarning;
- LLButton * mClientButton;
- LLTextBox * mClientText;
- LLTextBox * mClientCause;
-
- F32 mNetworkPacketLossCritical;
- F32 mNetworkPacketLossWarning;
- F32 mNetworkPingCritical;
- F32 mNetworkPingWarning;
- LLButton * mNetworkButton;
- LLTextBox * mNetworkText;
- LLTextBox * mNetworkCause;
-
- F32 mServerFrameTimeCritical;
- F32 mServerFrameTimeWarning;
- F32 mServerSingleProcessMaxTime;
- LLButton * mServerButton;
- LLTextBox * mServerText;
- LLTextBox * mServerCause;
-
- LLStringUtil::format_map_t mStringArgs;
-};
-
-#endif
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 8290494c22..2194c1112a 100755
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -225,7 +225,7 @@ void LLFloaterLand::onOpen(const LLSD& key)
refresh();
}
-void LLFloaterLand::onVisibilityChange(const LLSD& visible)
+void LLFloaterLand::onVisibilityChanged(const LLSD& visible)
{
if (!visible.asBoolean())
{
@@ -255,7 +255,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed)
BOOL LLFloaterLand::postBuild()
{
- setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChanged, this, _2));
LLTabContainer* tab = getChild<LLTabContainer>("landtab");
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 4f1c10274a..dccdfc9acb 100755
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -88,7 +88,7 @@ private:
LLFloaterLand(const LLSD& seed);
virtual ~LLFloaterLand();
- void onVisibilityChange(const LLSD& visible);
+ void onVisibilityChanged(const LLSD& visible);
protected:
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 100f1d580b..49ddcc7d18 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -113,8 +113,6 @@
#include "llviewernetwork.h"
#include "llviewershadermgr.h"
#include "glod/glod.h"
-#include <boost/algorithm/string.hpp>
-
const S32 SLM_SUPPORTED_VERSION = 3;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 50c013a49d..bc8a208030 100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -2545,8 +2545,6 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
@@ -2921,7 +2919,7 @@ void LLPanelEnvironmentInfo::onOpen(const LLSD& key)
}
// virtual
-void LLPanelEnvironmentInfo::handleVisibilityChange(BOOL new_visibility)
+void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility)
{
// If hiding (user switched to another tab or closed the floater),
// display user's preferred environment.
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index f0499f1903..dd961e21b2 100755
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -402,7 +402,7 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
// LLView
- /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
// LLPanelRegionInfo
/*virtual*/ bool refreshFromRegion(LLViewerRegion* region);
diff --git a/indra/newview/llfloatersceneloadstats.cpp b/indra/newview/llfloatersceneloadstats.cpp
new file mode 100644
index 0000000000..8aa93eae96
--- /dev/null
+++ b/indra/newview/llfloatersceneloadstats.cpp
@@ -0,0 +1,40 @@
+/**
+ * @file llfloatersceneloadstats.cpp
+ * @author Richard Nelson
+ * @brief debug floater for measuring various scene load statistics
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersceneloadstats.h"
+
+
+LLFloaterSceneLoadStats::LLFloaterSceneLoadStats( const LLSD& key )
+: LLFloater(key)
+{}
+
+BOOL LLFloaterSceneLoadStats::postBuild()
+{
+ return TRUE;
+}
diff --git a/indra/llprimitive/llvolumexml.h b/indra/newview/llfloatersceneloadstats.h
index 9d4d989475..aa414bf544 100755..100644
--- a/indra/llprimitive/llvolumexml.h
+++ b/indra/newview/llfloatersceneloadstats.h
@@ -1,10 +1,10 @@
/**
- * @file llvolumexml.h
- * @brief LLVolumeXml base class
+ * @file llfloatersceneloadstats.h
+ * @brief debug floater for measuring various scene load statistics
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2013, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,22 +24,20 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLVOLUMEXML_H
-#define LL_LLVOLUMEXML_H
+#ifndef LL_FLOATERSCENELOADSTATS_H
+#define LL_FLOATERSCENELOADSTATS_H
-#include "llvolume.h"
-#include "llxmlnode.h"
+#include "llfloater.h"
-// wrapper class for some volume/message functions
-class LLVolumeXml
+class LLFloaterSceneLoadStats : public LLFloater
{
-public:
- static LLPointer<LLXMLNode> exportProfileParams(const LLProfileParams* params);
+ friend class LLFloaterReg;
+private:
+ LLFloaterSceneLoadStats(const LLSD& key);
- static LLPointer<LLXMLNode> exportPathParams(const LLPathParams* params);
+public:
+ BOOL postBuild();
- static LLPointer<LLXMLNode> exportVolumeParams(const LLVolumeParams* params);
};
-#endif // LL_LLVOLUMEXML_H
-
+#endif // LL_FLOATERSCENELOADSTATS_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index d8d62e5bbb..285f52fcd6 100755
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -478,7 +478,7 @@ void LLSnapshotLivePreview::draw()
{
if (mFlashAlpha < 1.f)
{
- mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f));
+ mFlashAlpha = lerp(mFlashAlpha, 1.f, LLSmoothInterpolation::getInterpolant(0.02f));
}
else
{
@@ -487,7 +487,7 @@ void LLSnapshotLivePreview::draw()
}
else
{
- mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f));
+ mFlashAlpha = lerp(mFlashAlpha, 0.f, LLSmoothInterpolation::getInterpolant(0.15f));
}
// Draw shining animation if appropriate.
@@ -992,7 +992,7 @@ void LLSnapshotLivePreview::saveTexture()
llwarns << "Error encoding snapshot" << llendl;
}
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
+ add(LLStatViewer::SNAPSHOT, 1);
mDataSize = 0;
}
diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp
index 47612fe25c..3110d0391f 100755
--- a/indra/newview/llfollowcam.cpp
+++ b/indra/newview/llfollowcam.cpp
@@ -327,11 +327,11 @@ void LLFollowCam::update()
F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;
*/
- F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag );
+ F32 focusLagLerp = LLSmoothInterpolation::getInterpolant( mFocusLag );
focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );
mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);
}
- mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
+ mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f));
}// if focus is not locked ---------------------------------------------
@@ -414,7 +414,7 @@ void LLFollowCam::update()
//-------------------------------------------------------------------------------------------------
if ( distanceFromPositionToIdealPosition > mPositionThreshold )
{
- F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag );
+ F32 positionPullLerp = LLSmoothInterpolation::getInterpolant( mPositionLag );
simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );
}
@@ -434,7 +434,7 @@ void LLFollowCam::update()
updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);
mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent);
- mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
+ mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f));
} // if position is not locked -----------------------------------------------------------
@@ -489,7 +489,7 @@ BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_pos
if ( cameraOffsetAngle > mBehindnessMaxAngle )
{
- F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag);
+ F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLSmoothInterpolation::getInterpolant(mBehindnessLag);
cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));
cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it
constraint_active = TRUE;
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 9aa86297fc..876db96085 100755
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -1139,8 +1139,6 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index cbd844cdac..ba4927e622 100755
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -41,6 +41,7 @@
#include "llui.h"
#include "message.h"
#include "roles_constants.h"
+#include "llhttpclient.h"
#include "lltransactiontypes.h"
#include "llstatusbar.h"
#include "lleconomy.h"
@@ -50,6 +51,7 @@
#include "llnotificationsutil.h"
#include "lluictrlfactory.h"
#include "lltrans.h"
+#include "llviewerregion.h"
#include <boost/regex.hpp>
#if LL_MSVC
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index 557252ab0b..87455ec3f4 100755
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -28,7 +28,6 @@
#define LL_LLHUDICON_H
#include "llpointer.h"
-#include "lldarrayptr.h"
#include "llhudobject.h"
#include "v4color.h"
@@ -42,8 +41,6 @@
#include "lldarray.h"
// Renders a 2D icon billboard floating at the location specified.
-class LLDrawable;
-class LLViewerObject;
class LLViewerTexture;
class LLHUDIcon : public LLHUDObject
diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h
index 09e79acbfc..effea8f034 100755
--- a/indra/newview/llhudmanager.h
+++ b/indra/newview/llhudmanager.h
@@ -30,13 +30,9 @@
// Responsible for managing all HUD elements.
#include "llhudobject.h"
-#include "lldarrayptr.h"
+#include "lldarray.h"
-class LLViewerObject;
class LLHUDEffect;
-//Ventrella 9/16/05
-class LLHUDAnimalControls;
-// End Ventrella
class LLMessageSystem;
class LLHUDManager : public LLSingleton<LLHUDManager>
@@ -59,7 +55,7 @@ public:
static LLColor4 sChildColor;
protected:
- LLDynamicArrayPtr<LLPointer<LLHUDEffect> > mHUDEffects;
+ LLDynamicArray<LLPointer<LLHUDEffect>, 32> mHUDEffects;
};
#endif // LL_LLHUDMANAGER_H
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index c3b49f739a..19a4165b49 100755
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -30,6 +30,7 @@
#include "llhudnametag.h"
#include "llrender.h"
+#include "lltracerecording.h"
#include "llagent.h"
#include "llviewercontrol.h"
@@ -745,8 +746,8 @@ void LLHUDNameTag::updateAll()
current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
}
- LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
- F32 camera_vel = camera_vel_stat->getCurrent();
+ LLTrace::CountStatHandle<>* camera_vel_stat = LLViewerCamera::getVelocityStat();
+ F32 camera_vel = LLTrace::get_frame_recording().getLastRecording().getPerSec(*camera_vel_stat);
if (camera_vel > MAX_STABLE_CAMERA_VELOCITY)
{
return;
@@ -814,7 +815,7 @@ void LLHUDNameTag::updateAll()
VisibleTextObjectIterator this_object_it;
for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
{
- (*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
+ (*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLSmoothInterpolation::getInterpolant(POSITION_DAMPING_TC));
}
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3b72ad3cd9..7e18d37fe1 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -68,6 +68,7 @@
#include "llviewerparcelmgr.h"
#include "llconversationlog.h"
#include "message.h"
+#include "llviewerregion.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -228,7 +229,7 @@ void on_new_message(const LLSD& msg)
// 0. nothing - exit
if (("none" == user_preferences ||
ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
- && session_floater->isMessagePaneExpanded())
+ && session_floater->isMessagePaneExpanded())
{
return;
}
@@ -1561,7 +1562,7 @@ public:
}
void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
- {
+ {
llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
<< statusNum << "]: " << content << llendl;
//throw something back to the viewer here?
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index da6039a3ae..2d036cbc2f 100755
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -33,13 +33,12 @@
#include "lllogchat.h"
#include "llvoicechannel.h"
-
+#include "lldarray.h"
class LLAvatarName;
class LLFriendObserver;
class LLCallDialogManager;
class LLIMSpeakerMgr;
-
/**
* Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server
*/
@@ -557,7 +556,7 @@ public:
mAvatarNameCacheConnection.disconnect();
}
}
-
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a5043a30ac..c8ee8135a6 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -70,6 +70,7 @@
#include "llviewermenu.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llwearablelist.h"
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 02a2475cfd..b7c4ec6f8b 100755
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -32,6 +32,7 @@
#include "lldictionary.h"
#include "llinventorydefines.h"
#include "llui.h"
+#include "lluiimage.h"
#include "llwearabletype.h"
struct IconEntry : public LLDictionaryEntry
@@ -49,6 +50,8 @@ public:
LLIconDictionary();
};
+typedef LLPointer<LLUIImage> LLUIImagePtr;
+
LLIconDictionary::LLIconDictionary()
{
addEntry(LLInventoryType::ICONNAME_TEXTURE, new IconEntry("Inv_Texture"));
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index 2197c53bb8..bc09e32087 100755
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -30,7 +30,6 @@
#include "llassettype.h"
#include "llinventorytype.h"
-#include "lluiimage.h"
class LLInventoryIcon
{
@@ -41,11 +40,11 @@ public:
BOOL item_is_multi = FALSE);
static const std::string& getIconName(LLInventoryType::EIconName idx);
- static LLUIImagePtr getIcon(LLAssetType::EType asset_type,
+ static LLPointer<class LLUIImage> getIcon(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
U32 misc_flag = 0, // different meanings depending on item type
BOOL item_is_multi = FALSE);
- static LLUIImagePtr getIcon(LLInventoryType::EIconName idx);
+ static LLPointer<class LLUIImage> getIcon(LLInventoryType::EIconName idx);
protected:
static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8aac879a93..964adf5e50 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -31,7 +31,7 @@
#include "llfoldertype.h"
#include "lldarray.h"
#include "llframetimer.h"
-#include "llhttpclient.h"
+#include "llcurl.h"
#include "lluuid.h"
#include "llpermissionsflags.h"
#include "llstring.h"
@@ -79,7 +79,7 @@ public:
typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t;
typedef std::set<LLUUID> changed_items_t;
- class fetchInventoryResponder : public LLHTTPClient::Responder
+ class fetchInventoryResponder : public LLCurl::Responder
{
public:
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index cf1fd4c0d0..4fdb05bc82 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -396,9 +396,10 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
return getFilter().getShowFolderState();
}
+static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
+
void LLInventoryPanel::modelChanged(U32 mask)
{
- static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
LLFastTimer t2(FTM_REFRESH);
if (!mViewsInitialized) return;
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index dd402de394..2a131eff58 100755
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -141,7 +141,6 @@ void LLLandmarkList::processGetAssetReply(
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
// SJB: No use case for a notification here. Use lldebugs instead
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
{
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 2d9385390b..8b088da12e 100755
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -48,6 +48,7 @@
/* misc headers */
#include "llscrolllistctrl.h"
#include "llfilepicker.h"
+#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
#include "llviewerobject.h"
@@ -378,7 +379,7 @@ std::vector<LLViewerObject*> LLLocalBitmap::prepUpdateObjects(LLUUID old_id, U32
{
std::vector<LLViewerObject*> obj_list;
LLViewerFetchedTexture* old_texture = gTextureList.findImage(old_id);
-
+
for(U32 face_iterator = 0; face_iterator < old_texture->getNumFaces(channel); face_iterator++)
{
// getting an object from a face
@@ -451,7 +452,7 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel)
switch(channel)
{
case LLRender::DIFFUSE_MAP:
- {
+ {
object->setTETexture(face_iter, new_id);
update_tex = true;
break;
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 2ee84bf46e..47c077dcab 100755
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -30,11 +30,11 @@
#include "llavatarappearancedefines.h"
#include "lleventtimer.h"
-#include "llimage.h"
#include "llpointer.h"
#include "llwearabletype.h"
class LLScrollListCtrl;
+class LLImageRaw;
class LLViewerObject;
class LLLocalBitmap
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d79f1040bb..9b05c75617 100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -240,7 +240,7 @@ void LLManipRotate::render()
if (mManipPart == LL_ROT_Z)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.pushMatrix();
{
// selected part
@@ -251,7 +251,7 @@ void LLManipRotate::render()
}
else if (mManipPart == LL_ROT_Y)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.pushMatrix();
{
gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
@@ -262,7 +262,7 @@ void LLManipRotate::render()
}
else if (mManipPart == LL_ROT_X)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.pushMatrix();
{
gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
@@ -273,13 +273,13 @@ void LLManipRotate::render()
}
else if (mManipPart == LL_ROT_ROLL)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
}
else if (mManipPart == LL_NO_PART)
{
if (mHighlightedPart == LL_NO_PART)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
}
LLGLEnable cull_face(GL_CULL_FACE);
@@ -294,7 +294,7 @@ void LLManipRotate::render()
{
if (mHighlightedPart == LL_ROT_Z)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);
// hovering over part
gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i);
@@ -312,7 +312,7 @@ void LLManipRotate::render()
gGL.rotatef( 90.f, 1.f, 0.f, 0.f );
if (mHighlightedPart == LL_ROT_Y)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);
// hovering over part
gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i);
@@ -330,7 +330,7 @@ void LLManipRotate::render()
gGL.rotatef( 90.f, 0.f, 1.f, 0.f );
if (mHighlightedPart == LL_ROT_X)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);
// hovering over part
@@ -346,7 +346,7 @@ void LLManipRotate::render()
if (mHighlightedPart == LL_ROT_ROLL)
{
- mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
}
}
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index ae0884ac5d..15788d6ffd 100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -535,11 +535,11 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
{
if (mHighlightedPart == MANIPULATOR_IDS[i])
{
- mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
}
else
{
- mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
+ mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));
}
}
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index b62db70ec8..01337cfaed 100755
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1904,18 +1904,18 @@ void LLManipTranslate::renderTranslationHandles()
{
if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)
{
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
}
else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)
{
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
}
else
{
- mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
- mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
+ mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));
}
}
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 2075aeed63..9298d6952f 100755
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -392,7 +392,7 @@ BOOL LLMediaCtrl::postBuild ()
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
- setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));
return TRUE;
}
@@ -422,7 +422,7 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
////////////////////////////////////////////////////////////////////////////////
//
-void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
+void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility )
{
llinfos << "visibility changed to " << (new_visibility?"true":"false") << llendl;
if(mMediaSource)
@@ -450,7 +450,7 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
////////////////////////////////////////////////////////////////////////////////
//
-void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility )
+void LLMediaCtrl::onVisibilityChanged ( const LLSD& new_visibility )
{
// set state of frequent updates automatically if visibility changes
if ( new_visibility.asBoolean() )
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 7f2a5e1642..db501cdb8c 100755
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -149,7 +149,7 @@ public:
// over-rides
virtual BOOL handleKeyHere( KEY key, MASK mask);
- virtual void handleVisibilityChange ( BOOL new_visibility );
+ virtual void onVisibilityChange ( BOOL new_visibility );
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual void draw();
@@ -171,7 +171,7 @@ public:
void convertInputCoords(S32& x, S32& y);
private:
- void onVisibilityChange ( const LLSD& new_visibility );
+ void onVisibilityChanged ( const LLSD& new_visibility );
void onPopup(const LLSD& notification, const LLSD& response);
const S32 mTextureDepthBytes;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index b47fe9d4b1..55347039ac 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -26,8 +26,7 @@
#include "llviewerprecompiledheaders.h"
-#include "apr_pools.h"
-#include "apr_dso.h"
+#include "llapr.h"
#include "llhttpstatuscodes.h"
#include "llmeshrepository.h"
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index dea90b9042..7cf1d177ac 100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -162,7 +162,7 @@ void LLNetMap::draw()
static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
if (auto_center)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
}
// Prepare a scissor region
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 862e4be203..50d0b4256b 100755
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -52,6 +52,7 @@
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
+#include "llviewertexture.h"
#include "lltrans.h"
#include "llscrollcontainer.h"
#include "llstatusbar.h"
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index e71dba5cae..a499fa1d87 100755
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -30,6 +30,7 @@
#include "llpanel.h"
#include "llviewerwearable.h"
#include "lluictrl.h"
+#include "lllocaltextureobject.h"
#include "llscrollingpanellist.h"
#include "llvisualparam.h"
#include "lltoolmorph.h"
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 911af9df04..7ef427fa3e 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -324,7 +324,7 @@ void LLPanelFace::sendBump(U32 bumpiness)
{
LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
if (bumpiness < BUMPY_TEXTURE)
- {
+{
LL_DEBUGS("Materials") << "clearing bumptexture control" << LL_ENDL;
bumpytexture_ctrl->clear();
bumpytexture_ctrl->setImageAssetID(LLUUID());
@@ -345,7 +345,7 @@ void LLPanelFace::sendBump(U32 bumpiness)
//
LLSelectedTEMaterial::setNormalID(this, current_normal_map);
- LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
+ LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
}
void LLPanelFace::sendTexGen()
@@ -361,7 +361,7 @@ void LLPanelFace::sendShiny(U32 shininess)
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
if (shininess < SHINY_TEXTURE)
- {
+{
texture_ctrl->clear();
texture_ctrl->setImageAssetID(LLUUID());
}
@@ -648,7 +648,7 @@ void LLPanelFace::updateUI()
// only turn on auto-adjust button if there is a media renderer and the media is loaded
getChildView("button align")->setEnabled(editable);
-
+
LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
if (combobox_matmedia)
{
@@ -683,15 +683,15 @@ void LLPanelFace::updateUI()
bool identical_diffuse = false;
bool identical_norm = false;
bool identical_spec = false;
-
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
LLUUID id;
LLUUID normmap_id;
LLUUID specmap_id;
-
+
// Color swatch
{
getChildView("color label")->setEnabled(editable);
@@ -702,7 +702,7 @@ void LLPanelFace::updateUI()
bool identical_color = false;
if(mColorSwatch)
- {
+ {
LLSelectedTE::getColor(color, identical_color);
mColorSwatch->setOriginal(color);
@@ -734,7 +734,7 @@ void LLPanelFace::updateUI()
LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
if (combobox_shininess)
- {
+ {
combobox_shininess->selectNthItem((S32)shiny);
}
@@ -747,15 +747,15 @@ void LLPanelFace::updateUI()
getChildView("label environment")->setEnabled(editable);
getChildView("environment")->setEnabled(editable);
getChildView("label shinycolor")->setEnabled(editable);
-
+
getChild<LLUICtrl>("combobox shininess")->setTentative(!identical_spec);
getChild<LLUICtrl>("glossiness")->setTentative(!identical_spec);
getChild<LLUICtrl>("environment")->setTentative(!identical_spec);
getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
-
+
LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
if(mShinyColorSwatch)
- {
+ {
mShinyColorSwatch->setValid(editable);
mShinyColorSwatch->setEnabled( editable );
mShinyColorSwatch->setCanApplyImmediately( editable );
@@ -763,7 +763,7 @@ void LLPanelFace::updateUI()
U8 bumpy = 0;
// Bumpy
- {
+ {
bool identical_bumpy = false;
LLSelectedTE::getBumpmap(bumpy,identical_bumpy);
@@ -773,18 +773,18 @@ void LLPanelFace::updateUI()
bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
if (combobox_bumpiness)
- {
+ {
combobox_bumpiness->selectNthItem((S32)bumpy);
- }
+ }
else
- {
+ {
llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
- }
+ }
getChildView("combobox bumpiness")->setEnabled(editable);
getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
getChildView("label bumpiness")->setEnabled(editable);
- }
+ }
// Texture
{
@@ -812,9 +812,9 @@ void LLPanelFace::updateUI()
default:
{
llwarns << "Unexpected tex format in LLPanelFace...resorting to no alpha" << llendl;
- }
+ }
break;
- }
+ }
if(LLViewerMedia::textureHasMedia(id))
{
@@ -852,8 +852,8 @@ void LLPanelFace::updateUI()
updateAlphaControls();
- if(texture_ctrl)
- {
+ if(texture_ctrl)
+ {
if (identical_diffuse)
{
texture_ctrl->setTentative( FALSE );
@@ -865,22 +865,22 @@ void LLPanelFace::updateUI()
getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
}
else if (id.isNull())
- {
- // None selected
- texture_ctrl->setTentative( FALSE );
- texture_ctrl->setEnabled( FALSE );
- texture_ctrl->setImageAssetID( LLUUID::null );
+ {
+ // None selected
+ texture_ctrl->setTentative( FALSE );
+ texture_ctrl->setEnabled( FALSE );
+ texture_ctrl->setImageAssetID( LLUUID::null );
getChildView("combobox alphamode")->setEnabled( FALSE );
getChildView("label alphamode")->setEnabled( FALSE );
getChildView("maskcutoff")->setEnabled( FALSE);
getChildView("label maskcutoff")->setEnabled( FALSE );
- }
- else
- {
- // Tentative: multiple selected with different textures
- texture_ctrl->setTentative( TRUE );
- texture_ctrl->setEnabled( editable );
- texture_ctrl->setImageAssetID( id );
+ }
+ else
+ {
+ // Tentative: multiple selected with different textures
+ texture_ctrl->setTentative( TRUE );
+ texture_ctrl->setEnabled( editable );
+ texture_ctrl->setImageAssetID( id );
getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
@@ -895,20 +895,20 @@ void LLPanelFace::updateUI()
shinytexture_ctrl->setTentative( FALSE );
shinytexture_ctrl->setEnabled( editable );
shinytexture_ctrl->setImageAssetID( specmap_id );
- }
+ }
else if (specmap_id.isNull())
{
shinytexture_ctrl->setTentative( FALSE );
shinytexture_ctrl->setEnabled( editable );
shinytexture_ctrl->setImageAssetID( LLUUID::null );
- }
+ }
else
{
shinytexture_ctrl->setTentative( TRUE );
shinytexture_ctrl->setEnabled( editable );
shinytexture_ctrl->setImageAssetID( specmap_id );
- }
- }
+ }
+ }
if (bumpytexture_ctrl)
{
@@ -939,7 +939,7 @@ void LLPanelFace::updateUI()
{
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
align_planar = (cb_planar_align && cb_planar_align->get());
-
+
bool enabled = (editable && isIdenticalPlanarTexgen());
childSetValue("checkbox planar align", align_planar && enabled);
childSetEnabled("checkbox planar align", enabled);
@@ -1132,7 +1132,7 @@ void LLPanelFace::updateUI()
F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
-
+
getChildView("TexRot")->setEnabled(editable);
getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
@@ -1153,10 +1153,10 @@ void LLPanelFace::updateUI()
getChild<LLUICtrl>("glow")->setValue(glow);
getChild<LLUICtrl>("glow")->setTentative(!identical_glow);
getChildView("glow")->setEnabled(editable);
- getChildView("glow label")->setEnabled(editable);
+ getChildView("glow label")->setEnabled(editable);
}
- {
+ {
LLCtrlSelectionInterface* combobox_texgen = childGetSelectionInterface("combobox texgen");
if (combobox_texgen)
{
@@ -1164,9 +1164,9 @@ void LLPanelFace::updateUI()
combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
}
else
- {
+ {
llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
- }
+ }
getChildView("combobox texgen")->setEnabled(editable);
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
@@ -1182,7 +1182,7 @@ void LLPanelFace::updateUI()
{
getChild<LLUICtrl>("rpt")->setValue(getString("string repeats per face"));
}
- }
+ }
{
U8 fullbright_flag = 0;
@@ -1194,7 +1194,7 @@ void LLPanelFace::updateUI()
getChildView("checkbox fullbright")->setEnabled(editable);
getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
}
-
+
// Repeats per meter
{
F32 repeats_diff = 1.f;
@@ -1211,7 +1211,7 @@ void LLPanelFace::updateUI()
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
if (mComboTexGen)
- {
+ {
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
BOOL enabled = editable && (index != 1);
BOOL identical_repeats = true;
@@ -1219,26 +1219,26 @@ void LLPanelFace::updateUI()
U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
switch (material_type)
- {
+ {
default:
case MATTYPE_DIFFUSE:
- {
+ {
enabled = editable && !id.isNull();
identical_repeats = identical_diff_repeats;
repeats = repeats_diff;
- }
+ }
break;
case MATTYPE_SPECULAR:
- {
+ {
enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
identical_repeats = identical_spec_repeats;
repeats = repeats_spec;
- }
+ }
break;
case MATTYPE_NORMAL:
- {
+ {
enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
identical_repeats = identical_norm_repeats;
repeats = repeats_norm;
@@ -1278,14 +1278,14 @@ void LLPanelFace::updateUI()
if (!mIsAlpha)
{ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
- }
+ }
combobox_alphamode->selectNthItem(alpha_mode);
- }
- else
- {
+ }
+ else
+ {
llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
- }
+ }
getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
updateAlphaControls();
@@ -1297,15 +1297,15 @@ void LLPanelFace::updateUI()
texture_ctrl->setImageAssetID(material->getSpecularID());
if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
- {
+ {
material->getSpecularOffset(offset_x,offset_y);
material->getSpecularRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
- {
+ {
repeat_x *= 2.0f;
repeat_y *= 2.0f;
- }
+ }
rot = material->getSpecularRotation();
getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
@@ -1317,13 +1317,13 @@ void LLPanelFace::updateUI()
getChild<LLUICtrl>("environment")->setValue(material->getEnvironmentIntensity());
updateShinyControls(!material->getSpecularID().isNull(), true);
- }
+ }
// Assert desired colorswatch color to match material AFTER updateShinyControls
// to avoid getting overwritten with the default on some UI state changes.
//
if (!material->getSpecularID().isNull())
- {
+ {
getChild<LLColorSwatchCtrl>("shinycolorswatch")->setOriginal(material->getSpecularLightColor());
getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
}
@@ -1331,12 +1331,12 @@ void LLPanelFace::updateUI()
// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
// NORSPEC-103
LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP;
-
+
if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull())
||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull()))
- {
+ {
channel_to_edit = LLRender::DIFFUSE_MAP;
- }
+ }
LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit);
@@ -1345,16 +1345,16 @@ void LLPanelFace::updateUI()
texture_ctrl->setImageAssetID(material->getNormalID());
if (!material->getNormalID().isNull())
- {
+ {
material->getNormalOffset(offset_x,offset_y);
material->getNormalRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
- {
+ {
repeat_x *= 2.0f;
repeat_y *= 2.0f;
- }
-
+ }
+
rot = material->getNormalRotation();
getChild<LLUICtrl>("bumpyScaleU")->setValue(repeat_x);
getChild<LLUICtrl>("bumpyScaleV")->setValue(repeat_y);
@@ -1410,7 +1410,7 @@ void LLPanelFace::updateUI()
getChildView("button align")->setEnabled(FALSE);
//getChildView("has media")->setEnabled(FALSE);
//getChildView("media info set")->setEnabled(FALSE);
-
+
updateVisibility();
// Set variable values for numeric expressions
@@ -1768,7 +1768,7 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
void LLPanelFace::onCommitTexture( const LLSD& data )
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ add(LLStatViewer::EDIT_TEXTURE, 1);
sendTexture();
}
@@ -2023,8 +2023,8 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
{
case MATTYPE_DIFFUSE:
{
- LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
- }
+ LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
+}
break;
case MATTYPE_NORMAL:
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42c1f6bd48..7fba58156c 100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -449,7 +449,7 @@ private:
{
public:
- static void getFace(LLFace*& face_to_return, bool& identical_face);
+ static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
static void getTexId(LLUUID& id, bool& identical);
static void getObjectScaleS(F32& scale_s, bool& identical);
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index a50d9074f7..74c810ea79 100755
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -202,7 +202,7 @@ void LLPanelNearByMedia::onTopLost()
/*virtual*/
-void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )
+void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility )
{
if (new_visibility)
{
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index c3634de9b4..a9c1b190cf 100755
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -48,7 +48,7 @@ public:
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
/*virtual*/ void onTopLost();
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c09d4393c8..7648e12f96 100755
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -169,7 +169,7 @@ public:
return menu;
}
-
+
private:
static void onCreate(const LLSD& param)
{
@@ -481,7 +481,7 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
- setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChanged, this, _2));
mWearablesGearMenuBtn = getChild<LLMenuButton>("wearables_gear_menu_btn");
mGearMenuBtn = getChild<LLMenuButton>("gear_menu_btn");
@@ -767,7 +767,7 @@ void LLPanelOutfitEdit::onPlusBtnClicked(void)
}
}
-void LLPanelOutfitEdit::onVisibilityChange(const LLSD &in_visible_chain)
+void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain)
{
showAddWearablesPanel(false);
mWearableItemsList->resetSelection();
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 5d4b8d4644..30870daf40 100755
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -145,7 +145,7 @@ public:
void updatePlusButton();
void onPlusBtnClicked(void);
- void onVisibilityChange(const LLSD &in_visible_chain);
+ void onVisibilityChanged(const LLSD &in_visible_chain);
void applyFolderViewFilter(EFolderViewItemType type);
void applyListViewFilter(EListViewItemType type);
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 4740964dee..123e2891d6 100755
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -38,6 +38,7 @@ class LLFilterEditor;
class LLGroupList;
class LLMenuButton;
class LLTabContainer;
+class LLNetMap;
class LLPanelPeople
: public LLPanel
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 131e8e9359..79bcf15c1d 100755
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -913,7 +913,6 @@ bool callback_deed_to_group(const LLSD& notification, const LLSD& response)
if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED)))
{
LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE);
-// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
}
}
return false;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 5d9971c16c..da201ca36a 100755
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -302,9 +302,9 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)
}
// virtual
-void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
+void LLPanelPlaceProfile::onVisibilityChange(BOOL new_visibility)
{
- LLPanel::handleVisibilityChange(new_visibility);
+ LLPanel::onVisibilityChange(new_visibility);
LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
if (!parcel_mgr)
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index f4c6145881..01adfd4940 100755
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo
public:
LLPanelPlaceProfile();
/*virtual*/ ~LLPanelPlaceProfile();
-
+
/*virtual*/ BOOL postBuild();
/*virtual*/ void resetLocation();
@@ -47,7 +47,7 @@ public:
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
// Displays information about the currently selected parcel
// without sending a request to the server.
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 6c2a01fc82..dc18cc6081 100755
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -998,9 +998,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
}
// virtual
-void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility)
+void LLPanelPlaces::onVisibilityChange(BOOL new_visibility)
{
- LLPanel::handleVisibilityChange(new_visibility);
+ LLPanel::onVisibilityChange(new_visibility);
if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE)
{
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 85bdc2c4e1..b6019ca32e 100755
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -102,7 +102,7 @@ private:
void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
- /*virtual*/ void handleVisibilityChange(BOOL new_visibility);
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
void updateVerbs();
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index e2e7006773..435797bf80 100755
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -36,6 +36,7 @@
#include "lltabcontainer.h"
#include "llviewercontrol.h"
#include "llviewernetwork.h"
+#include "llweb.h"
static const std::string PANEL_PICKS = "panel_picks";
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 9dd665198f..3830847d74 100755
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -169,7 +169,7 @@ BOOL LLPanelTopInfoBar::postBuild()
mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(
boost::bind(&LLPanelTopInfoBar::onAgentParcelChange, this));
- setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChanged, this, _2));
return TRUE;
}
@@ -186,7 +186,7 @@ void LLPanelTopInfoBar::onNavBarShowParcelPropertiesCtrlChanged()
// when panel is shown, all minimized floaters should be shifted downwards to prevent overlapping of
// PanelTopInfoBar. See EXT-7951.
-void LLPanelTopInfoBar::onVisibilityChange(const LLSD& show)
+void LLPanelTopInfoBar::onVisibilityChanged(const LLSD& show)
{
// this height is used as a vertical offset for ALREADY MINIMIZED floaters
// when PanelTopInfoBar visibility changes
diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h
index d58d95be90..f37bd9c048 100755
--- a/indra/newview/llpaneltopinfobar.h
+++ b/indra/newview/llpaneltopinfobar.h
@@ -57,7 +57,7 @@ public:
/**
* Called when the top info bar gets shown or hidden
*/
- void onVisibilityChange(const LLSD& show);
+ void onVisibilityChanged(const LLSD& show);
boost::signals2::connection setResizeCallback( const resize_signal_t::slot_type& cb );
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 6be2ea6481..1782afddd9 100755
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
@@ -85,7 +85,7 @@ BOOL LLPanelVoiceDeviceSettings::postBuild()
}
// virtual
-void LLPanelVoiceDeviceSettings::handleVisibilityChange ( BOOL new_visibility )
+void LLPanelVoiceDeviceSettings::onVisibilityChange ( BOOL new_visibility )
{
if (new_visibility)
{
diff --git a/indra/newview/llpanelvoicedevicesettings.h b/indra/newview/llpanelvoicedevicesettings.h
index ba3bcad0dc..83464f476a 100755
--- a/indra/newview/llpanelvoicedevicesettings.h
+++ b/indra/newview/llpanelvoicedevicesettings.h
@@ -44,7 +44,7 @@ public:
void initialize();
void cleanup();
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
void setUseTuningMode(bool use) { mUseTuningMode = use; };
diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp
index 5fec6d967d..59ed53815b 100755
--- a/indra/newview/llpanelvoiceeffect.cpp
+++ b/indra/newview/llpanelvoiceeffect.cpp
@@ -35,6 +35,7 @@
#include "lltrans.h"
#include "lltransientfloatermgr.h"
#include "llvoiceclient.h"
+#include "llweb.h"
static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect");
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index aea7b33d7f..cb00f742cc 100755
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -87,7 +87,7 @@ void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)
}
/*virtual*/
-void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility )
+void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility )
{
if (new_visibility)
{
diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h
index 0d86e6bd28..b843fab756 100755
--- a/indra/newview/llpanelvolumepulldown.h
+++ b/indra/newview/llpanelvolumepulldown.h
@@ -42,7 +42,7 @@ class LLPanelVolumePulldown : public LLPanel
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
/*virtual*/ void onTopLost();
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
/*virtual*/ BOOL postBuild();
private:
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index f47928b131..bda603262d 100755
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -253,7 +253,7 @@ void LLPreviewGesture::onUpdateSucceeded()
refresh();
}
-void LLPreviewGesture::onVisibilityChange ( const LLSD& new_visibility )
+void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility )
{
if (new_visibility.asBoolean())
{
@@ -333,7 +333,7 @@ LLPreviewGesture::~LLPreviewGesture()
BOOL LLPreviewGesture::postBuild()
{
- setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2));
+ setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2));
LLLineEditor* edit;
LLComboBox* combo;
@@ -883,8 +883,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index fd4fcf9d8f..7ce5706a0d 100755
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -102,7 +102,7 @@ protected:
// "Sound", "Chat", or "Wait"
LLScrollListItem* addStep(const enum EStepType step_type);
- void onVisibilityChange ( const LLSD& new_visibility );
+ void onVisibilityChanged ( const LLSD& new_visibility );
static std::string getLabel(std::vector<std::string> labels);
static void updateLabel(LLScrollListItem* item);
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 3a9360fd23..97c9de4b72 100755
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -339,8 +339,6 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 968a912ea2..516ecedbc8 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -946,7 +946,7 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata)
void LLScriptEdCore::doSave( BOOL close_after_save )
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+ add(LLStatViewer::LSL_SAVES, 1);
if( mSaveCallback )
{
@@ -1150,8 +1150,7 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
void LLScriptEdCore::onBtnSaveToFile( void* userdata )
{
-
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+ add(LLStatViewer::LSL_SAVES, 1);
LLScriptEdCore* self = (LLScriptEdCore*) userdata;
@@ -1674,8 +1673,6 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
@@ -1906,8 +1903,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
new file mode 100644
index 0000000000..ed9eeb9330
--- /dev/null
+++ b/indra/newview/llscenemonitor.cpp
@@ -0,0 +1,702 @@
+/**
+ * @file llscenemonitor.cpp
+ * @brief monitor the scene loading process.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llrendertarget.h"
+#include "llscenemonitor.h"
+#include "llviewerwindow.h"
+#include "llviewerdisplay.h"
+#include "llviewercontrol.h"
+#include "llviewershadermgr.h"
+#include "llui.h"
+#include "llstartup.h"
+#include "llappviewer.h"
+#include "llwindow.h"
+#include "llpointer.h"
+#include "llspatialpartition.h"
+#include "llagent.h"
+#include "pipeline.h"
+#include "llviewerpartsim.h"
+
+LLSceneMonitorView* gSceneMonitorView = NULL;
+
+//
+//The procedures of monitoring when the scene finishes loading visually,
+//i.e., no pixel differences among frames, are:
+//1, freeze all dynamic objects and avatars;
+//2, (?) disable all sky and water;
+//3, capture frames periodically, by calling "capture()";
+//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff;
+//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "calcDiffAggregate()";
+//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()";
+//END.
+//
+
+LLSceneMonitor::LLSceneMonitor() :
+ mEnabled(false),
+ mDiff(NULL),
+ mDiffResult(0.f),
+ mDiffTolerance(0.1f),
+ mDiffState(WAITING_FOR_NEXT_DIFF),
+ mDebugViewerVisible(false),
+ mQueryObject(0),
+ mDiffPixelRatio(0.5f)
+{
+ mFrames[0] = NULL;
+ mFrames[1] = NULL;
+}
+
+LLSceneMonitor::~LLSceneMonitor()
+{
+ mDiffState = VIEWER_QUITTING;
+ reset();
+
+ mDitheringTexture = NULL;
+}
+
+void LLSceneMonitor::reset()
+{
+ delete mFrames[0];
+ delete mFrames[1];
+ delete mDiff;
+
+ mFrames[0] = NULL;
+ mFrames[1] = NULL;
+ mDiff = NULL;
+
+ mMonitorRecording.reset();
+ mSceneLoadRecording.reset();
+
+ unfreezeScene();
+
+ if(mQueryObject > 0)
+ {
+ LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(mQueryObject);
+ mQueryObject = 0;
+ }
+}
+
+void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height)
+{
+#if 1
+ //4 * 4 matrix
+ mDitherMatrixWidth = 4;
+ S32 dither_matrix[4][4] =
+ {
+ {1, 9, 3, 11},
+ {13, 5, 15, 7},
+ {4, 12, 2, 10},
+ {16, 8, 14, 6}
+ };
+
+ mDitherScale = 255.f / 17;
+#else
+ //8 * 8 matrix
+ mDitherMatrixWidth = 16;
+ S32 dither_matrix[16][16] =
+ {
+ {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},
+ {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},
+ {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},
+ {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
+ {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
+ {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
+ {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
+ {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22},
+ {1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},
+ {33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},
+ {9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},
+ {41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24},
+ {3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62},
+ {35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30},
+ {11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54},
+ {43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}
+ };
+
+ mDitherScale = 255.f / 65;
+#endif
+
+ LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3);
+ U8* data = image_raw->getData();
+ for (S32 i = 0; i < mDitherMatrixWidth; i++)
+ {
+ for (S32 j = 0; j < mDitherMatrixWidth; j++)
+ {
+ U8 val = dither_matrix[i][j];
+ *data++ = val;
+ *data++ = val;
+ *data++ = val;
+ }
+ }
+
+ mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), FALSE) ;
+ mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP);
+ mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT);
+
+ mDitherScaleS = (F32)width / mDitherMatrixWidth;
+ mDitherScaleT = (F32)height / mDitherMatrixWidth;
+}
+
+void LLSceneMonitor::setDebugViewerVisible(bool visible)
+{
+ mDebugViewerVisible = visible;
+}
+
+LLRenderTarget& LLSceneMonitor::getCaptureTarget()
+{
+ LLRenderTarget* cur_target = NULL;
+
+ S32 width = gViewerWindow->getWorldViewWidthRaw();
+ S32 height = gViewerWindow->getWorldViewHeightRaw();
+
+ if(!mFrames[0])
+ {
+ mFrames[0] = new LLRenderTarget();
+ mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ gGL.getTexUnit(0)->bind(mFrames[0]);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ cur_target = mFrames[0];
+ }
+ else if(!mFrames[1])
+ {
+ mFrames[1] = new LLRenderTarget();
+ mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ gGL.getTexUnit(0)->bind(mFrames[1]);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ cur_target = mFrames[1];
+ }
+ else //swap
+ {
+ cur_target = mFrames[0];
+ mFrames[0] = mFrames[1];
+ mFrames[1] = cur_target;
+ }
+
+ if(cur_target->getWidth() != width || cur_target->getHeight() != height) //size changed
+ {
+ cur_target->resize(width, height, GL_RGB);
+ }
+
+ // we're promising the target exists
+ return *cur_target;
+}
+
+void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp)
+{
+ mAvatarPauseHandles.push_back(avatarp->requestPause());
+}
+
+void LLSceneMonitor::freezeScene()
+{
+ //freeze all avatars
+ for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ iter != LLCharacter::sInstances.end(); ++iter)
+ {
+ freezeAvatar((LLCharacter*)(*iter));
+ }
+
+ // freeze everything else
+ gSavedSettings.setBOOL("FreezeTime", TRUE);
+
+ //disable sky, water and clouds
+ gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
+
+ //disable particle system
+ LLViewerPartSim::getInstance()->enable(false);
+}
+
+void LLSceneMonitor::unfreezeScene()
+{
+ //thaw all avatars
+ mAvatarPauseHandles.clear();
+
+ if(mDiffState == VIEWER_QUITTING)
+ {
+ return;
+ }
+
+ // thaw everything else
+ gSavedSettings.setBOOL("FreezeTime", FALSE);
+
+ //enable sky, water and clouds
+ gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES);
+
+ //enable particle system
+ LLViewerPartSim::getInstance()->enable(true);
+}
+
+void LLSceneMonitor::capture()
+{
+ static U32 last_capture_time = 0;
+ static LLCachedControl<bool> monitor_enabled(gSavedSettings, "SceneLoadingMonitorEnabled");
+ static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime");
+ static LLFrameTimer timer;
+
+ if (mEnabled
+ && (mMonitorRecording.getSum(*LLViewerCamera::getVelocityStat()) > 0.1f
+ || mMonitorRecording.getSum(*LLViewerCamera::getAngularVelocityStat()) > 0.05f))
+ {
+ reset();
+ freezeScene();
+ }
+
+ bool enabled = monitor_enabled || mDebugViewerVisible;
+ if(mEnabled != enabled)
+ {
+ if(mEnabled)
+ {
+ unfreezeScene();
+ }
+ else
+ {
+ reset();
+ freezeScene();
+ }
+
+ mEnabled = enabled;
+ }
+
+ if(timer.getElapsedTimeF32() > scene_load_sample_time()
+ && mEnabled
+ && LLGLSLShader::sNoFixedFunction
+ && last_capture_time != gFrameCount)
+ {
+ mSceneLoadRecording.resume();
+ mMonitorRecording.resume();
+
+ timer.reset();
+
+ last_capture_time = gFrameCount;
+
+ LLRenderTarget& cur_target = getCaptureTarget();
+
+ U32 old_FBO = LLRenderTarget::sCurFBO;
+
+ gGL.getTexUnit(0)->bind(&cur_target);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer.
+
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, cur_target.getWidth(), cur_target.getHeight()); //copy the content
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, old_FBO);
+
+ mDiffState = NEED_DIFF;
+ }
+}
+
+bool LLSceneMonitor::needsUpdate() const
+{
+ return mDiffState == NEED_DIFF;
+}
+
+static LLFastTimer::DeclareTimer FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE("Generate Scene Load Dither Texture");
+static LLFastTimer::DeclareTimer FTM_SCENE_LOAD_IMAGE_DIFF("Scene Load Image Diff");
+
+void LLSceneMonitor::compare()
+{
+ if(mDiffState != NEED_DIFF)
+ {
+ return;
+ }
+
+ if(!mFrames[0] || !mFrames[1])
+ {
+ return;
+ }
+ if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight())
+ { //size does not match
+ return;
+ }
+
+ LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF);
+ mDiffState = EXECUTE_DIFF;
+
+ S32 width = gViewerWindow->getWindowWidthRaw();
+ S32 height = gViewerWindow->getWindowHeightRaw();
+ if(!mDiff)
+ {
+ LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE);
+ mDiff = new LLRenderTarget();
+ mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
+
+ generateDitheringTexture(width, height);
+ }
+ else if(mDiff->getWidth() != width || mDiff->getHeight() != height)
+ {
+ LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE);
+ mDiff->resize(width, height, GL_RGBA);
+ generateDitheringTexture(width, height);
+ }
+
+ mDiff->bindTarget();
+ mDiff->clear();
+
+ gTwoTextureCompareProgram.bind();
+
+ gTwoTextureCompareProgram.uniform1f("dither_scale", mDitherScale);
+ gTwoTextureCompareProgram.uniform1f("dither_scale_s", mDitherScaleS);
+ gTwoTextureCompareProgram.uniform1f("dither_scale_t", mDitherScaleT);
+
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->bind(mFrames[0]);
+ gGL.getTexUnit(0)->activate();
+
+ gGL.getTexUnit(1)->activate();
+ gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->bind(mFrames[1]);
+ gGL.getTexUnit(1)->activate();
+
+ gGL.getTexUnit(2)->activate();
+ gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->bind(mDitheringTexture);
+ gGL.getTexUnit(2)->activate();
+
+ gl_rect_2d_simple_tex(width, height);
+
+ mDiff->flush();
+
+ gTwoTextureCompareProgram.unbind();
+
+ gGL.getTexUnit(0)->disable();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(1)->disable();
+ gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(2)->disable();
+ gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if (!mDebugViewerVisible)
+ {
+ calcDiffAggregate();
+ }
+}
+
+//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it.
+void LLSceneMonitor::calcDiffAggregate()
+{
+ LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF);
+
+ if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible)
+ {
+ return;
+ }
+
+ if(!mQueryObject)
+ {
+ mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName();
+ }
+
+ LLGLDepthTest depth(true, false, GL_ALWAYS);
+ if(!mDebugViewerVisible)
+ {
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ }
+
+ LLGLSLShader* cur_shader = NULL;
+
+ cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+ gOneTextureFilterProgram.bind();
+ gOneTextureFilterProgram.uniform1f("tolerance", mDiffTolerance);
+
+ if(mDiffState == EXECUTE_DIFF)
+ {
+ glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject);
+ }
+
+ gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
+
+ if(mDiffState == EXECUTE_DIFF)
+ {
+ glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ mDiffState = WAIT_ON_RESULT;
+ }
+
+ gOneTextureFilterProgram.unbind();
+
+ if(cur_shader != NULL)
+ {
+ cur_shader->bind();
+ }
+
+ if(!mDebugViewerVisible)
+ {
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
+}
+
+static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference");
+void LLSceneMonitor::fetchQueryResult()
+{
+ LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF);
+
+ if(mDiffState == WAIT_ON_RESULT)
+ {
+ mDiffState = WAITING_FOR_NEXT_DIFF;
+
+ GLuint available = 0;
+ glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ if(available)
+ {
+ GLuint count = 0;
+ glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count);
+
+ mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face)
+
+ LL_DEBUGS("SceneMonitor") << "Frame difference: " << std::setprecision(4) << mDiffResult << LL_ENDL;
+ record(sFramePixelDiff, mDiffResult);
+
+ static LLCachedControl<F32> diff_threshold(gSavedSettings,"SceneLoadingPixelDiffThreshold");
+ if(mDiffResult > diff_threshold())
+ {
+ mSceneLoadRecording.extend();
+ llassert(mSceneLoadRecording.getAcceptedRecording().getLastRecording().getSum(LLStatViewer::FPS));
+ }
+ else
+ {
+ mSceneLoadRecording.getPotentialRecording().nextPeriod();
+ llassert(mSceneLoadRecording.getPotentialRecording().getLastRecording().getSum(LLStatViewer::FPS));
+ }
+ }
+ }
+}
+
+//dump results to a file _scene_xmonitor_results.csv
+void LLSceneMonitor::dumpToFile(std::string file_name)
+{ using namespace LLTrace;
+
+ if (!hasResults()) return;
+
+ LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;
+
+ std::ofstream os(file_name.c_str());
+
+ os << std::setprecision(10);
+
+ PeriodicRecording& scene_load_recording = mSceneLoadRecording.getAcceptedRecording();
+ const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
+
+ LLUnit<F64, LLUnits::Seconds> frame_time;
+
+ os << "Stat";
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+ os << ", " << frame_time.value();
+ }
+ os << '\n';
+
+ typedef TraceType<CountAccumulator> trace_count;
+ for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances();
+ it != end_it;
+ ++it)
+ {
+ std::ostringstream row;
+ row << std::setprecision(10);
+
+ row << it->getName();
+
+ const char* unit_label = it->getUnitLabel();
+ if(unit_label[0])
+ {
+ row << "(" << unit_label << ")";
+ }
+
+ S32 samples = 0;
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);
+ row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getSum(*it);
+ }
+
+ row << '\n';
+
+ if (samples > 0)
+ {
+ os << row.str();
+ }
+ }
+
+ typedef TraceType<EventAccumulator> trace_event;
+
+ for (trace_event::instance_iter it = trace_event::beginInstances(), end_it = trace_event::endInstances();
+ it != end_it;
+ ++it)
+ {
+ std::ostringstream row;
+ row << std::setprecision(10);
+ row << it->getName();
+
+ const char* unit_label = it->getUnitLabel();
+ if(unit_label[0])
+ {
+ row << "(" << unit_label << ")";
+ }
+
+ S32 samples = 0;
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);
+ row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it);
+ }
+
+ row << '\n';
+
+ if (samples > 0)
+ {
+ os << row.str();
+ }
+ }
+
+ typedef TraceType<SampleAccumulator> trace_sample;
+
+ for (trace_sample::instance_iter it = trace_sample::beginInstances(), end_it = trace_sample::endInstances();
+ it != end_it;
+ ++it)
+ {
+ std::ostringstream row;
+ row << std::setprecision(10);
+ row << it->getName();
+
+ const char* unit_label = it->getUnitLabel();
+ if(unit_label[0])
+ {
+ row << "(" << unit_label << ")";
+ }
+
+ S32 samples = 0;
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it);
+ row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it);
+ }
+
+ row << '\n';
+
+ if (samples > 0)
+ {
+ os << row.str();
+ }
+ }
+
+ typedef TraceType<MemStatAccumulator> trace_mem;
+ for (trace_mem::instance_iter it = trace_mem::beginInstances(), end_it = trace_mem::endInstances();
+ it != end_it;
+ ++it)
+ {
+ os << it->getName() << "(KiB)";
+
+ for (S32 frame = 1; frame <= frame_count; frame++)
+ {
+ os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).getAs<LLUnits::Kibibytes>();
+ }
+
+ os << '\n';
+ }
+
+ os.flush();
+ os.close();
+}
+
+//-------------------------------------------------------------------------------------------------------------
+//definition of class LLSceneMonitorView
+//-------------------------------------------------------------------------------------------------------------
+LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect)
+ : LLFloater(LLSD())
+{
+ setRect(rect);
+ setVisible(FALSE);
+
+ setCanMinimize(false);
+ setCanClose(true);
+}
+
+void LLSceneMonitorView::onClickCloseBtn()
+{
+ setVisible(false);
+}
+
+void LLSceneMonitorView::onVisibilityChange(BOOL visible)
+{
+ visible = visible && LLGLSLShader::sNoFixedFunction;
+ LLSceneMonitor::getInstance()->setDebugViewerVisible(visible);
+}
+
+void LLSceneMonitorView::draw()
+{
+ const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget();
+ if(!target)
+ {
+ return;
+ }
+
+ F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio();
+ S32 height = (S32)(target->getHeight() * ratio);
+ S32 width = (S32)(target->getWidth() * ratio);
+
+ LLRect new_rect;
+ new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
+ setRect(new_rect);
+
+ //draw background
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
+
+ LLSceneMonitor::getInstance()->calcDiffAggregate();
+
+ //show some texts
+ LLColor4 color = LLColor4::white;
+ S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
+
+ S32 lines = 0;
+ std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult());
+ LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+ lines++;
+
+ num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance());
+ LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+ lines++;
+
+ num_str = llformat("Sampling time: %.3f seconds", gSavedSettings.getF32("SceneLoadingMonitorSampleTime"));
+ LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+ lines++;
+
+ num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getAcceptedRecording().getDuration().value());
+ LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP);
+ lines++;
+
+ LLView::draw();
+}
+
diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h
new file mode 100644
index 0000000000..9717310da4
--- /dev/null
+++ b/indra/newview/llscenemonitor.h
@@ -0,0 +1,124 @@
+/**
+ * @file llscenemonitor.h
+ * @brief monitor the process of scene loading
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSCENE_MONITOR_H
+#define LL_LLSCENE_MONITOR_H
+
+#include "llsingleton.h"
+#include "llmath.h"
+#include "llfloater.h"
+#include "llcharacter.h"
+#include "lltracerecording.h"
+
+class LLCharacter;
+class LLRenderTarget;
+class LLViewerTexture;
+
+class LLSceneMonitor : public LLSingleton<LLSceneMonitor>
+{
+ LOG_CLASS(LLSceneMonitor);
+public:
+ LLSceneMonitor();
+ ~LLSceneMonitor();
+
+ void freezeAvatar(LLCharacter* avatarp);
+ void setDebugViewerVisible(bool visible);
+
+ void capture(); //capture the main frame buffer
+ void compare(); //compare the stored two buffers.
+ void fetchQueryResult();
+ void calcDiffAggregate();
+ void setDiffTolerance(F32 tol) {mDiffTolerance = tol;}
+
+ const LLRenderTarget* getDiffTarget() const {return mDiff;}
+ F32 getDiffTolerance() const {return mDiffTolerance;}
+ F32 getDiffResult() const { return mDiffResult;}
+ F32 getDiffPixelRatio() const { return mDiffPixelRatio;}
+ bool isEnabled()const {return mEnabled;}
+ bool needsUpdate() const;
+
+ const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;}
+ void dumpToFile(std::string file_name);
+ bool hasResults() const { return mSceneLoadRecording.getAcceptedRecording().getDuration() != 0;}
+
+private:
+ void freezeScene();
+ void unfreezeScene();
+ void reset();
+ LLRenderTarget& getCaptureTarget();
+ void generateDitheringTexture(S32 width, S32 height);
+
+private:
+ bool mEnabled;
+ bool mDebugViewerVisible;
+
+ enum EDiffState
+ {
+ WAITING_FOR_NEXT_DIFF,
+ NEED_DIFF,
+ EXECUTE_DIFF,
+ WAIT_ON_RESULT,
+ VIEWER_QUITTING
+ } mDiffState;
+
+ LLRenderTarget* mFrames[2];
+ LLRenderTarget* mDiff;
+
+ GLuint mQueryObject; //used for glQuery
+ F32 mDiffResult; //aggregate results of mDiff.
+ F32 mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance
+
+ F32 mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension
+
+ LLPointer<LLViewerTexture> mDitheringTexture;
+ S32 mDitherMatrixWidth;
+ F32 mDitherScale;
+ F32 mDitherScaleS;
+ F32 mDitherScaleT;
+
+ std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+
+ LLTrace::ExtendablePeriodicRecording mSceneLoadRecording;
+ LLTrace::Recording mMonitorRecording;
+};
+
+class LLSceneMonitorView : public LLFloater
+{
+public:
+ LLSceneMonitorView(const LLRect& rect);
+
+ virtual void draw();
+
+ virtual void onVisibilityChange(BOOL visible);
+
+protected:
+ virtual void onClickCloseBtn();
+};
+
+extern LLSceneMonitorView* gSceneMonitorView;
+
+#endif
+
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index db57848320..28765fbfb1 100755
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -30,6 +30,7 @@
#include <vector>
#include <openssl/x509.h>
#include <ostream>
+#include "llthread.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4250)
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 0cbdbe16a3..b47c2de768 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1557,7 +1557,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
}
// apply texture for the selected faces
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ add(LLStatViewer::EDIT_TEXTURE, 1);
object->setTEImage(te, image);
dialog_refresh_all();
@@ -3541,9 +3541,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,
gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
// Keep track of how many objects have been deleted.
- F64 obj_delete_count = LLViewerStats::getInstance()->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT);
- obj_delete_count += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount();
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_OBJECT_DELETE_COUNT, obj_delete_count );
+ add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount());
}
break;
case 1:
@@ -5913,7 +5911,7 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
tep->getScale(&diffuse_s,&diffuse_t);
-
+
if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
{
v.mV[s_axis] = diffuse_s*scale.mV[s_axis];
@@ -5925,7 +5923,7 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
v.mV[s_axis] = diffuse_s/scale.mV[s_axis];
v.mV[t_axis] = diffuse_t/scale.mV[t_axis];
mTextureScaleRatios.push_back(v);
- }
+ }
}
}
}
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index df413ab849..a405129a25 100755
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -142,7 +142,7 @@ BOOL LLSidepanelAppearance::postBuild()
mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook");
- setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChange,this,_2));
+ setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2));
return TRUE;
}
@@ -181,7 +181,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
mOpened = true;
}
-void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
+void LLSidepanelAppearance::onVisibilityChanged(const LLSD &new_visibility)
{
LLSD visibility;
visibility["visible"] = new_visibility.asBoolean();
@@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
{
gAgentCamera.changeCameraToDefault();
gAgentCamera.resetView();
- }
+ }
}
}
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index b0a6b9cf91..cde05a8d9b 100755
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -47,7 +47,7 @@ public:
virtual ~LLSidepanelAppearance();
/*virtual*/ BOOL postBuild();
- /*virtual*/ void onOpen(const LLSD& key);
+ /*virtual*/ void onOpen(const LLSD& key);
void refreshCurrentOutfitName(const std::string& name = "");
@@ -68,7 +68,7 @@ public:
private:
void onFilterEdit(const std::string& search_string);
- void onVisibilityChange ( const LLSD& new_visibility );
+ void onVisibilityChanged ( const LLSD& new_visibility );
void onOpenOutfitButtonClicked();
void onEditAppearanceButtonClicked();
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index ad7c939728..090ee64801 100755
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -162,7 +162,7 @@ BOOL LLSidepanelTaskInfo::postBuild()
return TRUE;
}
-/*virtual*/ void LLSidepanelTaskInfo::handleVisibilityChange ( BOOL visible )
+/*virtual*/ void LLSidepanelTaskInfo::onVisibilityChange ( BOOL visible )
{
if (visible)
{
@@ -945,7 +945,6 @@ static bool callback_deed_to_group(const LLSD& notification, const LLSD& respons
if (group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED)))
{
LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE);
-// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
}
}
return FALSE;
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index 05edcda5ed..a1479ef0e7 100755
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -50,7 +50,7 @@ public:
virtual ~LLSidepanelTaskInfo();
/*virtual*/ BOOL postBuild();
- /*virtual*/ void handleVisibilityChange ( BOOL new_visibility );
+ /*virtual*/ void onVisibilityChange ( BOOL new_visibility );
void setObjectSelection(LLObjectSelectionHandle selection);
diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h
index 9d7780c4f9..80ce99b774 100755
--- a/indra/newview/llsimplestat.h
+++ b/indra/newview/llsimplestat.h
@@ -99,43 +99,43 @@ public:
* values back to zero.
*/
void reset()
- {
- mCount = 0;
- mMin = Value(0);
- mMax = Value(0);
- mTotal = Value(0);
- }
+ {
+ mCount = 0;
+ mMin = Value(0);
+ mMax = Value(0);
+ mTotal = Value(0);
+ }
void record(Value v)
+ {
+ if (mCount)
+ {
+ mMin = llmin(mMin, v);
+ mMax = llmax(mMax, v);
+ }
+ else
{
- if (mCount)
- {
- mMin = llmin(mMin, v);
- mMax = llmax(mMax, v);
- }
- else
- {
- mMin = v;
- mMax = v;
- }
- mTotal += v;
- ++mCount;
+ mMin = v;
+ mMax = v;
}
+ mTotal += v;
+ ++mCount;
+ }
void merge(const LLSimpleStatMMM<VALUE_T> & src)
+ {
+ if (! mCount)
+ {
+ *this = src;
+ }
+ else if (src.mCount)
{
- if (! mCount)
- {
- *this = src;
- }
- else if (src.mCount)
- {
- mMin = llmin(mMin, src.mMin);
- mMax = llmax(mMax, src.mMax);
- mCount += src.mCount;
- mTotal += src.mTotal;
- }
+ mMin = llmin(mMin, src.mMin);
+ mMax = llmax(mMax, src.mMax);
+ mCount += src.mCount;
+ mTotal += src.mTotal;
}
+ }
inline U32 getCount() const { return mCount; }
inline Value getMin() const { return mMin; }
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 78401020a6..caa551d6fa 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -51,32 +51,16 @@
#include "llvoavatar.h"
#include "llvolumemgr.h"
#include "lltextureatlas.h"
-#include "llglslshader.h"
#include "llviewershadermgr.h"
static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");
static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition");
-const F32 SG_OCCLUSION_FUDGE = 0.25f;
-#define SG_DISCARD_TOLERANCE 0.01f
-
-#if LL_OCTREE_PARANOIA_CHECK
-#define assert_octree_valid(x) x->validate()
-#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates()
-#else
-#define assert_octree_valid(x)
-#define assert_states_valid(x)
-#endif
-
extern bool gShiftFrame;
static U32 sZombieGroups = 0;
U32 LLSpatialGroup::sNodeCount = 0;
-#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0
-
-std::set<GLuint> LLSpatialGroup::sPendingQueries;
-
U32 gOctreeMaxCapacity;
BOOL LLSpatialGroup::sNoDelete = FALSE;
@@ -84,47 +68,6 @@ BOOL LLSpatialGroup::sNoDelete = FALSE;
static F32 sLastMaxTexPriority = 1.f;
static F32 sCurMaxTexPriority = 1.f;
-class LLOcclusionQueryPool : public LLGLNamePool
-{
-public:
- LLOcclusionQueryPool()
- {
- mCurQuery = 1;
- }
-
-protected:
-
- std::list<GLuint> mAvailableName;
- GLuint mCurQuery;
-
- virtual GLuint allocateName()
- {
- GLuint ret = 0;
-
- if (!mAvailableName.empty())
- {
- ret = mAvailableName.front();
- mAvailableName.pop_front();
- }
- else
- {
- ret = mCurQuery++;
- }
-
- return ret;
- }
-
- virtual void releaseName(GLuint name)
- {
-#if LL_TRACK_PENDING_OCCLUSION_QUERIES
- LLSpatialGroup::sPendingQueries.erase(name);
-#endif
- llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
- mAvailableName.push_back(name);
- }
-};
-
-static LLOcclusionQueryPool sQueryPool;
//static counter for frame to switch LOD on
@@ -138,185 +81,6 @@ void sg_assert(BOOL expr)
#endif
}
-S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
-{
- return AABBSphereIntersectR2(min, max, origin, rad*rad);
-}
-
-S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r)
-{
- F32 d = 0.f;
- F32 t;
-
- if ((min-origin).magVecSquared() < r &&
- (max-origin).magVecSquared() < r)
- {
- return 2;
- }
-
- for (U32 i = 0; i < 3; i++)
- {
- if (origin.mV[i] < min.mV[i])
- {
- t = min.mV[i] - origin.mV[i];
- d += t*t;
- }
- else if (origin.mV[i] > max.mV[i])
- {
- t = origin.mV[i] - max.mV[i];
- d += t*t;
- }
-
- if (d > r)
- {
- return 0;
- }
- }
-
- return 1;
-}
-
-
-S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad)
-{
- return AABBSphereIntersectR2(min, max, origin, rad*rad);
-}
-
-S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r)
-{
- F32 d = 0.f;
- F32 t;
-
- LLVector4a origina;
- origina.load3(origin.mV);
-
- LLVector4a v;
- v.setSub(min, origina);
-
- if (v.dot3(v) < r)
- {
- v.setSub(max, origina);
- if (v.dot3(v) < r)
- {
- return 2;
- }
- }
-
-
- for (U32 i = 0; i < 3; i++)
- {
- if (origin.mV[i] < min[i])
- {
- t = min[i] - origin.mV[i];
- d += t*t;
- }
- else if (origin.mV[i] > max[i])
- {
- t = origin.mV[i] - max[i];
- d += t*t;
- }
-
- if (d > r)
- {
- return 0;
- }
- }
-
- return 1;
-}
-
-
-typedef enum
-{
- b000 = 0x00,
- b001 = 0x01,
- b010 = 0x02,
- b011 = 0x03,
- b100 = 0x04,
- b101 = 0x05,
- b110 = 0x06,
- b111 = 0x07,
-} eLoveTheBits;
-
-//contact Runitai Linden for a copy of the SL object used to write this table
-//basically, you give the table a bitmask of the look-at vector to a node and it
-//gives you a triangle fan index array
-static U16 sOcclusionIndices[] =
-{
- //000
- b111, b110, b010, b011, b001, b101, b100, b110,
- //001
- b011, b010, b000, b001, b101, b111, b110, b010,
- //010
- b101, b100, b110, b111, b011, b001, b000, b100,
- //011
- b001, b000, b100, b101, b111, b011, b010, b000,
- //100
- b110, b000, b010, b011, b111, b101, b100, b000,
- //101
- b010, b100, b000, b001, b011, b111, b110, b100,
- //110
- b100, b010, b110, b111, b101, b001, b000, b010,
- //111
- b000, b110, b100, b101, b001, b011, b010, b110,
-};
-
-U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
-{
- LLVector4a origin;
- origin.load3(camera->getOrigin().mV);
-
- S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
-
- return cypher*8;
-}
-
-U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
-{
- LLVector4a origin;
- origin.load3(camera->getOrigin().mV);
-
- S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
-
- return (U8*) (sOcclusionIndices+cypher*8);
-}
-
-//create a vertex buffer for efficiently rendering cubes
-LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
-{
- LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
-
- ret->allocateBuffer(8, 64, true);
-
- LLStrider<LLVector3> pos;
- LLStrider<U16> idx;
-
- ret->getVertexStrider(pos);
- ret->getIndexStrider(idx);
-
- pos[0] = LLVector3(-1,-1,-1);
- pos[1] = LLVector3(-1,-1, 1);
- pos[2] = LLVector3(-1, 1,-1);
- pos[3] = LLVector3(-1, 1, 1);
- pos[4] = LLVector3( 1,-1,-1);
- pos[5] = LLVector3( 1,-1, 1);
- pos[6] = LLVector3( 1, 1,-1);
- pos[7] = LLVector3( 1, 1, 1);
-
- for (U32 i = 0; i < 64; i++)
- {
- idx[i] = sOcclusionIndices[i];
- }
-
- ret->flush();
-
- return ret;
-}
-
-static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
-
-BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group);
-
//returns:
// 0 if sphere and AABB are not intersecting
// 1 if they are
@@ -358,24 +122,13 @@ LLSpatialGroup::~LLSpatialGroup()
gPipeline.checkReferences(this);
}
- if (isState(DEAD))
+ if (hasState(DEAD))
{
sZombieGroups--;
}
sNodeCount--;
- if (gGLManager.mHasOcclusionQuery)
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
- {
- if (mOcclusionQuery[i])
- {
- sQueryPool.release(mOcclusionQuery[i]);
- }
- }
- }
-
clearDrawMap();
clearAtlasList() ;
}
@@ -509,22 +262,13 @@ void LLSpatialGroup::clearDrawMap()
BOOL LLSpatialGroup::isHUDGroup()
{
- return mSpatialPartition && mSpatialPartition->isHUDPartition() ;
+ return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
}
BOOL LLSpatialGroup::isRecentlyVisible() const
{
- return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ;
-}
-
-BOOL LLSpatialGroup::isVisible() const
-{
- return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE;
-}
-
-void LLSpatialGroup::setVisible()
-{
- mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame();
+ const S32 MIN_VIS_FRAME_RANGE = 2;
+ return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ;
}
void LLSpatialGroup::validate()
@@ -548,7 +292,7 @@ void LLSpatialGroup::validate()
sg_assert(drawable->getSpatialGroup() == this);
if (drawable->getSpatialBridge())
{
- sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge());
+ sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge());
}
/*if (drawable->isSpatialBridge())
@@ -588,14 +332,6 @@ void LLSpatialGroup::validate()
#endif
}
-void LLSpatialGroup::checkStates()
-{
-#if LL_OCTREE_PARANOIA_CHECK
- //LLOctreeStateCheck checker;
- //checker.traverse(mOctreeNode);
-#endif
-}
-
void LLSpatialGroup::validateDrawMap()
{
#if LL_OCTREE_PARANOIA_CHECK
@@ -619,7 +355,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
OctreeNode* parent = mOctreeNode->getOctParent();
if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&
- (mOctreeNode->contains(drawablep) ||
+ (mOctreeNode->contains(drawablep->getEntry()) ||
(drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&
parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{
@@ -633,15 +369,14 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
}
-BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree)
+BOOL LLSpatialGroup::addObject(LLDrawable *drawablep)
{
- if (!from_octree)
+ if(!drawablep)
{
- mOctreeNode->insert(drawablep);
+ return FALSE;
}
- else
{
- drawablep->setSpatialGroup(this);
+ drawablep->setGroup(this);
setState(OBJECT_DIRTY | GEOM_DIRTY);
setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
gPipeline.markRebuild(this, TRUE);
@@ -662,9 +397,9 @@ void LLSpatialGroup::rebuildGeom()
{
if (!isDead())
{
- mSpatialPartition->rebuildGeom(this);
+ getSpatialPartition()->rebuildGeom(this);
- if (isState(LLSpatialGroup::MESH_DIRTY))
+ if (hasState(LLSpatialGroup::MESH_DIRTY))
{
gPipeline.markMeshDirty(this);
}
@@ -675,7 +410,7 @@ void LLSpatialGroup::rebuildMesh()
{
if (!isDead())
{
- mSpatialPartition->rebuildMesh(this);
+ getSpatialPartition()->rebuildMesh(this);
}
}
@@ -686,7 +421,7 @@ static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
- if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
return;
}
@@ -751,137 +486,26 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)
}
-BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut)
-{
- const OctreeNode* node = mOctreeNode;
-
- if (node->isEmpty())
- { //don't do anything if there are no objects
- if (empty && mOctreeNode->getParent())
- { //only root is allowed to be empty
- OCT_ERRS << "Empty leaf found in octree." << llendl;
- }
- return FALSE;
- }
-
- LLVector4a& newMin = mObjectExtents[0];
- LLVector4a& newMax = mObjectExtents[1];
-
- if (isState(OBJECT_DIRTY))
- { //calculate new bounding box
- clearState(OBJECT_DIRTY);
-
- //initialize bounding box to first element
- OctreeNode::const_element_iter i = node->getDataBegin();
- LLDrawable* drawablep = *i;
- const LLVector4a* minMax = drawablep->getSpatialExtents();
-
- newMin = minMax[0];
- newMax = minMax[1];
-
- for (++i; i != node->getDataEnd(); ++i)
- {
- drawablep = *i;
- minMax = drawablep->getSpatialExtents();
-
- update_min_max(newMin, newMax, minMax[0]);
- update_min_max(newMin, newMax, minMax[1]);
-
- //bin up the object
- /*for (U32 i = 0; i < 3; i++)
- {
- if (minMax[0].mV[i] < newMin.mV[i])
- {
- newMin.mV[i] = minMax[0].mV[i];
- }
- if (minMax[1].mV[i] > newMax.mV[i])
- {
- newMax.mV[i] = minMax[1].mV[i];
- }
- }*/
- }
-
- mObjectBounds[0].setAdd(newMin, newMax);
- mObjectBounds[0].mul(0.5f);
- mObjectBounds[1].setSub(newMax, newMin);
- mObjectBounds[1].mul(0.5f);
- }
-
- if (empty)
- {
- minOut = newMin;
- maxOut = newMax;
- }
- else
- {
- minOut.setMin(minOut, newMin);
- maxOut.setMax(maxOut, newMax);
- }
-
- return TRUE;
-}
-
-void LLSpatialGroup::unbound()
-{
- if (isState(DIRTY))
- {
- return;
- }
-
- setState(DIRTY);
-
- //all the parent nodes need to rebound this child
- if (mOctreeNode)
- {
- OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent();
- while (parent != NULL)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) parent->getListener(0);
- if (group->isState(DIRTY))
- {
- return;
- }
-
- group->setState(DIRTY);
- parent = (OctreeNode*) parent->getParent();
- }
- }
-}
-
LLSpatialGroup* LLSpatialGroup::getParent()
{
- if (isDead())
- {
- return NULL;
+ return (LLSpatialGroup*)LLviewerOctreeGroup::getParent();
}
- if(!mOctreeNode)
+BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
{
- return NULL;
- }
- OctreeNode* parent = mOctreeNode->getOctParent();
-
- if (parent)
+ if(!drawablep)
{
- return (LLSpatialGroup*) parent->getListener(0);
+ return FALSE;
}
- return NULL;
-}
-
-BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
-{
unbound();
if (mOctreeNode && !from_octree)
{
- if (!mOctreeNode->remove(drawablep))
- {
- OCT_ERRS << "Could not remove drawable from spatial group" << llendl;
- }
+ drawablep->setGroup(NULL);
}
else
{
- drawablep->setSpatialGroup(NULL);
+ drawablep->setGroup(NULL);
setState(GEOM_DIRTY);
gPipeline.markRebuild(this, TRUE);
@@ -918,22 +542,22 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
mObjectExtents[0].add(offset);
mObjectExtents[1].add(offset);
- if (!mSpatialPartition->mRenderByGroup &&
- mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE &&
- mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
- mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
+ if (!getSpatialPartition()->mRenderByGroup &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
+ getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
{
setState(GEOM_DIRTY);
gPipeline.markRebuild(this, TRUE);
}
}
-class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler
+class LLSpatialSetState : public OctreeTraveler
{
public:
U32 mState;
LLSpatialSetState(U32 state) : mState(state) { }
- virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }
+ virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }
};
class LLSpatialSetStateDiff : public LLSpatialSetState
@@ -941,24 +565,17 @@ class LLSpatialSetStateDiff : public LLSpatialSetState
public:
LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { }
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
+ virtual void traverse(const OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
- if (!group->isState(mState))
+ if (!group->hasState(mState))
{
- LLSpatialGroup::OctreeTraveler::traverse(n);
+ OctreeTraveler::traverse(n);
}
}
};
-void LLSpatialGroup::setState(U32 state)
-{
- mState |= state;
-
- llassert(state <= LLSpatialGroup::STATE_MASK);
-}
-
void LLSpatialGroup::setState(U32 state, S32 mode)
{
llassert(state <= LLSpatialGroup::STATE_MASK);
@@ -982,12 +599,12 @@ void LLSpatialGroup::setState(U32 state, S32 mode)
}
}
-class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler
+class LLSpatialClearState : public OctreeTraveler
{
public:
U32 mState;
LLSpatialClearState(U32 state) : mState(state) { }
- virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); }
+ virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); }
};
class LLSpatialClearStateDiff : public LLSpatialClearState
@@ -995,24 +612,17 @@ class LLSpatialClearStateDiff : public LLSpatialClearState
public:
LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { }
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
+ virtual void traverse(const OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
- if (group->isState(mState))
+ if (group->hasState(mState))
{
- LLSpatialGroup::OctreeTraveler::traverse(n);
+ OctreeTraveler::traverse(n);
}
}
};
-void LLSpatialGroup::clearState(U32 state)
-{
- llassert(state <= LLSpatialGroup::STATE_MASK);
-
- mState &= ~state;
-}
-
void LLSpatialGroup::clearState(U32 state, S32 mode)
{
llassert(state <= LLSpatialGroup::STATE_MASK);
@@ -1036,144 +646,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)
}
}
-BOOL LLSpatialGroup::isState(U32 state) const
-{
- llassert(state <= LLSpatialGroup::STATE_MASK);
-
- return mState & state ? TRUE : FALSE;
-}
-
-//=====================================
-// Occlusion State Set/Clear
-//=====================================
-class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler
-{
-public:
- U32 mState;
- LLSpatialSetOcclusionState(U32 state) : mState(state) { }
- virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); }
-};
-
-class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState
-{
-public:
- LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { }
-
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (!group->isOcclusionState(mState))
- {
- LLSpatialGroup::OctreeTraveler::traverse(n);
- }
- }
-};
-
-
-void LLSpatialGroup::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])
- {
- sQueryPool.release(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
- }
- }
- }
- else
- {
- mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
- if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
- }
-}
-
-class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler
-{
-public:
- U32 mState;
-
- LLSpatialClearOcclusionState(U32 state) : mState(state) { }
- virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); }
-};
-
-class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState
-{
-public:
- LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { }
-
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (group->isOcclusionState(mState))
- {
- LLSpatialGroup::OctreeTraveler::traverse(n);
- }
- }
-};
-
-void LLSpatialGroup::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
- {
- mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
- }
-}
//======================================
// Octree Listener Implementation
//======================================
-LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
+LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part),
mObjectBoxSize(1.f),
- mState(0),
mGeometryBytes(0),
mSurfaceArea(0.f),
mBuilt(0.f),
- mOctreeNode(node),
- mSpatialPartition(part),
mVertexBuffer(NULL),
mBufferUsage(part->mBufferUsage),
mDistance(0.f),
@@ -1191,32 +672,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mViewAngle.splat(0.f);
mLastUpdateViewAngle.splat(-1.f);
- mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
- mObjectExtents[0] = mObjectExtents[1] = mViewAngle;
sg_assert(mOctreeNode->getListenerCount() == 0);
- mOctreeNode->addListener(this);
setState(SG_INITIAL_STATE_MASK);
gPipeline.markRebuild(this, TRUE);
- mBounds[0] = node->getCenter();
- mBounds[1] = node->getSize();
-
- part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod;
- mLODHash = part->mLODSeed;
-
- OctreeNode* oct_parent = node->getOctParent();
-
- LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL;
-
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mOcclusionQuery[i] = 0;
- mOcclusionIssued[i] = 0;
- mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
- mVisible[i] = 0;
- }
-
mRadius = 1;
mPixelArea = 1024.f;
}
@@ -1235,17 +695,17 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
}
#if !LL_RELEASE_FOR_DOWNLOAD
- if (isState(LLSpatialGroup::OBJECT_DIRTY))
+ if (hasState(LLSpatialGroup::OBJECT_DIRTY))
{
llerrs << "Spatial group dirty on distance update." << llendl;
}
#endif
if (!isEmpty())
{
- mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
+ mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
(F32) mOctreeNode->getSize().getLength3().getF32();
- mDistance = mSpatialPartition->calcDistance(this, camera);
- mPixelArea = mSpatialPartition->calcPixelArea(this, camera);
+ mDistance = getSpatialPartition()->calcDistance(this, camera);
+ mPixelArea = getSpatialPartition()->calcPixelArea(this, camera);
}
}
@@ -1266,9 +726,9 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
dist = eye.getLength3().getF32();
eye.normalize3fast();
- if (!group->isState(LLSpatialGroup::ALPHA_DIRTY))
+ if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY))
{
- if (!group->mSpatialPartition->isBridge())
+ if (!group->getSpatialPartition()->isBridge())
{
LLVector4a view_angle = eye;
@@ -1336,23 +796,18 @@ F32 LLSpatialGroup::getUpdateUrgency() const
}
}
-BOOL LLSpatialGroup::needsUpdate()
-{
- return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE;
-}
-
BOOL LLSpatialGroup::changeLOD()
{
- if (isState(ALPHA_DIRTY | OBJECT_DIRTY))
+ if (hasState(ALPHA_DIRTY | OBJECT_DIRTY))
{ ///a rebuild is going to happen, update distance and LoD
return TRUE;
}
- if (mSpatialPartition->mSlopRatio > 0.f)
+ if (getSpatialPartition()->mSlopRatio > 0.f)
{
F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius));
- if (fabsf(ratio) >= mSpatialPartition->mSlopRatio)
+ if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio)
{
return TRUE;
}
@@ -1371,34 +826,50 @@ BOOL LLSpatialGroup::changeLOD()
return FALSE;
}
-void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep)
+void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- addObject(drawablep, FALSE, TRUE);
+ addObject((LLDrawable*)entry->getDrawable());
unbound();
setState(OBJECT_DIRTY);
}
-void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable)
+void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)
{
- removeObject(drawable, TRUE);
- setState(OBJECT_DIRTY);
+ removeObject((LLDrawable*)entry->getDrawable(), TRUE);
+ LLviewerOctreeGroup::handleRemoval(node, entry);
}
void LLSpatialGroup::handleDestruction(const TreeNode* node)
{
+ if(isDead())
+ {
+ return;
+ }
setState(DEAD);
- for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
+ for (element_iter i = getDataBegin(); getElementCount() > 0 && i != getDataEnd();)
{
- LLDrawable* drawable = *i;
- if (drawable->getSpatialGroup() == this)
+ LLViewerOctreeEntry* entry = *i;
+
+ if (entry->getGroup() == this)
+ {
+ if(entry->hasDrawable())
+ {
+ ((LLDrawable*)entry->getDrawable())->setGroup(NULL);
+ }
+ else
+ {
+ llerrs << "No Drawable found in the entry." << llendl;
+ }
+ }
+ else
{
- drawable->setSpatialGroup(NULL);
+ ++i;
}
}
//clean up avatar attachment stats
- LLSpatialBridge* bridge = mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = getSpatialPartition()->asBridge();
if (bridge)
{
if (bridge->mAvatar.notNull())
@@ -1415,21 +886,11 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
mOctreeNode = NULL;
}
-void LLSpatialGroup::handleStateChange(const TreeNode* node)
-{
- //drop bounding box upon state change
- if (mOctreeNode != node)
- {
- mOctreeNode = (OctreeNode*) node;
- }
- unbound();
-}
-
void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
if (child->getListenerCount() == 0)
{
- new LLSpatialGroup(child, mSpatialPartition);
+ new LLSpatialGroup(child, getSpatialPartition());
}
else
{
@@ -1441,11 +902,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
assert_states_valid(this);
}
-void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child)
-{
- unbound();
-}
-
void LLSpatialGroup::destroyGL(bool keep_occlusion)
{
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
@@ -1463,20 +919,17 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)
if (!keep_occlusion)
{
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- if (mOcclusionQuery[i])
- {
- sQueryPool.release(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
- }
+ releaseOcclusionQueryObjectNames();
}
for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* facep = drawable->getFace(j);
@@ -1488,318 +941,27 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)
}
}
-BOOL LLSpatialGroup::rebound()
-{
- if (!isState(DIRTY))
- { //return TRUE if we're not empty
- return TRUE;
- }
-
- if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
- group->rebound();
-
- //copy single child's bounding box
- mBounds[0] = group->mBounds[0];
- mBounds[1] = group->mBounds[1];
- mExtents[0] = group->mExtents[0];
- mExtents[1] = group->mExtents[1];
-
- group->setState(SKIP_FRUSTUM_CHECK);
- }
- else if (mOctreeNode->isLeaf())
- { //copy object bounding box if this is a leaf
- boundObjects(TRUE, mExtents[0], mExtents[1]);
- mBounds[0] = mObjectBounds[0];
- mBounds[1] = mObjectBounds[1];
- }
- else
- {
- LLVector4a& newMin = mExtents[0];
- LLVector4a& newMax = mExtents[1];
- LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
- group->clearState(SKIP_FRUSTUM_CHECK);
- group->rebound();
- //initialize to first child
- newMin = group->mExtents[0];
- newMax = group->mExtents[1];
-
- //first, rebound children
- for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
- {
- group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
- group->clearState(SKIP_FRUSTUM_CHECK);
- group->rebound();
- const LLVector4a& max = group->mExtents[1];
- const LLVector4a& min = group->mExtents[0];
-
- newMax.setMax(newMax, max);
- newMin.setMin(newMin, min);
- }
-
- boundObjects(FALSE, newMin, newMax);
-
- mBounds[0].setAdd(newMin, newMax);
- mBounds[0].mul(0.5f);
- mBounds[1].setSub(newMax, newMin);
- mBounds[1].mul(0.5f);
- }
-
- clearState(DIRTY);
-
- return TRUE;
-}
-
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");
-
-void LLSpatialGroup::checkOcclusion()
-{
- if (LLPipeline::sUseOcclusion > 1)
- {
- LLFastTimer t(FTM_OCCLUSION_READBACK);
- LLSpatialGroup* parent = getParent();
- if (parent && parent->isOcclusionState(LLSpatialGroup::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");
-
- if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
- { //query was issued last frame, wait until it's available
- S32 max_loop = 1024;
- LLFastTimer t(FTM_OCCLUSION_WAIT);
- while (!available && max_loop-- > 0)
- {
- F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
- //do some usefu work while we wait
- LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
-
- 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 LL_TRACK_PENDING_OCCLUSION_QUERIES
- sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
-#endif
- }
- else if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
- { //delete the query to avoid holding onto hundreds of pending queries
- sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
-
- if (isOcclusionState(DISCARD_QUERY))
- {
- res = 2;
- }
-
- if (res > 0)
- {
- assert_states_valid(this);
- clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- else
- {
- assert_states_valid(this);
-
- setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
-
- assert_states_valid(this);
- }
-
- clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
- }
- }
- else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED))
- { //check occlusion has been issued for occluded node that has not had a query issued
- assert_states_valid(this);
- clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- }
-}
-
-static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
-static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw");
-
-
-
-void LLSpatialGroup::doOcclusion(LLCamera* camera)
-{
- if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
- {
- // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
- if (earlyFail(camera, this))
- {
- LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL);
- setOcclusionState(LLSpatialGroup::DISCARD_QUERY);
- assert_states_valid(this);
- clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- else
- {
- if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
- {
- { //no query pending, or previous query to be discarded
- LLFastTimer t(FTM_RENDER_OCCLUSION);
-
- if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- LLFastTimer t(FTM_OCCLUSION_ALLOCATE);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
- }
-
- // Depth clamp all water to avoid it being culled as a result of being
- // 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);
-
- LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
-
-#if !LL_DARWIN
- U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
-#else
- U32 mode = GL_SAMPLES_PASSED_ARB;
-#endif
-
-#if LL_TRACK_PENDING_OCCLUSION_QUERIES
- sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
-#endif
-
- {
- LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
-
- //store which frame this query was issued on
- mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
-
- {
- LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY);
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- }
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- llassert(shader);
-
- shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr());
- shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,
- mBounds[1][1]+SG_OCCLUSION_FUDGE,
- mBounds[1][2]+SG_OCCLUSION_FUDGE);
-
- if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
- {
- LLFastTimer t(FTM_OCCLUSION_DRAW_WATER);
-
- LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
- if (camera->getOrigin().isExactlyZero())
- { //origin is invalid, draw entire box
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
- }
- else
- {
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
- }
- }
- else
- {
- LLFastTimer t(FTM_OCCLUSION_DRAW);
- if (camera->getOrigin().isExactlyZero())
- { //origin is invalid, draw entire box
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
- }
- else
- {
- gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
- }
- }
-
-
- {
- LLFastTimer t(FTM_OCCLUSION_END_QUERY);
- glEndQueryARB(mode);
- }
- }
- }
-
- {
- LLFastTimer t(FTM_SET_OCCLUSION_STATE);
- setOcclusionState(LLSpatialGroup::QUERY_PENDING);
- clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
- }
- }
- }
- }
-}
-
//==============================================
-LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage)
+LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp)
: mRenderByGroup(render_by_group), mBridge(NULL)
{
- mOcclusionEnabled = TRUE;
- mDrawableType = 0;
+ mRegionp = regionp;
mPartitionType = LLViewerRegion::PARTITION_NONE;
- mLODSeed = 0;
- mLODPeriod = 1;
mVertexDataMask = data_mask;
mBufferUsage = buffer_usage;
mDepthMask = FALSE;
mSlopRatio = 0.25f;
mInfiniteFarClip = FALSE;
- LLVector4a center, size;
- center.splat(0.f);
- size.splat(1.f);
-
- mOctree = new LLSpatialGroup::OctreeRoot(center,size,
- NULL);
new LLSpatialGroup(mOctree, this);
}
LLSpatialPartition::~LLSpatialPartition()
{
- delete mOctree;
- mOctree = NULL;
}
-
LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
{
drawablep->updateSpatialExtents();
@@ -1807,11 +969,15 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
//keep drawable from being garbage collected
LLPointer<LLDrawable> ptr = drawablep;
+ if(!drawablep->getGroup())
+ {
assert_octree_valid(mOctree);
- mOctree->insert(drawablep);
+ mOctree->insert(drawablep->getEntry());
assert_octree_valid(mOctree);
+ }
LLSpatialGroup* group = drawablep->getSpatialGroup();
+ llassert(group != NULL);
if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
{
@@ -1829,11 +995,9 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
}
else
{
- drawablep->setSpatialGroup(NULL);
+ drawablep->setGroup(NULL);
}
- drawablep->setSpatialGroup(NULL);
-
assert_octree_valid(mOctree);
return TRUE;
@@ -1851,11 +1015,11 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
BOOL was_visible = curp ? curp->isVisible() : FALSE;
- if (curp && curp->mSpatialPartition != this)
+ if (curp && curp->getSpatialPartition() != this)
{
//keep drawable from being garbage collected
LLPointer<LLDrawable> ptr = drawablep;
- if (curp->mSpatialPartition->remove(drawablep, curp))
+ if (curp->getSpatialPartition()->remove(drawablep, curp))
{
put(drawablep, was_visible);
return;
@@ -1883,13 +1047,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL
put(drawablep, was_visible);
}
-class LLSpatialShift : public LLSpatialGroup::OctreeTraveler
+class LLSpatialShift : public OctreeTraveler
{
public:
const LLVector4a& mOffset;
LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { }
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
+ virtual void visit(const OctreeNode* branch)
{
((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);
}
@@ -1901,17 +1065,17 @@ void LLSpatialPartition::shift(const LLVector4a &offset)
shifter.traverse(mOctree);
}
-class LLOctreeCull : public LLSpatialGroup::OctreeTraveler
+class LLOctreeCull : public LLViewerOctreeCull
{
public:
- LLOctreeCull(LLCamera* camera)
- : mCamera(camera), mRes(0) { }
+ LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {}
- virtual bool earlyFail(LLSpatialGroup* group)
+ virtual bool earlyFail(LLviewerOctreeGroup* base_group)
{
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
group->checkOcclusion();
- if (group->mOctreeNode->getParent() && //never occlusion cull the root node
+ if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
LLPipeline::sUseOcclusion && //ignore occlusion if disabled
group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
@@ -1922,78 +1086,29 @@ public:
return false;
}
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
{
- LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
-
- if (earlyFail(group))
- {
- return;
- }
-
- if (mRes == 2 ||
- (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)))
- { //fully in, just add everything
- LLSpatialGroup::OctreeTraveler::traverse(n);
- }
- else
- {
- mRes = frustumCheck(group);
-
- if (mRes)
- { //at least partially in, run on down
- LLSpatialGroup::OctreeTraveler::traverse(n);
- }
-
- mRes = 0;
- }
- }
-
- virtual S32 frustumCheck(const LLSpatialGroup* group)
- {
- S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
+ S32 res = AABBInFrustumNoFarClipGroupBounds(group);
if (res != 0)
{
- res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist));
+ res = llmin(res, AABBSphereIntersectGroupExtents(group));
}
return res;
}
- virtual S32 frustumCheckObjects(const LLSpatialGroup* group)
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
{
- S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
+ S32 res = AABBInFrustumNoFarClipObjectBounds(group);
if (res != 0)
{
- res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist));
+ res = llmin(res, AABBSphereIntersectObjectExtents(group));
}
return res;
}
- virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group)
- {
- if (branch->getElementCount() == 0) //no elements
- {
- return false;
- }
- else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box
- {
- return true;
- }
- else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum
- {
- return false;
- }
-
- return true;
- }
-
- virtual void preprocess(LLSpatialGroup* group)
- {
-
- }
-
- virtual void processGroup(LLSpatialGroup* group)
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
{
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
if (group->needsUpdate() ||
group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1)
{
@@ -2001,21 +1116,6 @@ public:
}
gPipeline.markNotCulled(group, *mCamera);
}
-
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
-
- preprocess(group);
-
- if (checkObjects(branch, group))
- {
- processGroup(group);
- }
- }
-
- LLCamera *mCamera;
- S32 mRes;
};
class LLOctreeCullNoFarClip : public LLOctreeCull
@@ -2024,14 +1124,14 @@ public:
LLOctreeCullNoFarClip(LLCamera* camera)
: LLOctreeCull(camera) { }
- virtual S32 frustumCheck(const LLSpatialGroup* group)
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
{
- return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
+ return AABBInFrustumNoFarClipGroupBounds(group);
}
- virtual S32 frustumCheckObjects(const LLSpatialGroup* group)
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
{
- S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
+ S32 res = AABBInFrustumNoFarClipObjectBounds(group);
return res;
}
};
@@ -2042,14 +1142,14 @@ public:
LLOctreeCullShadow(LLCamera* camera)
: LLOctreeCull(camera) { }
- virtual S32 frustumCheck(const LLSpatialGroup* group)
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
{
- return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]);
+ return AABBInFrustumGroupBounds(group);
}
- virtual S32 frustumCheckObjects(const LLSpatialGroup* group)
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
{
- return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]);
+ return AABBInFrustumObjectBounds(group);
}
};
@@ -2059,9 +1159,11 @@ public:
LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)
: LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { }
- virtual bool earlyFail(LLSpatialGroup* group)
+ virtual bool earlyFail(LLviewerOctreeGroup* base_group)
{
- if (group->mOctreeNode->getParent() && //never occlusion cull the root node
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
+ if (group->getOctreeNode()->getParent() && //never occlusion cull the root node
LLPipeline::sUseOcclusion && //ignore occlusion if disabled
group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
@@ -2071,7 +1173,7 @@ public:
return false;
}
- virtual void traverse(const LLSpatialGroup::OctreeNode* n)
+ virtual void traverse(const OctreeNode* n)
{
LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0);
@@ -2080,10 +1182,10 @@ public:
return;
}
- if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||
+ if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||
mRes == 2)
{ //don't need to do frustum check
- LLSpatialGroup::OctreeTraveler::traverse(n);
+ OctreeTraveler::traverse(n);
}
else
{
@@ -2091,31 +1193,35 @@ public:
if (mRes)
{ //at least partially in, run on down
- LLSpatialGroup::OctreeTraveler::traverse(n);
+ OctreeTraveler::traverse(n);
}
mRes = 0;
}
}
- virtual void processGroup(LLSpatialGroup* group)
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
{
- llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty())
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
+ llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty())
if (mRes < 2)
{
- if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0)
+ if (AABBInFrustumObjectBounds(group) > 0)
{
mEmpty = FALSE;
- update_min_max(mMin, mMax, group->mObjectExtents[0]);
- update_min_max(mMin, mMax, group->mObjectExtents[1]);
+ const LLVector4a* exts = group->getObjectExtents();
+ update_min_max(mMin, mMax, exts[0]);
+ update_min_max(mMin, mMax, exts[1]);
}
}
else
{
mEmpty = FALSE;
- update_min_max(mMin, mMax, group->mExtents[0]);
- update_min_max(mMin, mMax, group->mExtents[1]);
+ const LLVector4a* exts = group->getExtents();
+ update_min_max(mMin, mMax, exts[0]);
+ update_min_max(mMin, mMax, exts[1]);
}
}
@@ -2130,10 +1236,12 @@ public:
LLOctreeCullDetectVisible(LLCamera* camera)
: LLOctreeCullShadow(camera), mResult(FALSE) { }
- virtual bool earlyFail(LLSpatialGroup* group)
+ virtual bool earlyFail(LLviewerOctreeGroup* base_group)
{
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+
if (mResult || //already found a node, don't check any more
- (group->mOctreeNode->getParent() && //never occlusion cull the root node
+ (group->getOctreeNode()->getParent() && //never occlusion cull the root node
LLPipeline::sUseOcclusion && //ignore occlusion if disabled
group->isOcclusionState(LLSpatialGroup::OCCLUDED)))
{
@@ -2143,9 +1251,9 @@ public:
return false;
}
- virtual void processGroup(LLSpatialGroup* group)
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
{
- if (group->isVisible())
+ if (base_group->isVisible())
{
mResult = TRUE;
}
@@ -2160,17 +1268,21 @@ public:
LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results)
: LLOctreeCull(camera), mResults(results) { }
- virtual bool earlyFail(LLSpatialGroup* group) { return false; }
- virtual void preprocess(LLSpatialGroup* group) { }
+ virtual bool earlyFail(LLviewerOctreeGroup* group) { return false; }
+ virtual void preprocess(LLviewerOctreeGroup* group) { }
- virtual void processGroup(LLSpatialGroup* group)
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
{
- LLSpatialGroup::OctreeNode* branch = group->mOctreeNode;
+ LLSpatialGroup* group = (LLSpatialGroup*)base_group;
+ OctreeNode* branch = group->getOctreeNode();
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
-
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
if (!drawable->isDead())
{
if (drawable->isSpatialBridge())
@@ -2283,18 +1395,22 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
}
-class LLOctreeDirty : public LLOctreeTraveler<LLDrawable>
+class LLOctreeDirty : public OctreeTraveler
{
public:
- virtual void visit(const LLOctreeNode<LLDrawable>* state)
+ virtual void visit(const OctreeNode* state)
{
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
group->destroyGL();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
- if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup)
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+ if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)
{
gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);
}
@@ -2318,11 +1434,6 @@ void LLSpatialPartition::resetVertexBuffers()
dirty.traverse(mOctree);
}
-BOOL LLSpatialPartition::isOcclusionEnabled()
-{
- return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2;
-}
-
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
LLVector4a visMina, visMaxa;
@@ -2365,13 +1476,28 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
((LLSpatialGroup*)mOctree->getListener(0))->validate();
#endif
-
- if (for_select)
- {
LLOctreeSelect selecter(&camera, results);
selecter.traverse(mOctree);
+
+ return 0;
+ }
+
+S32 LLSpatialPartition::cull(LLCamera &camera)
+{
+#if LL_OCTREE_PARANOIA_CHECK
+ ((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
+#endif
+ {
+ LLFastTimer ftm(FTM_CULL_REBOUND);
+ LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
+ group->rebound();
}
- else if (LLPipeline::sShadowRender)
+
+#if LL_OCTREE_PARANOIA_CHECK
+ ((LLSpatialGroup*)mOctree->getListener(0))->validate();
+#endif
+
+ if (LLPipeline::sShadowRender)
{
LLFastTimer ftm(FTM_FRUSTUM_CULL);
LLOctreeCullShadow culler(&camera);
@@ -2393,50 +1519,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
return 0;
}
-BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group)
-{
- if (camera->getOrigin().isExactlyZero())
- {
- return FALSE;
- }
-
- const F32 vel = SG_OCCLUSION_FUDGE*2.f;
- LLVector4a fudge;
- fudge.splat(vel);
-
- const LLVector4a& c = group->mBounds[0];
- LLVector4a r;
- r.setAdd(group->mBounds[1], fudge);
-
- /*if (r.magVecSquared() > 1024.0*1024.0)
- {
- return TRUE;
- }*/
-
- LLVector4a e;
- e.load3(camera->getOrigin().mV);
-
- LLVector4a min;
- min.setSub(c,r);
- LLVector4a max;
- max.setAdd(c,r);
-
- S32 lt = e.lessThan(min).getGatheredBits() & 0x7;
- if (lt)
- {
- return FALSE;
- }
-
- S32 gt = e.greaterThan(max).getGatheredBits() & 0x7;
- if (gt)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
void pushVerts(LLDrawInfo* params, U32 mask)
{
LLRenderPass::applyModelMatrix(*params);
@@ -2508,7 +1590,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
void pushBufferVerts(LLSpatialGroup* group, U32 mask)
{
- if (group->mSpatialPartition->mRenderByGroup)
+ if (group->getSpatialPartition()->mRenderByGroup)
{
if (!group->mDrawMap.empty())
{
@@ -2531,7 +1613,8 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
}
else
{
- drawBox(group->mBounds[0], group->mBounds[1]);
+ const LLVector4a* bounds = group->getBounds();
+ drawBox(bounds[0], bounds[1]);
}
}
@@ -2576,7 +1659,7 @@ void renderOctree(LLSpatialGroup* group)
LLVector4 col;
if (group->mBuilt > 0.f)
{
- group->mBuilt -= 2.f * gFrameIntervalSeconds;
+ group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
{
col.setVec(1.0f, 0, 0, group->mBuilt*0.5f);
@@ -2595,14 +1678,20 @@ void renderOctree(LLSpatialGroup* group)
gGL.diffuseColor4f(1,0,0,group->mBuilt);
gGL.flush();
glLineWidth(5.f);
- drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
+
+ const LLVector4a* bounds = group->getObjectBounds();
+ drawBoxOutline(bounds[0], bounds[1]);
gGL.flush();
glLineWidth(1.f);
gGL.flush();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
- if (!group->mSpatialPartition->isBridge())
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
+ if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
LLVector3 trans = drawable->getRegion()->getOriginAgent();
@@ -2634,7 +1723,7 @@ void renderOctree(LLSpatialGroup* group)
}
}
- if (!group->mSpatialPartition->isBridge())
+ if (!group->getSpatialPartition()->isBridge())
{
gGL.popMatrix();
}
@@ -2646,7 +1735,7 @@ void renderOctree(LLSpatialGroup* group)
else
{
if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
- && group->mSpatialPartition->mRenderByGroup)
+ && group->getSpatialPartition()->mRenderByGroup)
{
col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
}
@@ -2659,9 +1748,10 @@ void renderOctree(LLSpatialGroup* group)
gGL.diffuseColor4fv(col.mV);
LLVector4a fudge;
fudge.splat(0.001f);
- LLVector4a size = group->mObjectBounds[1];
- size.mul(1.01f);
- size.add(fudge);
+
+ //LLVector4a size = group->mObjectBounds[1];
+ //size.mul(1.01f);
+ //size.add(fudge);
//{
// LLGLDepthTest depth(GL_TRUE, GL_FALSE);
@@ -2677,10 +1767,12 @@ void renderOctree(LLSpatialGroup* group)
//drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
gGL.diffuseColor4f(0,1,1,1);
- drawBoxOutline(group->mBounds[0],group->mBounds[1]);
+
+ const LLVector4a* bounds = group->getBounds();
+ drawBoxOutline(bounds[0], bounds[1]);
//draw bounding box for draw info
- /*if (group->mSpatialPartition->mRenderByGroup)
+ /*if (group->getSpatialPartition()->mRenderByGroup)
{
gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f);
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
@@ -3444,13 +2536,17 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
void renderPhysicsShapes(LLSpatialGroup* group)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
LLVOVolume* volume = drawable->getVOVolume();
if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
{
- if (!group->mSpatialPartition->isBridge())
+ if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
LLVector3 trans = drawable->getRegion()->getOriginAgent();
@@ -4014,17 +3110,18 @@ void renderAgentTarget(LLVOAvatar* avatar)
}
}
-class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
+class LLOctreeRenderNonOccluded : public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {}
- virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
{
node->accept(this);
stop_glerror();
@@ -4064,11 +3161,11 @@ public:
}
}
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
+ virtual void visit(const OctreeNode* branch)
{
LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
-
- if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])))
+ const LLVector4a* bounds = group->getBounds();
+ if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
{
return;
}
@@ -4081,14 +3178,19 @@ public:
if (!group->isEmpty())
{
gGL.diffuseColor3f(0,0,1);
- drawBoxOutline(group->mObjectBounds[0],
- group->mObjectBounds[1]);
+
+ const LLVector4a* obj_bounds = group->getObjectBounds();
+ drawBoxOutline(obj_bounds[0], obj_bounds[1]);
}
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
{
@@ -4211,17 +3313,18 @@ public:
};
-class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable>
+class LLOctreeRenderPhysicsShapes : public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {}
- virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))
{
node->accept(this);
stop_glerror();
@@ -4239,23 +3342,24 @@ public:
}
}
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
+ virtual void visit(const OctreeNode* branch)
{
}
};
-class LLOctreePushBBoxVerts : public LLOctreeTraveler<LLDrawable>
+class LLOctreePushBBoxVerts : public OctreeTraveler
{
public:
LLCamera* mCamera;
LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {}
- virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
+ const LLVector4a* bounds = group->getBounds();
+ if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1]))
{
node->accept(this);
@@ -4266,19 +3370,23 @@ public:
}
}
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
+ virtual void visit(const OctreeNode* branch)
{
LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0);
- if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])))
+ const LLVector4a* bounds = group->getBounds();
+ if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))
{
return;
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
-
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(!drawable)
+ {
+ continue;
+ }
renderBoundingBox(drawable, FALSE);
}
}
@@ -4290,7 +3398,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera)
pusher.traverse(mOctree);
}
-class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable>
+class LLOctreeStateCheck : public OctreeTraveler
{
public:
U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS];
@@ -4303,7 +3411,7 @@ public:
}
}
- virtual void traverse(const LLSpatialGroup::OctreeNode* node)
+ virtual void traverse(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
@@ -4330,7 +3438,7 @@ public:
}
- virtual void visit(const LLOctreeNode<LLDrawable>* state)
+ virtual void visit(const OctreeNode* state)
{
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
@@ -4342,7 +3450,7 @@ public:
}
}
- if (group->isState(LLSpatialGroup::DIRTY))
+ if (group->hasState(LLSpatialGroup::DIRTY))
{
assert_parent_state(group, LLSpatialGroup::DIRTY);
}
@@ -4353,7 +3461,7 @@ public:
LLSpatialGroup* parent = group->getParent();
while (parent)
{
- if (!parent->isState(state))
+ if (!parent->hasState(state))
{
llerrs << "Spatial group failed parent state check." << llendl;
}
@@ -4469,7 +3577,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
}
LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
+class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>
{
public:
LL_ALIGN_16(LLVector4a mStart);
@@ -4497,21 +3605,21 @@ public:
{
}
- virtual void visit(const LLSpatialGroup::OctreeNode* branch)
+ virtual void visit(const OctreeNode* branch)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
+ for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
check(*i);
}
}
- virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node)
+ virtual LLDrawable* check(const OctreeNode* node)
{
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
{
- const LLSpatialGroup::OctreeNode* child = node->getChild(i);
+ const OctreeNode* child = node->getChild(i);
LLVector3 res;
LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0);
@@ -4519,17 +3627,18 @@ public:
LLVector4a size;
LLVector4a center;
- size = group->mBounds[1];
- center = group->mBounds[0];
+ const LLVector4a* bounds = group->getBounds();
+ size = bounds[1];
+ center = bounds[0];
LLVector4a local_start = mStart;
LLVector4a local_end = mEnd;
- if (group->mSpatialPartition->isBridge())
+ if (group->getSpatialPartition()->isBridge())
{
- LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix();
+ LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix();
local_matrix.invert();
-
+
LLMatrix4a local_matrix4a;
local_matrix4a.loadu(local_matrix);
@@ -4546,8 +3655,10 @@ public:
return mHit;
}
- virtual bool check(LLDrawable* drawable)
+ virtual bool check(LLViewerOctreeEntry* entry)
{
+ LLDrawable* drawable = (LLDrawable*)entry->getDrawable();
+
if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
{
return false;
@@ -4944,5 +4055,3 @@ void LLCullResult::assertDrawMapsEmpty()
}
}
-
-
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 9732be90af..05ed70ab59 100755
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -45,23 +45,16 @@
#define SG_STATE_INHERIT_MASK (OCCLUDED)
#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
+class LLViewerOctreePartition;
class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
class LLTextureAtlas;
class LLTextureAtlasSlot;
+class LLViewerRegion;
-S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad);
-S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared);
-
-S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
-S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
void pushVerts(LLFace* face, U32 mask);
-// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
-U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
-U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
-
class LLDrawInfo : public LLRefCount
{
protected:
@@ -182,7 +175,7 @@ public:
}
};
-
+
struct CompareBump
{
bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
@@ -205,13 +198,13 @@ public:
};
LL_ALIGN_PREFIX(64)
-class LLSpatialGroup : public LLOctreeListener<LLDrawable>
+class LLSpatialGroup : public LLOcclusionCullingGroup
{
friend class LLSpatialPartition;
friend class LLOctreeStateCheck;
public:
- LLSpatialGroup(const LLSpatialGroup& rhs)
+ LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)
{
*this = rhs;
}
@@ -232,7 +225,6 @@ public:
return *this;
}
- static std::set<GLuint> sPendingQueries; //pending occlusion queries
static U32 sNodeCount;
static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
@@ -244,15 +236,6 @@ public:
typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;
typedef std::map<U32, buffer_texture_map_t> buffer_map_t;
- typedef LLOctreeListener<LLDrawable> BaseType;
- typedef LLOctreeListener<LLDrawable> OctreeListener;
- typedef LLTreeNode<LLDrawable> TreeNode;
- typedef LLOctreeNode<LLDrawable> OctreeNode;
- typedef LLOctreeRoot<LLDrawable> OctreeRoot;
- typedef LLOctreeTraveler<LLDrawable> OctreeTraveler;
- typedef LLOctreeNode<LLDrawable>::element_iter element_iter;
- typedef LLOctreeNode<LLDrawable>::element_list element_list;
-
struct CompareDistanceGreater
{
bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
@@ -279,104 +262,57 @@ public:
typedef enum
{
- OCCLUDED = 0x00010000,
- QUERY_PENDING = 0x00020000,
- ACTIVE_OCCLUSION = 0x00040000,
- DISCARD_QUERY = 0x00080000,
- EARLY_FAIL = 0x00100000,
- } eOcclusionState;
-
- typedef enum
- {
- DEAD = 0x00000001,
- DIRTY = 0x00000002,
- OBJECT_DIRTY = 0x00000004,
- GEOM_DIRTY = 0x00000008,
- ALPHA_DIRTY = 0x00000010,
- SKIP_FRUSTUM_CHECK = 0x00000020,
- IN_IMAGE_QUEUE = 0x00000040,
- IMAGE_DIRTY = 0x00000080,
- MESH_DIRTY = 0x00000100,
- NEW_DRAWINFO = 0x00000200,
- IN_BUILD_Q1 = 0x00000400,
- IN_BUILD_Q2 = 0x00000800,
+ GEOM_DIRTY = LLviewerOctreeGroup::INVALID_STATE,
+ ALPHA_DIRTY = (GEOM_DIRTY << 1),
+ IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1),
+ IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1),
+ MESH_DIRTY = (IMAGE_DIRTY << 1),
+ NEW_DRAWINFO = (MESH_DIRTY << 1),
+ IN_BUILD_Q1 = (NEW_DRAWINFO << 1),
+ IN_BUILD_Q2 = (IN_BUILD_Q1 << 1),
STATE_MASK = 0x0000FFFF,
} eSpatialState;
- typedef enum
- {
- STATE_MODE_SINGLE = 0, //set one node
- STATE_MODE_BRANCH, //set entire branch
- STATE_MODE_DIFF, //set entire branch as long as current state is different
- STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras
- } eSetStateMode;
-
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
BOOL isHUDGroup() ;
- BOOL isDead() { return isState(DEAD); }
- BOOL isState(U32 state) const;
- BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
- U32 getState() { return mState; }
- void setState(U32 state);
- void clearState(U32 state);
void clearDrawMap();
void validate();
- void checkStates();
void validateDrawMap();
void setState(U32 state, S32 mode);
void clearState(U32 state, S32 mode);
-
- void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
- void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
+ void clearState(U32 state) {mState &= ~state;}
LLSpatialGroup* getParent();
-
- BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
+ BOOL addObject(LLDrawable *drawablep);
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
- BOOL isVisible() const;
BOOL isRecentlyVisible() const;
- void setVisible();
void shift(const LLVector4a &offset);
- BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
- void unbound();
- BOOL rebound();
- void checkOcclusion(); //read back last occlusion query (if any)
- void doOcclusion(LLCamera* camera); //issue occlusion query
void destroyGL(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
- BOOL needsUpdate();
F32 getUpdateUrgency() const;
BOOL changeLOD();
void rebuildGeom();
void rebuildMesh();
+ void setState(U32 state) {mState |= state;}
void dirtyGeom() { setState(GEOM_DIRTY); }
void dirtyMesh() { setState(MESH_DIRTY); }
- //octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
- element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
- element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
- bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); }
-
- U32 getElementCount() const { return mOctreeNode->getElementCount(); }
- bool isEmpty() const { return mOctreeNode->isEmpty(); }
-
void drawObjectBox(LLColor4 col);
+ LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
+
//LISTENER FUNCTIONS
- virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
- virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
+ virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face);
+ virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
virtual void handleDestruction(const TreeNode* node);
- virtual void handleStateChange(const TreeNode* node);
virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
- virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
//-------------------
//for atlas use
@@ -399,21 +335,6 @@ public:
public:
- typedef enum
- {
- BOUNDS = 0,
- EXTENTS = 2,
- OBJECT_BOUNDS = 4,
- OBJECT_EXTENTS = 6,
- VIEW_ANGLE = 8,
- LAST_VIEW_ANGLE = 9,
- V4_COUNT = 10
- } eV4Index;
-
- LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
- LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
- LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
- LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
LL_ALIGN_16(LLVector4a mViewAngle);
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
@@ -434,11 +355,6 @@ private:
protected:
virtual ~LLSpatialGroup();
- U32 mState;
- U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
- U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
-
- S32 mLODHash;
static S32 sLODSeed;
public:
@@ -449,16 +365,12 @@ public:
F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
F32 mBuilt;
- OctreeNode* mOctreeNode;
- LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
- GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
draw_map_t mDrawMap;
- S32 mVisible[LLViewerCamera::NUM_CAMERAS];
F32 mDistance;
F32 mDepth;
F32 mLastUpdateDistance;
@@ -481,10 +393,10 @@ public:
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
-class LLSpatialPartition: public LLGeometryManager
+class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
{
public:
- LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage);
+ LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp);
virtual ~LLSpatialPartition();
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
@@ -511,7 +423,8 @@ public:
virtual void rebuildMesh(LLSpatialGroup* group);
BOOL visibleObjectsInFrustum(LLCamera& camera);
- S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
+ /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum
+ S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum
BOOL isVisible(const LLVector3& v);
bool isHUDPartition() ;
@@ -524,25 +437,20 @@ public:
void renderIntersectingBBoxes(LLCamera* camera);
void restoreGL();
void resetVertexBuffers();
- BOOL isOcclusionEnabled();
+
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
public:
- LLSpatialGroup::OctreeNode* mOctree;
LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
// to call asBridge() from the destructor
- BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
+
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
U32 mBufferUsage;
const BOOL mRenderByGroup;
- U32 mLODSeed;
- U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
U32 mVertexDataMask;
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
- U32 mDrawableType;
- U32 mPartitionType;
};
// class for creating bridges between spatial partitions
@@ -554,7 +462,7 @@ protected:
public:
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
- LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask);
+ LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp);
void destroyTree();
@@ -676,7 +584,7 @@ private:
class LLWaterPartition : public LLSpatialPartition
{
public:
- LLWaterPartition();
+ LLWaterPartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group) { }
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
};
@@ -685,14 +593,14 @@ public:
class LLVoidWaterPartition : public LLWaterPartition
{
public:
- LLVoidWaterPartition();
+ LLVoidWaterPartition(LLViewerRegion* regionp);
};
//spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
class LLTerrainPartition : public LLSpatialPartition
{
public:
- LLTerrainPartition();
+ LLTerrainPartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group);
virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
@@ -701,7 +609,7 @@ public:
class LLTreePartition : public LLSpatialPartition
{
public:
- LLTreePartition();
+ LLTreePartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group) { }
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
@@ -711,7 +619,7 @@ public:
class LLParticlePartition : public LLSpatialPartition
{
public:
- LLParticlePartition();
+ LLParticlePartition(LLViewerRegion* regionp);
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
@@ -723,14 +631,14 @@ protected:
class LLHUDParticlePartition : public LLParticlePartition
{
public:
- LLHUDParticlePartition();
+ LLHUDParticlePartition(LLViewerRegion* regionp);
};
//spatial partition for grass (implemented in LLVOGrass.cpp)
class LLGrassPartition : public LLSpatialPartition
{
public:
- LLGrassPartition();
+ LLGrassPartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group);
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
protected:
@@ -760,7 +668,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
{
public:
- LLVolumePartition();
+ LLVolumePartition(LLViewerRegion* regionp);
virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
@@ -771,7 +679,7 @@ public:
class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
{
public:
- LLVolumeBridge(LLDrawable* drawable);
+ LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp);
virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
@@ -781,7 +689,7 @@ public:
class LLHUDBridge : public LLVolumeBridge
{
public:
- LLHUDBridge(LLDrawable* drawablep);
+ LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
virtual void shiftPos(const LLVector4a& vec);
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
};
@@ -790,7 +698,7 @@ public:
class LLBridgePartition : public LLSpatialPartition
{
public:
- LLBridgePartition();
+ LLBridgePartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group) { }
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
};
@@ -798,7 +706,7 @@ public:
class LLHUDPartition : public LLBridgePartition
{
public:
- LLHUDPartition();
+ LLHUDPartition(LLViewerRegion* regionp);
virtual void shift(const LLVector4a &offset);
};
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index a4582071e8..dacea187c3 100755
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -34,7 +34,9 @@
#include "llgroupmgr.h"
#include "llsdutil.h"
#include "lluicolortable.h"
+#include "llhttpclient.h"
#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
#include "llvoavatar.h"
#include "llworld.h"
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index cff3a7e02a..de8d549055 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -645,7 +645,7 @@ bool idle_startup()
gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
}
#endif
-
+
if (gAudiop)
{
#if LL_WINDOWS
@@ -2052,7 +2052,7 @@ bool idle_startup()
static LLFrameTimer wearables_timer;
const F32 wearables_time = wearables_timer.getElapsedTimeF32();
- const F32 MAX_WEARABLES_TIME = 10.f;
+ static LLCachedControl<F32> max_wearables_time(gSavedSettings, "ClothingLoadingDelay");
if (!gAgent.isGenderChosen() && isAgentAvatarValid())
{
@@ -2072,10 +2072,10 @@ bool idle_startup()
display_startup();
- if (wearables_time > MAX_WEARABLES_TIME)
+ if (wearables_time > max_wearables_time())
{
LLNotificationsUtil::add("ClothingLoading");
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
+ record(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, wearables_time);
LLStartUp::setStartupState( STATE_CLEANUP );
return TRUE;
}
@@ -2106,7 +2106,7 @@ bool idle_startup()
display_startup();
update_texture_fetch();
display_startup();
- set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME,
+ set_startup_status(0.9f + 0.1f * wearables_time / max_wearables_time(),
LLTrans::getString("LoginDownloadingClothing").c_str(),
gAgent.mMOTD.c_str());
display_startup();
@@ -2186,9 +2186,6 @@ bool idle_startup()
LLAppViewer::instance()->handleLoginComplete();
- // reset timers now that we are running "logged in" logic
- LLFastTimer::reset();
-
LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
display_startup();
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index ff69c6e9fd..f3406d9f8d 100755
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -37,7 +37,6 @@
#include "llviewercontrol.h"
#include "llfloaterbuycurrency.h"
#include "llbuycurrencyhtml.h"
-#include "llfloaterlagmeter.h"
#include "llpanelnearbymedia.h"
#include "llpanelvolumepulldown.h"
#include "llfloaterregioninfo.h"
@@ -199,10 +198,10 @@ BOOL LLStatusBar::postBuild()
sgp.rect(r);
sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
sgp.mouse_opaque(false);
+ sgp.stat.count_stat_float(&LLStatViewer::KBIT);
+ sgp.units("Kbps");
+ sgp.precision(0);
mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp);
- mSGBandwidth->setStat(&LLViewerStats::getInstance()->mKBitStat);
- mSGBandwidth->setUnits("Kbps");
- mSGBandwidth->setPrecision(0);
addChild(mSGBandwidth);
x -= SIM_STAT_WIDTH + 2;
@@ -213,17 +212,20 @@ BOOL LLStatusBar::postBuild()
pgp.rect(r);
pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
pgp.mouse_opaque(false);
+ pgp.stat.sample_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT);
+ pgp.units("%");
+ pgp.min(0.f);
+ pgp.max(5.f);
+ pgp.precision(1);
+ pgp.per_sec(false);
+ LLStatGraph::Thresholds thresholds;
+ thresholds.threshold.add(LLStatGraph::ThresholdParams().value(0.1).color(LLColor4::green))
+ .add(LLStatGraph::ThresholdParams().value(0.25f).color(LLColor4::yellow))
+ .add(LLStatGraph::ThresholdParams().value(0.6f).color(LLColor4::red));
+
+ pgp.thresholds(thresholds);
mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp);
- mSGPacketLoss->setStat(&LLViewerStats::getInstance()->mPacketsLostPercentStat);
- mSGPacketLoss->setUnits("%");
- mSGPacketLoss->setMin(0.f);
- mSGPacketLoss->setMax(5.f);
- mSGPacketLoss->setThreshold(0, 0.5f);
- mSGPacketLoss->setThreshold(1, 1.f);
- mSGPacketLoss->setThreshold(2, 3.f);
- mSGPacketLoss->setPrecision(1);
- mSGPacketLoss->mPerSec = FALSE;
addChild(mSGPacketLoss);
mPanelVolumePulldown = new LLPanelVolumePulldown();
@@ -253,9 +255,9 @@ void LLStatusBar::refresh()
F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;
mSGBandwidth->setMin(0.f);
mSGBandwidth->setMax(bwtotal*1.25f);
- mSGBandwidth->setThreshold(0, bwtotal*0.75f);
- mSGBandwidth->setThreshold(1, bwtotal);
- mSGBandwidth->setThreshold(2, bwtotal);
+ //mSGBandwidth->setThreshold(0, bwtotal*0.75f);
+ //mSGBandwidth->setThreshold(1, bwtotal);
+ //mSGBandwidth->setThreshold(2, bwtotal);
}
// update clock every 10 seconds
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index 9d24bf8771..33a64ae7d5 100755
--- a/indra/newview/llsurface.h
+++ b/indra/newview/llsurface.h
@@ -45,7 +45,6 @@
class LLTimer;
class LLUUID;
class LLAgent;
-class LLStat;
static const U8 NO_EDGE = 0x00;
static const U8 EAST_EDGE = 0x01;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 36a7aeb590..ee3b605cb0 100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -571,10 +571,10 @@ bool LLTextureCacheRemoteWorker::doWrite()
// (almost always) write to the fast cache.
if (mRawImage->getDataSize())
{
- llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
- }
+ llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
}
}
+ }
else
{
alreadyCached = mCache->updateEntry(idx, entry, mImageSize, mDataSize); // update the existing entry.
@@ -922,7 +922,7 @@ void LLTextureCache::setDirNames(ELLPath location)
mFastCacheFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);
}
-void LLTextureCache::purgeCache(ELLPath location)
+void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)
{
LLMutexLock lock(&mHeaderMutex);
@@ -948,7 +948,7 @@ void LLTextureCache::purgeCache(ELLPath location)
}
//remove the current texture cache.
- purgeAllTextures(true);
+ purgeAllTextures(remove_dir);
}
//is called in the main thread before initCache(...) is called.
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index deaacc4975..c2a5cf9405 100755
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -104,7 +104,7 @@ public:
/*virtual*/ S32 update(F32 max_time_ms);
- void purgeCache(ELLPath location);
+ void purgeCache(ELLPath location, bool remove_dir = true);
void setReadOnly(BOOL read_only) ;
S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4676f7b251..3276b2b9e1 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -207,7 +207,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
: LLFloater(LLSD()),
mOwner( owner ),
mImageAssetID( owner->getImageAssetID() ),
- mFallbackImage( fallback_image ),
+ mFallbackImage( fallback_image ),
mOriginalImageAssetID(owner->getImageAssetID()),
mLabel(label),
mTentativeLabel(NULL),
@@ -548,11 +548,11 @@ void LLFloaterTexturePicker::draw()
if (gFocusMgr.childHasMouseCapture(getDragHandle()))
{
- mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
}
else
{
- mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+ mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));
}
updateImageStats();
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 6173e76a35..4b9a950b98 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -53,6 +53,7 @@
#include "llviewerstatsrecorder.h"
#include "llviewerassetstats.h"
#include "llworld.h"
+#include "llsdparam.h"
#include "llsdutil.h"
#include "llstartup.h"
#include "llsdserialize.h"
@@ -64,8 +65,8 @@
#include "bufferstream.h"
bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
-LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);
-LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128);
+LLTrace::SampleStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits");
+LLTrace::SampleStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");
//////////////////////////////////////////////////////////////////////////////
@@ -1246,7 +1247,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
- LLTextureFetch::sCacheHitRate.addValue(100.f);
+ sample(LLTextureFetch::sCacheHitRate, 100.f);
}
else
{
@@ -1264,7 +1265,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
// fall through
- LLTextureFetch::sCacheHitRate.addValue(0.f);
+ sample(LLTextureFetch::sCacheHitRate, 0.f);
}
}
@@ -1884,7 +1885,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
if (log_to_viewer_log || log_to_sim)
{
U64 timeNow = LLTimer::getTotalTime();
- mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime);
+ mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime.value());
mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP);
mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize);
mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset);
@@ -1896,9 +1897,9 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
LLCore::HttpStatus status(response->getStatus());
LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID
- << " status: " << status.toHex()
- << " '" << status.toString() << "'"
- << llendl;
+ << " status: " << status.toHex()
+ << " '" << status.toString() << "'"
+ << llendl;
// unsigned int offset(0), length(0), full_length(0);
// response->getRange(&offset, &length, &full_length);
// llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle
@@ -2329,11 +2330,11 @@ bool LLTextureFetchWorker::writeToCacheComplete()
// Threads: Ttf
void LLTextureFetchWorker::recordTextureStart(bool is_http)
{
- if (! mMetricsStartTime)
+ if (! mMetricsStartTime.value())
{
mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
}
- LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE,
is_http,
LLImageBase::TYPE_AVATAR_BAKE == mType);
}
@@ -2342,15 +2343,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http)
// Threads: Ttf
void LLTextureFetchWorker::recordTextureDone(bool is_http)
{
- if (mMetricsStartTime)
+ if (mMetricsStartTime.value())
{
- LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
+ LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE,
is_http,
LLImageBase::TYPE_AVATAR_BAKE == mType,
LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
mMetricsStartTime = 0;
}
- LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE,
is_http,
LLImageBase::TYPE_AVATAR_BAKE == mType);
}
@@ -2411,6 +2412,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHttpMetricsHeaders = new LLCore::HttpHeaders;
mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
+
+ //reset the texture timer.
+ gTextureTimer.reset();
+ gTextureTimer.pause();
}
LLTextureFetch::~LLTextureFetch()
@@ -2756,7 +2761,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
F32 cache_read_time = worker->mCacheReadTime;
if (cache_read_time != 0.f)
{
- sCacheReadLatency.addValue(cache_read_time * 1000.f);
+ sample(sCacheReadLatency, cache_read_time * 1000.f);
}
res = true;
LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
@@ -2882,7 +2887,7 @@ S32 LLTextureFetch::update(F32 max_time_ms)
mNetworkQueueMutex.lock(); // +Mfnq
mMaxBandwidth = band_width;
- gTextureList.sTextureBits += mHTTPTextureBits;
+ add(LLStatViewer::TEXTURE_KBIT, mHTTPTextureBits);
mHTTPTextureBits = 0;
mNetworkQueueMutex.unlock(); // -Mfnq
@@ -3789,7 +3794,7 @@ AssetReportHandler stats_handler;
bool
TFReqSetRegion::doWork(LLTextureFetch *)
{
- LLViewerAssetStatsFF::set_region_thread1(mRegionHandle);
+ LLViewerAssetStatsFF::set_region(mRegionHandle);
return true;
}
@@ -3814,8 +3819,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
static const U32 report_priority(1);
static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL);
- if (! gViewerAssetStatsThread1)
- return true;
+ //if (! gViewerAssetStatsThread1)
+ // return true;
static volatile bool reporting_started(false);
static volatile S32 report_sequence(0);
@@ -3825,17 +3830,21 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// but leave it in 'this'. Destructor will rid us of it.
LLViewerAssetStats & main_stats = *mMainStats;
- // Merge existing stats into those from main, convert to LLSD
- main_stats.merge(*gViewerAssetStatsThread1);
- LLSD merged_llsd = main_stats.asLLSD(true);
-
- // Add some additional meta fields to the content
- merged_llsd["session_id"] = mSessionID;
- merged_llsd["agent_id"] = mAgentID;
- merged_llsd["message"] = "ViewerAssetMetrics"; // Identifies the type of metrics
- merged_llsd["sequence"] = report_sequence; // Sequence number
- merged_llsd["initial"] = ! reporting_started; // Initial data from viewer
- merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak; // Break in data prior to this report
+ LLViewerAssetStats::AssetStats stats;
+ main_stats.getStats(stats, true);
+ //LLSD merged_llsd = main_stats.asLLSD();
+
+ bool initial_report = !reporting_started;
+ stats.session_id = mSessionID;
+ stats.agent_id = mAgentID;
+ stats.message = "ViewerAssetMetrics";
+ stats.sequence = static_cast<bool>(report_sequence);
+ stats.initial = initial_report;
+ stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);
+
+ LLSD sd;
+ LLParamSDParser parser;
+ parser.writeSD(sd, stats);
// Update sequence number
if (S32_MAX == ++report_sequence)
@@ -3843,13 +3852,14 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
reporting_started = true;
// Limit the size of the stats report if necessary.
- merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd);
+
+ sd["truncated"] = truncate_viewer_metrics(10, sd);
if (! mCapsURL.empty())
{
LLCore::BufferArray * ba = new LLCore::BufferArray;
LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::toXML(merged_llsd, bas);
+ LLSDSerialize::toXML(sd, bas);
fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(),
report_priority,
@@ -3869,11 +3879,9 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// In QA mode, Metrics submode, log the result for ease of testing
if (fetcher->isQAMode())
{
- LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL;
+ LL_INFOS("Textures") << ll_pretty_print_sd(sd) << LL_ENDL;
}
- gViewerAssetStatsThread1->reset();
-
return true;
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 902a3d7a25..7fc58e230c 100755
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -37,15 +37,15 @@
#include "lltextureinfo.h"
#include "llapr.h"
#include "llimageworker.h"
-#include "llstat.h"
#include "llcurl.h"
-#include "llstat.h"
#include "httprequest.h"
#include "httpoptions.h"
#include "httpheaders.h"
#include "httphandler.h"
+#include "lltrace.h"
#include "llviewertexture.h"
+class LLViewerTexture;
class LLTextureFetchWorker;
class LLImageDecodeThread;
class LLHost;
@@ -309,8 +309,8 @@ private:
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
- static LLStat sCacheHitRate;
- static LLStat sCacheReadLatency;
+ static LLTrace::SampleStatHandle<> sCacheHitRate;
+ static LLTrace::SampleStatHandle<> sCacheReadLatency;
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
@@ -330,7 +330,7 @@ private:
LLTextureInfo mTextureInfo;
// XXX possible delete
- U32 mHTTPTextureBits; // Mfnq
+ LLUnit<U32, LLUnits::Bits> mHTTPTextureBits; // Mfnq
// XXX possible delete
//debug use
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index e80136b286..18df9a7b54 100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -49,6 +49,8 @@
#include "llviewertexturelist.h"
#include "llvovolume.h"
#include "llviewerstats.h"
+#include "llworld.h"
+#include "llviewerobjectlist.h"
// For avatar texture view
#include "llvoavatarself.h"
@@ -505,18 +507,21 @@ private:
void LLGLTexMemBar::draw()
{
- S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes);
- S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes;
- S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes);
- S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes;
+ LLUnit<S32, LLUnits::Mibibytes> bound_mem = LLViewerTexture::sBoundTextureMemory;
+ LLUnit<S32, LLUnits::Mibibytes> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem;
+ LLUnit<S32, LLUnits::Mibibytes> total_mem = LLViewerTexture::sTotalTextureMemory;
+ LLUnit<S32, LLUnits::Mibibytes> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
- F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
- F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
+ F32 cache_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ;
+ F32 cache_max_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;
S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
- F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024);
- F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024);
+ LLUnit<F32, LLUnits::Bytes> total_texture_downloaded = gTotalTextureData;
+ LLUnit<F32, LLUnits::Bytes> total_object_downloaded = gTotalObjectData;
U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests();
+ U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects();
+ U32 total_objects = gObjectList.getNumObjects();
+
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@@ -532,10 +537,10 @@ void LLGLTexMemBar::draw()
text_color, LLFontGL::LEFT, LLFontGL::TOP);
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
- total_mem,
- max_total_mem,
- bound_mem,
- max_bound_mem,
+ total_mem.value(),
+ max_total_mem.value(),
+ bound_mem.value(),
+ max_bound_mem.value(),
LLRenderTarget::sBytesAllocated/(1024*1024),
LLImageRaw::sGlobalRawMemory >> 20,
discard_bias,
@@ -549,9 +554,11 @@ void LLGLTexMemBar::draw()
U32 cache_read(0U), cache_write(0U), res_wait(0U);
LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
- text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
- total_texture_downloaded,
- total_object_downloaded,
+ text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#Cached: %d/%d Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
+ total_texture_downloaded.value(),
+ total_object_downloaded.value(),
+ total_objects,
+ total_active_cached_objects,
total_http_requests,
cache_read,
cache_write,
@@ -679,7 +686,7 @@ void LLGLTexSizeBar::draw()
if(LLImageGL::sCurTexSizeBar == mIndex)
{
- F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};
+ LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
std::string text;
text = llformat("%d", mTopLoaded) ;
@@ -691,8 +698,8 @@ void LLGLTexSizeBar::draw()
text_color, LLFontGL::LEFT, LLFontGL::TOP);
}
- F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
- F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
+ LLColor4 loaded_color(1.0f, 0.0f, 0.0f, 0.75f);
+ LLColor4 bound_color(1.0f, 1.0f, 0.0f, 0.75f);
gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ;
gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ;
}
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 3f75f8da5e..85232f4a0b 100755
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -42,7 +42,6 @@
#include "lllineeditor.h"
#include "lluictrlfactory.h"
#include "llnotifications.h"
-#include "llfunctorregistry.h"
#include "llrootview.h"
#include "lltransientfloatermgr.h"
#include "llviewercontrol.h" // for gSavedSettings
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index b2318f9158..ed0f22f16a 100755
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -521,7 +521,7 @@ void LLToolBarView::draw()
{
if (mToolbars[i])
{
- LLLayoutStack::ELayoutOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType());
+ LLView::EOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType());
if (orientation == LLLayoutStack::HORIZONTAL)
{
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index e085834326..a4dce9efe8 100755
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1094,7 +1094,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
return;
}
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ add(LLStatViewer::EDIT_TEXTURE, 1);
S32 num_faces = hit_obj->getNumTEs();
for( S32 face = 0; face < num_faces; face++ )
{
@@ -1162,7 +1162,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
}
// update viewer side image in anticipation of update from simulator
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ add(LLStatViewer::EDIT_TEXTURE, 1);
hit_obj->setTEImage(hit_face, image);
dialog_refresh_all();
@@ -1386,7 +1386,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
effectp->setDuration(LL_HUD_DUR_SHORT);
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT);
+ add(LLStatViewer::OBJECT_REZ, 1);
}
void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index fc9a316759..c912d81a03 100755
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -42,6 +42,7 @@
#include "llfloaterscriptdebug.h"
#include "lltooltip.h"
#include "llhudeffecttrail.h"
+#include "llhudicon.h"
#include "llhudmanager.h"
#include "llkeyboard.h"
#include "llmediaentry.h"
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 641fbc5042..b7718847ae 100755
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -433,7 +433,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
effectp->setDuration(LL_HUD_DUR_SHORT);
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT);
+ add(LLStatViewer::OBJECT_CREATE, 1);
return TRUE;
}
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 7c604a04bf..0a9153eecb 100755
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -32,6 +32,7 @@
#include "llagentcamera.h"
#include "llviewercontrol.h"
#include "lldrawable.h"
+#include "llhudicon.h"
#include "llmanip.h"
#include "llmenugl.h"
#include "llselectmgr.h"
diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h
index baa27f6071..74dababe8c 100755
--- a/indra/newview/lltoolselect.h
+++ b/indra/newview/lltoolselect.h
@@ -34,7 +34,7 @@
class LLObjectSelection;
-class LLToolSelect : public LLTool, public LLSingleton<LLToolSelect>
+class LLToolSelect : public LLTool
{
public:
LLToolSelect( LLToolComposite* composite );
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index aaa81c57d4..bada565d3d 100755
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -31,6 +31,8 @@
#include "stdtypes.h"
#include "llvoavatar.h"
+#include "llsdparam.h"
+#include "llsdutil.h"
/*
* Classes and utility functions for per-thread and per-region
@@ -78,126 +80,258 @@
*
*/
-
-// ------------------------------------------------------
-// Global data definitions
-// ------------------------------------------------------
-LLViewerAssetStats * gViewerAssetStatsMain(0);
-LLViewerAssetStats * gViewerAssetStatsThread1(0);
-
-
-// ------------------------------------------------------
-// Local declarations
-// ------------------------------------------------------
-namespace
+namespace LLViewerAssetStatsFF
{
+ static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp)
+ {
+ // For statistical purposes, we divide GETs into several
+ // populations of asset fetches:
+ // - textures which are de-prioritized in the asset system
+ // - wearables (clothing, bodyparts) which directly affect
+ // user experiences when they log in
+ // - sounds
+ // - gestures
+ // - everything else.
+ //
+ llassert_always(50 == LLViewerAssetType::AT_COUNT);
+
+ // Multiple asset definitions are floating around so this requires some
+ // maintenance and attention.
+ static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] =
+ {
+ EVACTextureTempHTTPGet, // (0) AT_TEXTURE
+ EVACSoundUDPGet, // AT_SOUND
+ EVACOtherGet, // AT_CALLINGCARD
+ EVACOtherGet, // AT_LANDMARK
+ EVACOtherGet, // AT_SCRIPT
+ EVACWearableUDPGet, // AT_CLOTHING
+ EVACOtherGet, // AT_OBJECT
+ EVACOtherGet, // AT_NOTECARD
+ EVACOtherGet, // AT_CATEGORY
+ EVACOtherGet, // AT_ROOT_CATEGORY
+ EVACOtherGet, // (10) AT_LSL_TEXT
+ EVACOtherGet, // AT_LSL_BYTECODE
+ EVACOtherGet, // AT_TEXTURE_TGA
+ EVACWearableUDPGet, // AT_BODYPART
+ EVACOtherGet, // AT_TRASH
+ EVACOtherGet, // AT_SNAPSHOT_CATEGORY
+ EVACOtherGet, // AT_LOST_AND_FOUND
+ EVACSoundUDPGet, // AT_SOUND_WAV
+ EVACOtherGet, // AT_IMAGE_TGA
+ EVACOtherGet, // AT_IMAGE_JPEG
+ EVACGestureUDPGet, // (20) AT_ANIMATION
+ EVACGestureUDPGet, // AT_GESTURE
+ EVACOtherGet, // AT_SIMSTATE
+ EVACOtherGet, // AT_FAVORITE
+ EVACOtherGet, // AT_LINK
+ EVACOtherGet, // AT_LINK_FOLDER
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, // (30)
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, // (40)
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, //
+ EVACOtherGet, // AT_MESH
+ // (50)
+ };
-static LLViewerAssetStats::EViewerAssetCategories
-asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp);
-
+ if (at < 0 || at >= LLViewerAssetType::AT_COUNT)
+{
+ return EVACOtherGet;
}
-
-// ------------------------------------------------------
-// LLViewerAssetStats::PerRegionStats struct definition
-// ------------------------------------------------------
-void
-LLViewerAssetStats::PerRegionStats::reset()
+ EViewerAssetCategories ret(asset_to_bin_map[at]);
+ if (EVACTextureTempHTTPGet == ret)
+ {
+ // Indexed with [is_temp][with_http]
+ static const EViewerAssetCategories texture_bin_map[2][2] =
{
- for (int i(0); i < LL_ARRAY_SIZE(mRequests); ++i)
{
- mRequests[i].mEnqueued.reset();
- mRequests[i].mDequeued.reset();
- mRequests[i].mResponse.reset();
+ EVACTextureNonTempUDPGet,
+ EVACTextureNonTempHTTPGet,
+ },
+ {
+ EVACTextureTempUDPGet,
+ EVACTextureTempHTTPGet,
}
- mFPS.reset();
+ };
- mTotalTime = 0;
- mStartTimestamp = LLViewerAssetStatsFF::get_timestamp();
+ ret = texture_bin_map[is_temp][with_http];
+ }
+ return ret;
}
-
-void
-LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionStats & src)
-{
- // mRegionHandle, mTotalTime, mStartTimestamp are left alone.
+ static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP ("enqueuedassetrequeststemptexturehttp",
+ "Number of temporary texture asset http requests enqueued"),
+ sEnqueueAssetRequestsTempTextureUDP ("enqueuedassetrequeststemptextureudp",
+ "Number of temporary texture asset udp requests enqueued"),
+ sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp",
+ "Number of texture asset http requests enqueued"),
+ sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp",
+ "Number of texture asset udp requests enqueued"),
+ sEnqueuedAssetRequestsWearableUdp ("enqueuedassetrequestswearableudp",
+ "Number of wearable asset requests enqueued"),
+ sEnqueuedAssetRequestsSoundUdp ("enqueuedassetrequestssoundudp",
+ "Number of sound asset requests enqueued"),
+ sEnqueuedAssetRequestsGestureUdp ("enqueuedassetrequestsgestureudp",
+ "Number of gesture asset requests enqueued"),
+ sEnqueuedAssetRequestsOther ("enqueuedassetrequestsother",
+ "Number of other asset requests enqueued");
+
+ static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = {
+ &sEnqueueAssetRequestsTempTextureHTTP,
+ &sEnqueueAssetRequestsTempTextureUDP,
+ &sEnqueueAssetRequestsNonTempTextureHTTP,
+ &sEnqueueAssetRequestsNonTempTextureUDP,
+ &sEnqueuedAssetRequestsWearableUdp,
+ &sEnqueuedAssetRequestsSoundUdp,
+ &sEnqueuedAssetRequestsGestureUdp,
+ &sEnqueuedAssetRequestsOther
+ };
- // mFPS
- if (src.mFPS.getCount() && mFPS.getCount())
- {
- mFPS.merge(src.mFPS);
- }
-
- // Avatar stats - data all comes from main thread, so leave alone.
-
- // Requests
- for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
- {
- mRequests[i].mEnqueued.merge(src.mRequests[i].mEnqueued);
- mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued);
- mRequests[i].mResponse.merge(src.mRequests[i].mResponse);
- }
-
-}
-
-
-void
-LLViewerAssetStats::PerRegionStats::accumulateTime(duration_t now)
-{
- mTotalTime += (now - mStartTimestamp);
- mStartTimestamp = now;
+ static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP ("dequeuedassetrequeststemptexturehttp",
+ "Number of temporary texture asset http requests dequeued"),
+ sDequeueAssetRequestsTempTextureUDP ("dequeuedassetrequeststemptextureudp",
+ "Number of temporary texture asset udp requests dequeued"),
+ sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp",
+ "Number of texture asset http requests dequeued"),
+ sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp",
+ "Number of texture asset udp requests dequeued"),
+ sDequeuedAssetRequestsWearableUdp ("dequeuedassetrequestswearableudp",
+ "Number of wearable asset requests dequeued"),
+ sDequeuedAssetRequestsSoundUdp ("dequeuedassetrequestssoundudp",
+ "Number of sound asset requests dequeued"),
+ sDequeuedAssetRequestsGestureUdp ("dequeuedassetrequestsgestureudp",
+ "Number of gesture asset requests dequeued"),
+ sDequeuedAssetRequestsOther ("dequeuedassetrequestsother",
+ "Number of other asset requests dequeued");
+
+ static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = {
+ &sDequeueAssetRequestsTempTextureHTTP,
+ &sDequeueAssetRequestsTempTextureUDP,
+ &sDequeueAssetRequestsNonTempTextureHTTP,
+ &sDequeueAssetRequestsNonTempTextureUDP,
+ &sDequeuedAssetRequestsWearableUdp,
+ &sDequeuedAssetRequestsSoundUdp,
+ &sDequeuedAssetRequestsGestureUdp,
+ &sDequeuedAssetRequestsOther
+ };
+
+ static LLTrace::EventStatHandle<LLTrace::Seconds> sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp",
+ "Time spent responding to temporary texture asset http requests"),
+ sResponseAssetRequestsTempTextureUDP ("assetresponsetimestemptextureudp",
+ "Time spent responding to temporary texture asset udp requests"),
+ sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp",
+ "Time spent responding to texture asset http requests"),
+ sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp",
+ "Time spent responding to texture asset udp requests"),
+ sResponsedAssetRequestsWearableUdp ("assetresponsetimeswearableudp",
+ "Time spent responding to wearable asset requests"),
+ sResponsedAssetRequestsSoundUdp ("assetresponsetimessoundudp",
+ "Time spent responding to sound asset requests"),
+ sResponsedAssetRequestsGestureUdp ("assetresponsetimesgestureudp",
+ "Time spent responding to gesture asset requests"),
+ sResponsedAssetRequestsOther ("assetresponsetimesother",
+ "Time spent responding to other asset requests");
+
+ static LLTrace::EventStatHandle<LLTrace::Seconds>* sResponse[EVACCount] = {
+ &sResponseAssetRequestsTempTextureHTTP,
+ &sResponseAssetRequestsTempTextureUDP,
+ &sResponseAssetRequestsNonTempTextureHTTP,
+ &sResponseAssetRequestsNonTempTextureUDP,
+ &sResponsedAssetRequestsWearableUdp,
+ &sResponsedAssetRequestsSoundUdp,
+ &sResponsedAssetRequestsGestureUdp,
+ &sResponsedAssetRequestsOther
+ };
}
+// ------------------------------------------------------
+// Global data definitions
+// ------------------------------------------------------
+LLViewerAssetStats * gViewerAssetStats(0);
// ------------------------------------------------------
// LLViewerAssetStats class definition
// ------------------------------------------------------
LLViewerAssetStats::LLViewerAssetStats()
- : mRegionHandle(U64(0))
+: mRegionHandle(U64(0)),
+ mCurRecording(NULL)
{
- reset();
+ start();
}
LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
- : mRegionHandle(src.mRegionHandle),
- mResetTimestamp(src.mResetTimestamp)
+: mRegionHandle(src.mRegionHandle)
{
- const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
- for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
+ mRegionRecordings = src.mRegionRecordings;
+
+ mCurRecording = &mRegionRecordings[mRegionHandle];
+
+ // assume this is being passed to another thread, so make sure we have unique copies of recording data
+ for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end();
+ it != end_it;
+ ++it)
{
- mRegionStats[it->first] = new PerRegionStats(*it->second);
+ it->second.stop();
+ it->second.makeUnique();
}
- mCurRegionStats = mRegionStats[mRegionHandle];
-}
+ LLStopWatchControlsMixin<LLViewerAssetStats>::setPlayState(src.getPlayState());
+}
-void
-LLViewerAssetStats::reset()
+void LLViewerAssetStats::handleStart()
{
- // Empty the map of all region stats
- mRegionStats.clear();
+ if (mCurRecording)
+ {
+ mCurRecording->start();
+ }
+}
- // If we have a current stats, reset it, otherwise, as at construction,
- // create a new one as we must always have a current stats block.
- if (mCurRegionStats)
+void LLViewerAssetStats::handleStop()
+{
+ if (mCurRecording)
{
- mCurRegionStats->reset();
+ mCurRecording->stop();
}
- else
+}
+
+void LLViewerAssetStats::handleReset()
{
- mCurRegionStats = new PerRegionStats(mRegionHandle);
+ reset();
}
- // And add reference to map
- mRegionStats[mRegionHandle] = mCurRegionStats;
- // Start timestamp consistent with per-region collector
- mResetTimestamp = mCurRegionStats->mStartTimestamp;
-}
+void LLViewerAssetStats::reset()
+{
+ // Empty the map of all region stats
+ mRegionRecordings.clear();
+ // initialize new recording for current region
+ if (mRegionHandle)
+ {
+ mCurRecording = &mRegionRecordings[mRegionHandle];
+ }
+}
-void
-LLViewerAssetStats::setRegion(region_handle_t region_handle)
+void LLViewerAssetStats::setRegion(region_handle_t region_handle)
{
if (region_handle == mRegionHandle)
{
@@ -205,171 +339,173 @@ LLViewerAssetStats::setRegion(region_handle_t region_handle)
return;
}
- // Get duration for current set
- const duration_t now = LLViewerAssetStatsFF::get_timestamp();
- mCurRegionStats->accumulateTime(now);
-
- // Prepare new set
- PerRegionContainer::iterator new_stats = mRegionStats.find(region_handle);
- if (mRegionStats.end() == new_stats)
+ if (mCurRecording)
{
- // Haven't seen this region_id before, create a new block and make it current.
- mCurRegionStats = new PerRegionStats(region_handle);
- mRegionStats[region_handle] = mCurRegionStats;
+ mCurRecording->pause();
}
- else
+ if (region_handle)
{
- mCurRegionStats = new_stats->second;
+ mCurRecording = &mRegionRecordings[region_handle];
+ mCurRecording->start();
}
- mCurRegionStats->mStartTimestamp = now;
+
mRegionHandle = region_handle;
}
+void LLViewerAssetStats::updateStats()
+{
+ if (mCurRecording && mCurRecording->isStarted())
+ {
+ mCurRecording->update();
+ }
+}
-void
-LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
{
- const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
+ using namespace LLViewerAssetStatsFF;
+
+ stats.regions.setProvided();
- ++(mCurRegionStats->mRequests[int(eac)].mEnqueued);
+ for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end();
+ it != end_it;
+ ++it)
+ {
+ RegionStats& r = stats.regions.add();
+ LLTrace::Recording& rec = it->second;
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])
+ || rec.getSum(*sDequeued[EVACTextureTempHTTPGet])
+ || rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value())
+ {
+ r.get_texture_temp_http .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value());
}
-
-void
-LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACTextureTempUDPGet])
+ || rec.getSum(*sDequeued[EVACTextureTempUDPGet])
+ || rec.getSum(*sResponse[EVACTextureTempUDPGet]).value())
{
- const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
-
- ++(mCurRegionStats->mRequests[int(eac)].mDequeued);
+ r.get_texture_temp_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value());
}
-
-void
-LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])
+ || rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])
+ || rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value())
{
- const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
-
- mCurRegionStats->mRequests[int(eac)].mResponse.record(duration);
+ r.get_texture_non_temp_http .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value());
}
-void
-LLViewerAssetStats::recordFPS(F32 fps)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])
+ || rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])
+ || rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value())
{
- mCurRegionStats->mFPS.record(fps);
+ r.get_texture_non_temp_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value());
}
-LLSD
-LLViewerAssetStats::asLLSD(bool compact_output)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACWearableUDPGet])
+ || rec.getSum(*sDequeued[EVACWearableUDPGet])
+ || rec.getSum(*sResponse[EVACWearableUDPGet]).value())
{
- // Top-level tags
- static const LLSD::String tags[EVACCount] =
- {
- LLSD::String("get_texture_temp_http"),
- LLSD::String("get_texture_temp_udp"),
- LLSD::String("get_texture_non_temp_http"),
- LLSD::String("get_texture_non_temp_udp"),
- LLSD::String("get_wearable_udp"),
- LLSD::String("get_sound_udp"),
- LLSD::String("get_gesture_udp"),
- LLSD::String("get_other")
- };
+ r.get_wearable_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACWearableUDPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACWearableUDPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACWearableUDPGet]).value());
+ }
- // Stats Group Sub-tags.
- static const LLSD::String enq_tag("enqueued");
- static const LLSD::String deq_tag("dequeued");
- static const LLSD::String rcnt_tag("resp_count");
- static const LLSD::String rmin_tag("resp_min");
- static const LLSD::String rmax_tag("resp_max");
- static const LLSD::String rmean_tag("resp_mean");
-
- // MMM Group Sub-tags.
- static const LLSD::String cnt_tag("count");
- static const LLSD::String min_tag("min");
- static const LLSD::String max_tag("max");
- static const LLSD::String mean_tag("mean");
-
- const duration_t now = LLViewerAssetStatsFF::get_timestamp();
- mCurRegionStats->accumulateTime(now);
-
- LLSD regions = LLSD::emptyArray();
- for (PerRegionContainer::iterator it = mRegionStats.begin();
- mRegionStats.end() != it;
- ++it)
- {
- if (0 == it->first)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACSoundUDPGet])
+ || rec.getSum(*sDequeued[EVACSoundUDPGet])
+ || rec.getSum(*sResponse[EVACSoundUDPGet]).value())
{
- // Never emit NULL UUID/handle in results.
- continue;
+ r.get_sound_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACSoundUDPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACSoundUDPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACSoundUDPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACSoundUDPGet]).value());
}
- PerRegionStats & stats = *it->second;
-
- LLSD reg_stat = LLSD::emptyMap();
-
- for (int i = 0; i < LL_ARRAY_SIZE(tags); ++i)
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACGestureUDPGet])
+ || rec.getSum(*sDequeued[EVACGestureUDPGet])
+ || rec.getSum(*sResponse[EVACGestureUDPGet]).value())
{
- PerRegionStats::prs_group & group(stats.mRequests[i]);
+ r.get_gesture_udp .enqueued((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACGestureUDPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACGestureUDPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value());
+ }
- if ((! compact_output) ||
- group.mEnqueued.getCount() ||
- group.mDequeued.getCount() ||
- group.mResponse.getCount())
+ if (!compact_output
+ || rec.getSum(*sEnqueued[EVACOtherGet])
+ || rec.getSum(*sDequeued[EVACOtherGet])
+ || rec.getSum(*sResponse[EVACOtherGet]).value())
{
- LLSD & slot = reg_stat[tags[i]];
- slot = LLSD::emptyMap();
- slot[enq_tag] = LLSD(S32(stats.mRequests[i].mEnqueued.getCount()));
- slot[deq_tag] = LLSD(S32(stats.mRequests[i].mDequeued.getCount()));
- slot[rcnt_tag] = LLSD(S32(stats.mRequests[i].mResponse.getCount()));
- slot[rmin_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMin() * 1.0e-6));
- slot[rmax_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMax() * 1.0e-6));
- slot[rmean_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMean() * 1.0e-6));
- }
+ r.get_other .enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACOtherGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACOtherGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value());
}
- if ((! compact_output) || stats.mFPS.getCount())
+ S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE);
+ if (!compact_output || fps != 0)
{
- LLSD & slot = reg_stat["fps"];
- slot = LLSD::emptyMap();
- slot[cnt_tag] = LLSD(S32(stats.mFPS.getCount()));
- slot[min_tag] = LLSD(F64(stats.mFPS.getMin()));
- slot[max_tag] = LLSD(F64(stats.mFPS.getMax()));
- slot[mean_tag] = LLSD(F64(stats.mFPS.getMean()));
+ r.fps.count(fps);
+ r.fps.min(rec.getMin(LLStatViewer::FPS_SAMPLE));
+ r.fps.max(rec.getMax(LLStatViewer::FPS_SAMPLE));
+ r.fps.mean(rec.getMean(LLStatViewer::FPS_SAMPLE));
}
U32 grid_x(0), grid_y(0);
grid_from_region_handle(it->first, &grid_x, &grid_y);
- reg_stat["grid_x"] = LLSD::Integer(grid_x);
- reg_stat["grid_y"] = LLSD::Integer(grid_y);
- reg_stat["duration"] = LLSD::Real(stats.mTotalTime * 1.0e-6);
- regions.append(reg_stat);
+ r.grid_x(grid_x);
+ r.grid_y(grid_y);
+ r.duration(LLUnit<F64, LLUnits::Microseconds>(rec.getDuration()).value());
}
- LLSD ret = LLSD::emptyMap();
- ret["regions"] = regions;
- ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6);
-
- return ret;
+ stats.duration(mCurRecording ? LLUnit<F64, LLUnits::Microseconds>(mCurRecording->getDuration()).value() : 0.0);
}
-void
-LLViewerAssetStats::merge(const LLViewerAssetStats & src)
-{
- // mRegionHandle, mCurRegionStats and mResetTimestamp are left untouched.
- // Just merge the stats bodies
-
- const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
- for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
- {
- PerRegionContainer::iterator dst(mRegionStats.find(it->first));
- if (mRegionStats.end() == dst)
+LLSD LLViewerAssetStats::asLLSD(bool compact_output)
{
- // Destination is missing data, just make a private copy
- mRegionStats[it->first] = new PerRegionStats(*it->second);
- }
- else
+ LLParamSDParser parser;
+ LLSD sd;
+ AssetStats stats;
+ getStats(stats, compact_output);
+ LLInitParam::predicate_rule_t rule = LLInitParam::default_parse_rules();
+ if (!compact_output)
{
- dst->second->merge(*it->second);
+ rule.allow(LLInitParam::EMPTY);
}
+ parser.writeSD(sd, stats, rule);
+ return sd;
}
-}
-
// ------------------------------------------------------
// Global free-function definitions (LLViewerAssetStatsFF namespace)
@@ -377,238 +513,93 @@ LLViewerAssetStats::merge(const LLViewerAssetStats & src)
namespace LLViewerAssetStatsFF
{
-
-//
-// Target thread is elaborated in the function name. This could
-// have been something 'templatey' like specializations iterated
-// over a set of constants but with so few, this is clearer I think.
-//
-// As for the threads themselves... rather than do fine-grained
-// locking as we gather statistics, this code creates a collector
-// for each thread, allocated and run independently. Logging
-// happens at relatively infrequent intervals and at that time
-// the data is sent to a single thread to be aggregated into
-// a single entity with locks, thread safety and other niceties.
-//
-// A particularly fussy implementation would distribute the
-// per-thread pointers across separate cache lines. But that should
-// be beyond current requirements.
-//
-
-// 'main' thread - initial program thread
-
-void
-set_region_main(LLViewerAssetStats::region_handle_t region_handle)
+void set_region(LLViewerAssetStats::region_handle_t region_handle)
{
- if (! gViewerAssetStatsMain)
+ if (! gViewerAssetStats)
return;
- gViewerAssetStatsMain->setRegion(region_handle);
+ gViewerAssetStats->setRegion(region_handle);
}
-void
-record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
{
- if (! gViewerAssetStatsMain)
- return;
-
- gViewerAssetStatsMain->recordGetEnqueued(at, with_http, is_temp);
-}
-
-void
-record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
-{
- if (! gViewerAssetStatsMain)
- return;
-
- gViewerAssetStatsMain->recordGetDequeued(at, with_http, is_temp);
-}
-
-void
-record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
-{
- if (! gViewerAssetStatsMain)
- return;
-
- gViewerAssetStatsMain->recordGetServiced(at, with_http, is_temp, duration);
-}
-
-void
-record_fps_main(F32 fps)
-{
- if (! gViewerAssetStatsMain)
- return;
-
- gViewerAssetStatsMain->recordFPS(fps);
-}
-
-// 'thread1' - should be for TextureFetch thread
-
-void
-set_region_thread1(LLViewerAssetStats::region_handle_t region_handle)
-{
- if (! gViewerAssetStatsThread1)
- return;
-
- gViewerAssetStatsThread1->setRegion(region_handle);
-}
-
-void
-record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
-{
- if (! gViewerAssetStatsThread1)
- return;
+ const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
- gViewerAssetStatsThread1->recordGetEnqueued(at, with_http, is_temp);
+ add(*sEnqueued[int(eac)], 1);
}
-void
-record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
{
- if (! gViewerAssetStatsThread1)
- return;
+ const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
- gViewerAssetStatsThread1->recordGetDequeued(at, with_http, is_temp);
+ add(*sDequeued[int(eac)], 1);
}
-void
-record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
+void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
{
- if (! gViewerAssetStatsThread1)
- return;
+ const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
- gViewerAssetStatsThread1->recordGetServiced(at, with_http, is_temp, duration);
+ record(*sResponse[int(eac)], LLTrace::Microseconds(duration));
}
-
-void
-init()
+void init()
{
- if (! gViewerAssetStatsMain)
- {
- gViewerAssetStatsMain = new LLViewerAssetStats();
- }
- if (! gViewerAssetStatsThread1)
+ if (! gViewerAssetStats)
{
- gViewerAssetStatsThread1 = new LLViewerAssetStats();
+ gViewerAssetStats = new LLViewerAssetStats();
}
}
void
cleanup()
{
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = 0;
-
- delete gViewerAssetStatsThread1;
- gViewerAssetStatsThread1 = 0;
+ delete gViewerAssetStats;
+ gViewerAssetStats = 0;
}
} // namespace LLViewerAssetStatsFF
-// ------------------------------------------------------
-// Local function definitions
-// ------------------------------------------------------
-
-namespace
-{
-LLViewerAssetStats::EViewerAssetCategories
-asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp)
-{
- // For statistical purposes, we divide GETs into several
- // populations of asset fetches:
- // - textures which are de-prioritized in the asset system
- // - wearables (clothing, bodyparts) which directly affect
- // user experiences when they log in
- // - sounds
- // - gestures
- // - everything else.
- //
- llassert_always(50 == LLViewerAssetType::AT_COUNT);
-
- // Multiple asset definitions are floating around so this requires some
- // maintenance and attention.
- static const LLViewerAssetStats::EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] =
- {
- LLViewerAssetStats::EVACTextureTempHTTPGet, // (0) AT_TEXTURE
- LLViewerAssetStats::EVACSoundUDPGet, // AT_SOUND
- LLViewerAssetStats::EVACOtherGet, // AT_CALLINGCARD
- LLViewerAssetStats::EVACOtherGet, // AT_LANDMARK
- LLViewerAssetStats::EVACOtherGet, // AT_SCRIPT
- LLViewerAssetStats::EVACWearableUDPGet, // AT_CLOTHING
- LLViewerAssetStats::EVACOtherGet, // AT_OBJECT
- LLViewerAssetStats::EVACOtherGet, // AT_NOTECARD
- LLViewerAssetStats::EVACOtherGet, // AT_CATEGORY
- LLViewerAssetStats::EVACOtherGet, // AT_ROOT_CATEGORY
- LLViewerAssetStats::EVACOtherGet, // (10) AT_LSL_TEXT
- LLViewerAssetStats::EVACOtherGet, // AT_LSL_BYTECODE
- LLViewerAssetStats::EVACOtherGet, // AT_TEXTURE_TGA
- LLViewerAssetStats::EVACWearableUDPGet, // AT_BODYPART
- LLViewerAssetStats::EVACOtherGet, // AT_TRASH
- LLViewerAssetStats::EVACOtherGet, // AT_SNAPSHOT_CATEGORY
- LLViewerAssetStats::EVACOtherGet, // AT_LOST_AND_FOUND
- LLViewerAssetStats::EVACSoundUDPGet, // AT_SOUND_WAV
- LLViewerAssetStats::EVACOtherGet, // AT_IMAGE_TGA
- LLViewerAssetStats::EVACOtherGet, // AT_IMAGE_JPEG
- LLViewerAssetStats::EVACGestureUDPGet, // (20) AT_ANIMATION
- LLViewerAssetStats::EVACGestureUDPGet, // AT_GESTURE
- LLViewerAssetStats::EVACOtherGet, // AT_SIMSTATE
- LLViewerAssetStats::EVACOtherGet, // AT_FAVORITE
- LLViewerAssetStats::EVACOtherGet, // AT_LINK
- LLViewerAssetStats::EVACOtherGet, // AT_LINK_FOLDER
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, // (30)
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, // (40)
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, //
- LLViewerAssetStats::EVACOtherGet, // AT_MESH
- // (50)
- };
+LLViewerAssetStats::AssetRequestType::AssetRequestType()
+: enqueued("enqueued"),
+ dequeued("dequeued"),
+ resp_count("resp_count"),
+ resp_min("resp_min"),
+ resp_max("resp_max"),
+ resp_mean("resp_mean")
+{}
- if (at < 0 || at >= LLViewerAssetType::AT_COUNT)
- {
- return LLViewerAssetStats::EVACOtherGet;
- }
- LLViewerAssetStats::EViewerAssetCategories ret(asset_to_bin_map[at]);
- if (LLViewerAssetStats::EVACTextureTempHTTPGet == ret)
- {
- // Indexed with [is_temp][with_http]
- static const LLViewerAssetStats::EViewerAssetCategories texture_bin_map[2][2] =
- {
- {
- LLViewerAssetStats::EVACTextureNonTempUDPGet,
- LLViewerAssetStats::EVACTextureNonTempHTTPGet,
- },
- {
- LLViewerAssetStats::EVACTextureTempUDPGet,
- LLViewerAssetStats::EVACTextureTempHTTPGet,
- }
- };
-
- ret = texture_bin_map[is_temp][with_http];
- }
- return ret;
-}
-
-} // anonymous namespace
+LLViewerAssetStats::FPSStats::FPSStats()
+: count("count"),
+ min("min"),
+ max("max"),
+ mean("mean")
+{}
+
+LLViewerAssetStats::RegionStats::RegionStats()
+: get_texture_temp_http("get_texture_temp_http"),
+ get_texture_temp_udp("get_texture_temp_udp"),
+ get_texture_non_temp_http("get_texture_non_temp_http"),
+ get_texture_non_temp_udp("get_texture_non_temp_udp"),
+ get_wearable_udp("get_wearable_udp"),
+ get_sound_udp("get_sound_udp"),
+ get_gesture_udp("get_gesture_udp"),
+ get_other("get_other"),
+ fps("fps"),
+ grid_x("grid_x"),
+ grid_y("grid_y"),
+ duration("duration")
+{}
+
+LLViewerAssetStats::AssetStats::AssetStats()
+: regions("regions"),
+ duration("duration"),
+ session_id("session_id"),
+ agent_id("agent_id"),
+ message("message"),
+ sequence("sequence"),
+ initial("initial"),
+ break_("break")
+{}
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
index e4581d2120..2126d569f8 100755
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -37,6 +37,8 @@
#include "llsimplestat.h"
#include "llsd.h"
#include "llvoavatar.h"
+#include "lltrace.h"
+#include "llinitparam.h"
/**
* @class LLViewerAssetStats
@@ -73,29 +75,15 @@
* LLViewerAssetStatsFF is provided for conditional test-and-call
* operations.
*/
-class LLViewerAssetStats
+class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>
{
public:
- enum EViewerAssetCategories
- {
- EVACTextureTempHTTPGet, //< Texture GETs - temp/baked, HTTP
- EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP
- EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP
- EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP
- EVACWearableUDPGet, //< Wearable GETs
- EVACSoundUDPGet, //< Sound GETs
- EVACGestureUDPGet, //< Gesture GETs
- EVACOtherGet, //< Other GETs
-
- EVACCount // Must be last
- };
-
/**
* Type for duration and other time values in the metrics. Selected
* for compatibility with the pre-existing timestamp on the texture
* fetcher class, LLTextureFetch.
*/
- typedef U64 duration_t;
+ typedef LLUnit<U64, LLUnits::Microseconds> duration_t;
/**
* Type for the region identifier used in stats. Currently uses
@@ -104,64 +92,65 @@ public:
*/
typedef U64 region_handle_t;
- /**
- * @brief Collected data for a single region visited by the avatar.
- *
- * Fairly simple, for each asset bin enumerated above a count
- * of enqueue and dequeue operations and simple stats on response
- * times for completed requests.
- */
- class PerRegionStats : public LLRefCount
+ struct AssetRequestType : public LLInitParam::Block<AssetRequestType>
{
- public:
- PerRegionStats(const region_handle_t region_handle)
- : LLRefCount(),
- mRegionHandle(region_handle)
- {
- reset();
- }
-
- PerRegionStats(const PerRegionStats & src)
- : LLRefCount(),
- mRegionHandle(src.mRegionHandle),
- mTotalTime(src.mTotalTime),
- mStartTimestamp(src.mStartTimestamp),
- mFPS(src.mFPS)
+ Mandatory<S32> enqueued,
+ dequeued,
+ resp_count;
+ Mandatory<F64> resp_min,
+ resp_max,
+ resp_mean;
+
+ AssetRequestType();
+ };
+
+ struct FPSStats : public LLInitParam::Block<FPSStats>
{
- for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
- {
- mRequests[i] = src.mRequests[i];
- }
- }
+ Mandatory<S32> count;
+ Mandatory<F64> min,
+ max,
+ mean;
+ FPSStats();
+ };
- // Default assignment and destructor are correct.
+ struct RegionStats : public LLInitParam::Block<RegionStats>
+ {
+ Optional<AssetRequestType> get_texture_temp_http,
+ get_texture_temp_udp,
+ get_texture_non_temp_http,
+ get_texture_non_temp_udp,
+ get_wearable_udp,
+ get_sound_udp,
+ get_gesture_udp,
+ get_other;
+ Optional<FPSStats> fps;
+ Optional<S32> grid_x,
+ grid_y;
+ Optional<F64> duration;
+
+ RegionStats();
+ };
- void reset();
-
- void merge(const PerRegionStats & src);
+ struct AssetStats : public LLInitParam::Block<AssetStats>
+ {
+ Multiple<RegionStats> regions;
+ Mandatory<F64> duration;
- // Apply current running time to total and reset start point.
- // Return current timestamp as a convenience.
- void accumulateTime(duration_t now);
+ Mandatory<LLUUID> session_id,
+ agent_id;
- public:
- region_handle_t mRegionHandle;
- duration_t mTotalTime;
- duration_t mStartTimestamp;
- LLSimpleStatMMM<> mFPS;
+ Mandatory<std::string> message;
+ Mandatory<S32> sequence;
+ Mandatory<bool> initial,
+ break_;
- struct prs_group
- {
- LLSimpleStatCounter mEnqueued;
- LLSimpleStatCounter mDequeued;
- LLSimpleStatMMM<duration_t> mResponse;
- }
- mRequests [EVACCount];
+ AssetStats();
};
public:
LLViewerAssetStats();
LLViewerAssetStats(const LLViewerAssetStats &);
+
// Default destructor is correct.
LLViewerAssetStats & operator=(const LLViewerAssetStats &); // Not defined
@@ -174,88 +163,32 @@ public:
// collection calls.
void setRegion(region_handle_t region_handle);
- // Asset GET Requests
- void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
- void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
- void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration);
-
- // Frames-Per-Second Samples
- void recordFPS(F32 fps);
-
- // Avatar-related statistics
- void recordAvatarStats();
-
- // Merge a source instance into a destination instance. This is
- // conceptually an 'operator+=()' method:
- // - counts are added
- // - minimums are min'd
- // - maximums are max'd
- // - other scalars are ignored ('this' wins)
- //
- void merge(const LLViewerAssetStats & src);
+ // gather latest metrics data
+ // call from main thread
+ void updateStats();
// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
- // Returned LLSD is structured as follows:
- //
- // &stats_group = {
- // enqueued : int,
- // dequeued : int,
- // resp_count : int,
- // resp_min : float,
- // resp_max : float,
- // resp_mean : float
- // }
- //
- // &mmm_group = {
- // count : int,
- // min : float,
- // max : float,
- // mean : float
- // }
- //
- // {
- // duration: int
- // regions: {
- // $: { // Keys are strings of the region's handle in hex
- // duration: : int,
- // fps: : &mmm_group,
- // get_texture_temp_http : &stats_group,
- // get_texture_temp_udp : &stats_group,
- // get_texture_non_temp_http : &stats_group,
- // get_texture_non_temp_udp : &stats_group,
- // get_wearable_udp : &stats_group,
- // get_sound_udp : &stats_group,
- // get_gesture_udp : &stats_group,
- // get_other : &stats_group
- // }
- // }
- // }
- //
- // @param compact_output If true, omits from conversion any mmm_block
- // or stats_block that would contain all zero data.
- // Useful for transmission when the receiver knows
- // what is expected and will assume zero for missing
- // blocks.
+ // Uses AssetStats structure seen above
+ void getStats(AssetStats& stats, bool compact_output);
LLSD asLLSD(bool compact_output);
protected:
- typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer;
+ void handleStart();
+ void handleStop();
+ void handleReset();
+
+ typedef std::map<region_handle_t, LLTrace::Recording > PerRegionRecordingContainer;
// Region of the currently-active region. Always valid but may
// be zero after construction or when explicitly set. Unchanged
// by a reset() call.
region_handle_t mRegionHandle;
- // Pointer to metrics collection for currently-active region. Always
- // valid and unchanged after reset() though contents will be changed.
- // Always points to a collection contained in mRegionStats.
- LLPointer<PerRegionStats> mCurRegionStats;
+ // Pointer to metrics collection for currently-active region.
+ LLTrace::Recording* mCurRecording;
// Metrics data for all regions during one collection cycle
- PerRegionContainer mRegionStats;
-
- // Time of last reset
- duration_t mResetTimestamp;
+ PerRegionRecordingContainer mRegionRecordings;
};
@@ -273,12 +206,24 @@ protected:
* - Main: main() program execution thread
* - Thread1: TextureFetch worker thread
*/
-extern LLViewerAssetStats * gViewerAssetStatsMain;
-
-extern LLViewerAssetStats * gViewerAssetStatsThread1;
+extern LLViewerAssetStats * gViewerAssetStats;
namespace LLViewerAssetStatsFF
{
+ enum EViewerAssetCategories
+ {
+ EVACTextureTempHTTPGet, //< Texture GETs - temp/baked, HTTP
+ EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP
+ EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP
+ EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP
+ EVACWearableUDPGet, //< Wearable GETs
+ EVACSoundUDPGet, //< Sound GETs
+ EVACGestureUDPGet, //< Gesture GETs
+ EVACOtherGet, //< Other GETs
+
+ EVACCount // Must be last
+ };
+
/**
* @brief Allocation and deallocation of globals.
*
@@ -303,28 +248,16 @@ inline LLViewerAssetStats::duration_t get_timestamp()
/**
* Region context, event and duration loggers for the Main thread.
*/
-void set_region_main(LLViewerAssetStats::region_handle_t region_handle);
+void set_region(LLViewerAssetStats::region_handle_t region_handle);
-void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
-void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
-void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp,
+void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp,
LLViewerAssetStats::duration_t duration);
-void record_fps_main(F32 fps);
-
-/**
- * Region context, event and duration loggers for Thread 1.
- */
-void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle);
-
-void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
-
-void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
-
-void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp,
- LLViewerAssetStats::duration_t duration);
+void record_avatar_stats();
} // namespace LLViewerAssetStatsFF
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index d042f62830..5c2dd20ec3 100755
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -69,12 +69,12 @@ public:
protected:
void recordMetrics()
{
- if (mMetricsStartTime)
+ if (mMetricsStartTime.value())
{
// Okay, it appears this request was used for useful things. Record
// the expected dequeue and duration of request processing.
- LLViewerAssetStatsFF::record_dequeue_main(mType, false, false);
- LLViewerAssetStatsFF::record_response_main(mType, false, false,
+ LLViewerAssetStatsFF::record_dequeue(mType, false, false);
+ LLViewerAssetStatsFF::record_response(mType, false, false,
(LLViewerAssetStatsFF::get_timestamp()
- mMetricsStartTime));
mMetricsStartTime = 0;
@@ -373,7 +373,7 @@ void LLViewerAssetStorage::_queueDataRequest(
LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
- LLViewerAssetStatsFF::record_enqueue_main(atype, false, false);
+ LLViewerAssetStatsFF::record_enqueue(atype, false, false);
}
}
else
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 3da934b148..c1518833bd 100755
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -37,6 +37,7 @@
#include "llviewerwindow.h"
#include "llvoiceclient.h"
#include "llviewermedia.h"
+#include "llviewerregion.h"
#include "llprogressview.h"
#include "llcallbacklist.h"
#include "llstartup.h"
@@ -400,7 +401,7 @@ void audio_update_volume(bool force_update)
gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
if(!LLViewerCamera::getInstance()->cameraUnderWater())
- gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+ gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
else
gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff"));
@@ -494,18 +495,18 @@ void audio_update_wind(bool force_update)
LLViewerRegion* region = gAgent.getRegion();
if (region)
{
- // Scale down the contribution of weather-simulation wind to the
- // ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s
- // whereas steady-state avatar walk velocity is only 3.2 m/s.
- // Without this the world feels desolate on first login when you are
- // standing still.
- static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
- LLVector3 scaled_wind_vec = gWindVec * wind_level;
-
- // Mix in the avatar's motion, subtract because when you walk north,
- // the apparent wind moves south.
- LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
-
+ // Scale down the contribution of weather-simulation wind to the
+ // ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s
+ // whereas steady-state avatar walk velocity is only 3.2 m/s.
+ // Without this the world feels desolate on first login when you are
+ // standing still.
+ static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
+ LLVector3 scaled_wind_vec = gWindVec * wind_level;
+
+ // Mix in the avatar's motion, subtract because when you walk north,
+ // the apparent wind moves south.
+ LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity();
+
// rotate the wind vector to be listener (agent) relative
gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec );
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index b5aa0ac92a..ebc4f09edb 100755
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -49,11 +49,15 @@
#include "llglheaders.h"
#include "llquaternion.h"
#include "llwindow.h" // getPixelAspectRatio()
+#include "lltracerecording.h"
// System includes
#include <iomanip> // for setprecision
-U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity");
+LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity");
+
+LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
//glu pick matrix implementation borrowed from Mesa3D
glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport)
@@ -160,11 +164,11 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
F32 drot;
rotation.getAngleAxis(&drot, &x, &y, &z);
- mVelocityStat.addValue(dpos);
- mAngularVelocityStat.addValue(drot);
+ add(sVelocityStat, dpos);
+ add(sAngularVelocityStat, drot);
- mAverageSpeed = mVelocityStat.getMeanPerSec() ;
- mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ;
+ mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50);
+ mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat);
mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));
// update pixel meter ratio using default fov, not modified one
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index b857c7fe89..7b2887d725 100755
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -29,10 +29,10 @@
#include "llcamera.h"
#include "llsingleton.h"
-#include "llstat.h"
#include "lltimer.h"
#include "m4math.h"
#include "llcoord.h"
+#include "lltrace.h"
class LLViewerObject;
@@ -80,7 +80,7 @@ public:
NUM_CAMERAS
} eCameraID;
- static U32 sCurCameraID;
+ static eCameraID sCurCameraID;
LLViewerCamera();
@@ -100,9 +100,9 @@ public:
BOOL projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp = TRUE) const;
BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const;
- const LLVector3* getVelocityDir() const {return &mVelocityDir;}
- LLStat *getVelocityStat() { return &mVelocityStat; }
- LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; }
+ LLVector3 getVelocityDir() const {return mVelocityDir;}
+ static LLTrace::CountStatHandle<>* getVelocityStat() {return &sVelocityStat; }
+ static LLTrace::CountStatHandle<>* getAngularVelocityStat() {return &sAngularVelocityStat; }
F32 getCosHalfFov() {return mCosHalfCameraFOV;}
F32 getAverageSpeed() {return mAverageSpeed ;}
F32 getAverageAngularSpeed() {return mAverageAngularSpeed;}
@@ -117,9 +117,9 @@ public:
F32 getDefaultFOV() { return mCameraFOVDefault; }
BOOL cameraUnderWater() const;
+ BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);
const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; }
- BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);
F32 getPixelMeterRatio() const { return mPixelMeterRatio; }
S32 getScreenPixelArea() const { return mScreenPixelArea; }
@@ -130,12 +130,12 @@ public:
protected:
void calcProjection(const F32 far_distance) const;
- LLStat mVelocityStat;
- LLStat mAngularVelocityStat;
+ static LLTrace::CountStatHandle<> sVelocityStat;
+ static LLTrace::CountStatHandle<> sAngularVelocityStat;
+
LLVector3 mVelocityDir ;
F32 mAverageSpeed ;
F32 mAverageAngularSpeed ;
-
mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix
mutable LLMatrix4 mModelviewMatrix;
F32 mCameraFOVDefault;
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index b07fe39e37..1de8493749 100755
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -77,6 +77,7 @@
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llpostprocess.h"
+#include "llscenemonitor.h"
extern LLPointer<LLViewerTexture> gStartTexture;
extern bool gShiftFrame;
@@ -84,9 +85,6 @@ extern bool gShiftFrame;
LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
// used to toggle renderer back on after teleport
-const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain
-const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
-const F32 TELEPORT_LOCAL_DELAY = 1.0f; // Delay to prevent teleports after starting an in-sim teleport.
BOOL gTeleportDisplay = FALSE;
LLFrameTimer gTeleportDisplayTimer;
LLFrameTimer gTeleportArrivalTimer;
@@ -133,7 +131,7 @@ void display_startup()
//
if (!LLViewerFetchedTexture::sWhiteImagep.isNull())
{
- LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
+ LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
}
LLGLSDefault gls_default;
@@ -225,7 +223,7 @@ void display_stats()
}
static LLFastTimer::DeclareTimer FTM_PICK("Picking");
-static LLFastTimer::DeclareTimer FTM_RENDER("Render", true);
+static LLFastTimer::DeclareTimer FTM_RENDER("Render");
static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
@@ -391,7 +389,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLFastTimer t(FTM_TELEPORT_DISPLAY);
LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
- const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
+ static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay");
+ static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");
S32 attach_count = 0;
if (isAgentAvatarValid())
@@ -459,7 +458,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
case LLAgent::TELEPORT_ARRIVING:
// Make the user wait while content "pre-caches"
{
- F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
+ F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());
if( arrival_fraction > 1.f )
{
arrival_fraction = 1.f;
@@ -476,7 +475,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// Short delay when teleporting in the same sim (progress screen active but not shown - did not
// fall-through from TELEPORT_START)
{
- if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY )
+ if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() )
{
//LLFirstUse::useTeleport();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
@@ -626,7 +625,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);
- const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
+ const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time
gPipeline.createObjects(max_geom_update_time);
gPipeline.processPartitionQ();
gPipeline.updateGeom(max_geom_update_time);
@@ -767,8 +766,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLFastTimer t(FTM_IMAGE_UPDATE_CLASS);
- LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
- LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
+ 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));
}
@@ -779,7 +780,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLFastTimer t(FTM_IMAGE_UPDATE_LIST);
- F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
+ F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time
max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
gTextureList.updateImages(max_image_decode_time);
}
@@ -821,6 +822,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
+ LLSceneMonitor::getInstance()->fetchQueryResult();
+
LLGLState::checkStates();
LLGLState::checkClientArrays();
@@ -1008,6 +1011,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLPipeline::sUnderWaterRender = FALSE;
+ {
+ //capture the frame buffer.
+ LLSceneMonitor::getInstance()->capture();
+ }
+
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
if (!for_snapshot)
{
@@ -1058,7 +1066,7 @@ void render_hud_attachments()
// clamp target zoom level to reasonable values
gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
// smoothly interpolate current zoom level
- gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f));
+ gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLSmoothInterpolation::getInterpolant(0.03f));
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
@@ -1251,6 +1259,15 @@ void render_ui(F32 zoom_factor, int subfield)
glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));
}
+ if(LLSceneMonitor::getInstance()->needsUpdate())
+ {
+ gGL.pushMatrix();
+ gViewerWindow->setup2DRender();
+ LLSceneMonitor::getInstance()->compare();
+ gViewerWindow->setup3DRender();
+ gGL.popMatrix();
+ }
+
{
BOOL to_texture = gPipeline.canUseVertexShaders() &&
LLPipeline::sRenderGlow;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c6b28b9e5e..39f8249300 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -28,66 +28,65 @@
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
-
#include "llviewerfloaterreg.h"
-#include "llfloaterautoreplacesettings.h"
+
+#include "llcommandhandler.h"
#include "llcompilequeue.h"
#include "llfasttimerview.h"
#include "llfloaterabout.h"
#include "llfloaterauction.h"
+#include "llfloaterautoreplacesettings.h"
#include "llfloateravatar.h"
#include "llfloateravatarpicker.h"
#include "llfloateravatartextures.h"
#include "llfloaterbeacons.h"
#include "llfloaterbuildoptions.h"
+#include "llfloaterbulkpermission.h"
+#include "llfloaterbump.h"
#include "llfloaterbuy.h"
#include "llfloaterbuycontents.h"
#include "llfloaterbuycurrency.h"
#include "llfloaterbuycurrencyhtml.h"
#include "llfloaterbuyland.h"
-#include "llfloaterbulkpermission.h"
-#include "llfloaterbump.h"
#include "llfloaterbvhpreview.h"
#include "llfloatercamera.h"
#include "llfloaterchatvoicevolume.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloaterdeleteenvpreset.h"
+#include "llfloaterdestinations.h"
#include "llfloaterdisplayname.h"
#include "llfloatereditdaycycle.h"
#include "llfloatereditsky.h"
#include "llfloatereditwater.h"
#include "llfloaterenvironmentsettings.h"
#include "llfloaterevent.h"
-#include "llfloaterdestinations.h"
#include "llfloaterfonttest.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergroups.h"
#include "llfloaterhardwaresettings.h"
#include "llfloaterhelpbrowser.h"
-#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
-#include "llfloatermediasettings.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
#include "llfloaterimsession.h"
#include "llfloaterinspect.h"
#include "llfloaterinventory.h"
#include "llfloaterjoystick.h"
-#include "llfloaterlagmeter.h"
#include "llfloaterland.h"
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
+#include "llfloatermediasettings.h"
#include "llfloatermemleak.h"
+#include "llfloatermodelpreview.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaterobjectweights.h"
#include "llfloateropenobject.h"
#include "llfloateroutbox.h"
#include "llfloaterpathfindingcharacters.h"
-#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpathfindingconsole.h"
+#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpay.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -96,6 +95,7 @@
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
#include "llfloaterreporter.h"
+#include "llfloatersceneloadstats.h"
#include "llfloaterscriptdebug.h"
#include "llfloaterscriptlimits.h"
#include "llfloatersearch.h"
@@ -110,12 +110,14 @@
#include "llfloatertestlistview.h"
#include "llfloatertexturefetchdebugger.h"
#include "llfloatertools.h"
-#include "llfloatertos.h"
#include "llfloatertopobjects.h"
+#include "llfloatertos.h"
#include "llfloatertoybox.h"
#include "llfloatertranslationsettings.h"
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
+#include "llfloaterwebcontent.h"
+#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@@ -136,10 +138,8 @@
#include "llpreviewscript.h"
#include "llpreviewsound.h"
#include "llpreviewtexture.h"
-#include "llsyswellwindow.h"
#include "llscriptfloater.h"
-#include "llfloatermodelpreview.h"
-#include "llcommandhandler.h"
+#include "llsyswellwindow.h"
// *NOTE: Please add files in alphabetical order to keep merges easy.
@@ -231,7 +231,6 @@ void LLViewerFloaterReg::registerFloaters()
LLNotificationsUI::registerFloater();
LLFloaterDisplayNameUtil::registerFloater();
- LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
@@ -305,6 +304,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
+ LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index f6e840adcd..f4155df4d1 100755
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -501,7 +501,7 @@ void LLViewerJoystick::moveObjects(bool reset)
};
F32 cur_delta[6];
- F32 time = gFrameIntervalSeconds;
+ F32 time = gFrameIntervalSeconds.value();
// avoid making ridicously big movements if there's a big drop in fps
if (time > .2f)
@@ -665,7 +665,7 @@ void LLViewerJoystick::moveAvatar(bool reset)
};
// time interval in seconds between this frame and the previous
- F32 time = gFrameIntervalSeconds;
+ F32 time = gFrameIntervalSeconds.value();
// avoid making ridicously big movements if there's a big drop in fps
if (time > .2f)
@@ -878,7 +878,7 @@ void LLViewerJoystick::moveFlycam(bool reset)
gSavedSettings.getF32("FlycamAxisDeadZone6")
};
- F32 time = gFrameIntervalSeconds;
+ F32 time = gFrameIntervalSeconds.value();
// avoid making ridiculously big movements if there's a big drop in fps
if (time > .2f)
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 4ecdc31e21..49ac2735ca 100755
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -161,6 +161,11 @@ void agent_push_backward( EKeystate s )
camera_move_backward(s);
return;
}
+ else if (gAgentAvatarp->isSitting())
+ {
+ gAgentCamera.changeCameraToThirdPerson();
+ return;
+ }
agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5e2f05f468..fb199ba879 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7401,7 +7401,7 @@ void handle_dump_avatar_local_textures(void*)
void handle_dump_timers()
{
- LLFastTimer::dumpCurTimes();
+ LLTrace::TimeBlock::dumpCurTimes();
}
void handle_debug_avatar_textures(void*)
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index be78603e2d..b7282a8493 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -1096,17 +1096,17 @@ void upload_new_resource(
if( LLAssetType::AT_SOUND == asset_type )
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+ add(LLStatViewer::UPLOAD_SOUND, 1);
}
else
if( LLAssetType::AT_TEXTURE == asset_type )
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+ add(LLStatViewer::UPLOAD_TEXTURE, 1);
}
else
if( LLAssetType::AT_ANIMATION == asset_type)
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+ add(LLStatViewer::ANIMATION_UPLOADS, 1);
}
if(LLInventoryType::IT_NONE == inv_type)
@@ -1231,18 +1231,15 @@ void increase_new_upload_stats(LLAssetType::EType asset_type)
{
if ( LLAssetType::AT_SOUND == asset_type )
{
- LLViewerStats::getInstance()->incStat(
- LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+ add(LLStatViewer::UPLOAD_SOUND, 1);
}
else if ( LLAssetType::AT_TEXTURE == asset_type )
{
- LLViewerStats::getInstance()->incStat(
- LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+ add(LLStatViewer::UPLOAD_TEXTURE, 1);
}
else if ( LLAssetType::AT_ANIMATION == asset_type )
{
- LLViewerStats::getInstance()->incStat(
- LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+ add(LLStatViewer::ANIMATION_UPLOADS, 1);
}
}
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 3136358b83..3034d00b22 100755
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -31,6 +31,8 @@
#include "llassetstorage.h"
#include "llinventorytype.h"
#include "llfilepicker.h"
+#include "llthread.h"
+#include <queue>
class LLTransactionID;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ace16396db..c33efd4255 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2628,7 +2628,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LLSD args;
args["SUBJECT"] = subj;
args["MESSAGE"] = mes;
- LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
+ LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(LLDate(timestamp)));
}
// Also send down the old path for now.
@@ -4129,7 +4129,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
LLTracker::stopTracking(NULL);
}
- else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() )
+ else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero())
{
//look at the beacon
LLVector3 global_agent_pos = agent_pos;
@@ -4480,18 +4480,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// *TODO: Remove this dependency, or figure out a better way to handle
// this hack.
-extern U32 gObjectBits;
+extern LLUnit<U32, LLUnits::Bits> gObjectData;
void process_object_update(LLMessageSystem *mesgsys, void **user_data)
{
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
- gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveCompressedSize();
}
else
{
- gObjectBits += mesgsys->getReceiveSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveSize();
}
// Update the object...
@@ -4503,11 +4503,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
- gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveCompressedSize();
}
else
{
- gObjectBits += mesgsys->getReceiveSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveSize();
}
// Update the object...
@@ -4519,11 +4519,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
// Update the data counters
if (mesgsys->getReceiveCompressedSize())
{
- gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveCompressedSize();
}
else
{
- gObjectBits += mesgsys->getReceiveSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveSize();
}
// Update the object...
@@ -4535,11 +4535,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
{
if (mesgsys->getReceiveCompressedSize())
{
- gObjectBits += mesgsys->getReceiveCompressedSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveCompressedSize();
}
else
{
- gObjectBits += mesgsys->getReceiveSize() * 8;
+ gObjectData += (LLUnit<U32, LLUnits::Bytes>)mesgsys->getReceiveSize();
}
gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
@@ -4547,30 +4547,42 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects");
+const U32 KILLOBJECT_DELETE_OPCODE = 0;
+
void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
{
LLFastTimer t(FTM_PROCESS_OBJECTS);
LLUUID id;
- U32 local_id;
- S32 i;
- S32 num_objects;
- num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
+ U32 ip = mesgsys->getSenderIP();
+ U32 port = mesgsys->getSenderPort();
+ LLViewerRegion* regionp = NULL;
+ {
+ LLHost host(ip, port);
+ regionp = LLWorld::getInstance()->getRegion(host);
+ }
- for (i = 0; i < num_objects; i++)
+ bool delete_object = false;
+ S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
+ for (S32 i = 0; i < num_objects; ++i)
{
+ U32 local_id;
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
+ if (local_id == KILLOBJECT_DELETE_OPCODE)
+ {
+ // This local_id is invalid, but was sent by the server to flag
+ // all subsequent local_id's as objects that were actually deleted
+ // rather than unsubscribed from interestlist.
+ delete_object = true;
+ continue;
+ }
- LLViewerObjectList::getUUIDFromLocal(id,
- local_id,
- gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
+ LLViewerObjectList::getUUIDFromLocal(id, local_id, ip, port);
if (id == LLUUID::null)
{
LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
- gObjectList.mNumUnknownKills++;
continue;
}
else
@@ -4578,9 +4590,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
}
- // ...don't kill the avatar
- if (!(id == gAgentID))
+ if (id == gAgentID)
{
+ // never kill our avatar
+ continue;
+ }
+
LLViewerObject *objectp = gObjectList.findObject(id);
if (objectp)
{
@@ -4594,18 +4609,16 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
// Do the kill
gObjectList.killObject(objectp);
}
- else
+
+ if(delete_object)
{
- LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
- gObjectList.mNumUnknownKills++;
- }
+ regionp->killCacheEntry(local_id);
}
// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
// which is using the object, release the mouse capture correctly when the object dies.
// See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
}
}
@@ -4817,145 +4830,18 @@ 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);
- switch (stat_id)
+ LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id);
+
+ if (measurementp )
{
- case LL_SIM_STAT_TIME_DILATION:
- LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
- break;
- case LL_SIM_STAT_FPS:
- LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_PHYSFPS:
- LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_AGENTUPS:
- LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_FRAMEMS:
- LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_NETMS:
- LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMOTHERMS:
- LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMPHYSICSMS:
- LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_AGENTMS:
- LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_IMAGESMS:
- LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SCRIPTMS:
- LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_NUMTASKS:
- LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
- break;
- case LL_SIM_STAT_NUMTASKSACTIVE:
- LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
- break;
- case LL_SIM_STAT_NUMAGENTMAIN:
- LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
- break;
- case LL_SIM_STAT_NUMAGENTCHILD:
- LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
- break;
- case LL_SIM_STAT_NUMSCRIPTSACTIVE:
- LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
- break;
- case LL_SIM_STAT_SCRIPT_EPS:
- LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_INPPS:
- LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_OUTPPS:
- LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
- break;
- case LL_SIM_STAT_PENDING_DOWNLOADS:
- LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
- break;
- case LL_SIM_STAT_PENDING_UPLOADS:
- LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
- break;
- case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
- LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
- break;
- case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
- LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
- break;
- case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
- LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
- break;
- case LL_SIM_STAT_PHYSICS_LOD_TASKS:
- LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMPHYSICSSTEPMS:
- LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
- LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMPHYSICSOTHERMS:
- LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMPHYSICSMEMORY:
- LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMSPARETIME:
- LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMSLEEPTIME:
- LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_IOPUMPTIME:
- LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_PCTSCRIPTSRUN:
- LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value);
- break;
- case LL_SIM_STAT_SIMAISTEPTIMEMS:
- LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value);
- break;
- case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS:
- LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value);
- break;
- case LL_SIM_STAT_PCTSTEPPEDCHARACTERS:
- LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value);
- break;
- default:
- // Used to be a commented out warning.
- LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
- break;
+ measurementp->sample(stat_value);
+ }
+ else
+ {
+ llwarns << "Unknown sim stat identifier: " << stat_id << llendl;
}
}
- /*
- msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation);
- LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation);
-
- // Process information
- // { CpuUsage F32 }
- // { SimMemTotal F32 }
- // { SimMemRSS F32 }
- // { ProcessUptime F32 }
- F32 cpu_usage;
- F32 sim_mem_total;
- F32 sim_mem_rss;
- F32 process_uptime;
- msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage);
- msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total);
- msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss);
- msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime);
- LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage);
- LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total);
- LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss);
- */
-
//
// Various hacks that aren't statistics, but are being handled here.
//
@@ -6010,7 +5896,7 @@ void process_alert_core(const std::string& message, BOOL modal)
// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
if ( message == "You died and have been teleported to your home location")
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
+ add(LLStatViewer::KILLED, 1);
}
else if( message == "Home position set." )
{
@@ -7471,8 +7357,6 @@ void onCovenantLoadComplete(LLVFS *vfs,
}
else
{
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
-
if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
LL_ERR_FILE_EMPTY == status)
{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 6f7b2f40e6..6362ccfba6 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -39,6 +39,7 @@
#include "llfloaterreg.h"
#include "llfontgl.h"
#include "llframetimer.h"
+#include "llhudicon.h"
#include "llinventory.h"
#include "llinventorydefines.h"
#include "llmaterialtable.h"
@@ -100,6 +101,7 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
+#include "llvocache.h"
//#define DEBUG_UPDATE_TYPE
@@ -112,6 +114,9 @@ BOOL LLViewerObject::sMapDebug = TRUE;
LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK
LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit
S32 LLViewerObject::sAxisArrowLength(50);
+LLTrace::MemStatHandle LLViewerObject::sMemStat("LLViewerObject");
+
+
BOOL LLViewerObject::sPulseEnabled(FALSE);
BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
@@ -119,6 +124,7 @@ BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
F64 LLViewerObject::sMaxUpdateInterpolationTime = 3.0; // For motion interpolation: after X seconds with no updates, don't predict object motion
F64 LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0; // For motion interpolation: after Y seconds with no updates, taper off motion prediction
+std::map<std::string, U32> LLViewerObject::sObjectDataMap;
static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
@@ -351,6 +357,10 @@ void LLViewerObject::markDead()
// Mark itself as dead
mDead = TRUE;
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
gObjectList.cleanupReferences(this);
LLViewerObject *childp;
@@ -495,6 +505,8 @@ void LLViewerObject::initVOClasses()
LLVOGrass::initClass();
LLVOWater::initClass();
LLVOVolume::initClass();
+
+ initObjectDataMap();
}
void LLViewerObject::cleanupVOClasses()
@@ -504,6 +516,118 @@ void LLViewerObject::cleanupVOClasses()
LLVOTree::cleanupClass();
LLVOAvatar::cleanupClass();
LLVOVolume::cleanupClass();
+
+ sObjectDataMap.clear();
+}
+
+//object data map for compressed && !OUT_TERSE_IMPROVED
+//static
+void LLViewerObject::initObjectDataMap()
+{
+ U32 count = 0;
+
+ sObjectDataMap["ID"] = count; //full id //LLUUID
+ count += sizeof(LLUUID);
+
+ sObjectDataMap["LocalID"] = count; //U32
+ count += sizeof(U32);
+
+ sObjectDataMap["PCode"] = count; //U8
+ count += sizeof(U8);
+
+ sObjectDataMap["State"] = count; //U8
+ count += sizeof(U8);
+
+ sObjectDataMap["CRC"] = count; //U32
+ count += sizeof(U32);
+
+ sObjectDataMap["Material"] = count; //U8
+ count += sizeof(U8);
+
+ sObjectDataMap["ClickAction"] = count; //U8
+ count += sizeof(U8);
+
+ sObjectDataMap["Scale"] = count; //LLVector3
+ count += sizeof(LLVector3);
+
+ sObjectDataMap["Pos"] = count; //LLVector3
+ count += sizeof(LLVector3);
+
+ sObjectDataMap["Rot"] = count; //LLVector3
+ count += sizeof(LLVector3);
+
+ sObjectDataMap["SpecialCode"] = count; //U32
+ count += sizeof(U32);
+
+ sObjectDataMap["Owner"] = count; //LLUUID
+ count += sizeof(LLUUID);
+
+ sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set
+ count += sizeof(LLVector3);
+
+ //ParentID is after Omega if there is Omega, otherwise is after Owner
+ sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set
+ count += sizeof(U32);
+
+ //-------
+ //The rest items are not included here
+ //-------
+}
+
+//static
+void LLViewerObject::unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name)
+{
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackVector3(value, name.c_str());
+ dp->reset();
+}
+
+//static
+void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name)
+{
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackUUID(value, name.c_str());
+ dp->reset();
+}
+
+//static
+void LLViewerObject::unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name)
+{
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackU32(value, name.c_str());
+ dp->reset();
+}
+
+//static
+void LLViewerObject::unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name)
+{
+ dp->shift(sObjectDataMap[name]);
+ dp->unpackU8(value, name.c_str());
+ dp->reset();
+}
+
+//static
+U32 LLViewerObject::unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id)
+{
+ dp->shift(sObjectDataMap["SpecialCode"]);
+ U32 value;
+ dp->unpackU32(value, "SpecialCode");
+
+ parent_id = 0;
+ if(value & 0x20)
+ {
+ S32 offset = sObjectDataMap["ParentID"];
+ if(!(value & 0x80))
+ {
+ offset -= sizeof(LLVector3);
+ }
+
+ dp->shift(offset);
+ dp->unpackU32(parent_id, "ParentID");
+ }
+ dp->reset();
+
+ return parent_id;
}
// Replaces all name value pairs with data from \n delimited list
@@ -895,6 +1019,29 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url)
return retval;
}
+//extract spatial information from object update message
+//return parent_id
+//static
+U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot)
+{
+ U32 parent_id = 0;
+ LLViewerObject::unpackParentID(dp, parent_id);
+ if(parent_id > 0)
+ {
+ //is a child, no need to decode further.
+ return parent_id;
+ }
+
+ LLViewerObject::unpackVector3(dp, scale, "Scale");
+ LLViewerObject::unpackVector3(dp, pos, "Pos");
+
+ LLVector3 vec;
+ LLViewerObject::unpackVector3(dp, vec, "Rot");
+ rot.unpackFromVector3(vec);
+
+ return parent_id;
+}
+
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
@@ -911,10 +1058,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Coordinates of objects on simulators are region-local.
- U64 region_handle;
- mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+ U64 region_handle = 0;
+ if(mesgsys != NULL)
{
+ mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
if(regionp != mRegionp && regionp && mRegionp)//region cross
{
@@ -927,6 +1075,17 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
else
{
+ if(regionp != mRegionp)
+ {
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
+ if(regionp)
+ {
+ regionp->addToCreatedList(getLocalID());
+ }
+ }
mRegionp = regionp ;
}
}
@@ -940,11 +1099,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
return retval;
}
+ if(mesgsys != NULL)
+ {
U16 time_dilation16;
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
F32 time_dilation = ((F32) time_dilation16) / 65535.f;
mTimeDilation = time_dilation;
mRegionp->setTimeDilation(time_dilation);
+ }
// this will be used to determine if we've really changed position
// Use getPosition, not getPositionRegion, since this is what we're comparing directly against.
@@ -1717,13 +1879,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// Preload these five flags for every object.
// Finer shades require the object to be selected, and the selection manager
// stores the extended permission info.
+ if(mesgsys != NULL)
+ {
U32 flags;
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num);
- // keep local flags and overwrite remote-controlled flags
- mFlags = (mFlags & FLAGS_LOCAL) | flags;
-
- // ...new objects that should come in selected need to be added to the selected list
- mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+ loadFlags(flags);
+ }
}
break;
@@ -1751,10 +1912,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
// No parent now, new parent in message -> attach to that parent if possible
LLUUID parent_uuid;
+
+ if(mesgsys != NULL)
+ {
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
parent_id,
mesgsys->getSenderIP(),
mesgsys->getSenderPort());
+ }
+ else
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ mRegionp->getHost().getAddress(),
+ mRegionp->getHost().getPort());
+ }
LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid);
@@ -1830,9 +2002,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
//
//parent_id
- U32 ip = mesgsys->getSenderIP();
- U32 port = mesgsys->getSenderPort();
+ U32 ip, port;
+ if(mesgsys != NULL)
+ {
+ ip = mesgsys->getSenderIP();
+ port = mesgsys->getSenderPort();
+ }
+ else
+ {
+ ip = mRegionp->getHost().getAddress();
+ port = mRegionp->getHost().getPort();
+ }
gObjectList.orphanize(this, parent_id, ip, port);
// Hide particles, icon and HUD
@@ -1870,10 +2051,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
else
{
LLUUID parent_uuid;
+
+ if(mesgsys != NULL)
+ {
LLViewerObjectList::getUUIDFromLocal(parent_uuid,
parent_id,
gMessageSystem->getSenderIP(),
gMessageSystem->getSenderPort());
+ }
+ else
+ {
+ LLViewerObjectList::getUUIDFromLocal(parent_uuid,
+ parent_id,
+ mRegionp->getHost().getAddress(),
+ mRegionp->getHost().getPort());
+ }
sent_parentp = gObjectList.findObject(parent_uuid);
if (isAvatar())
@@ -1894,8 +2086,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
//
// Switching parents, but we don't know the new parent.
//
- U32 ip = mesgsys->getSenderIP();
- U32 port = mesgsys->getSenderPort();
+ U32 ip, port;
+
+ if(mesgsys != NULL)
+ {
+ ip = mesgsys->getSenderIP();
+ port = mesgsys->getSenderPort();
+ }
+ else
+ {
+ ip = mRegionp->getHost().getAddress();
+ port = mRegionp->getHost().getPort();
+ }
// We're an orphan, flag things appropriately.
gObjectList.orphanize(this, parent_id, ip, port);
@@ -1979,7 +2181,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.normQuat();
- if (sPingInterpolate)
+ if (sPingInterpolate && mesgsys != NULL)
{
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
if (cdp)
@@ -2002,6 +2204,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// If we're going to skip this message, why are we
// doing all the parenting, etc above?
+ if(mesgsys != NULL)
+ {
U32 packet_id = mesgsys->getCurrentRecvPacketID();
if (packet_id < mLatestRecvPacketID &&
mLatestRecvPacketID - packet_id < 65536)
@@ -2009,8 +2213,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
//skip application of this message, it's old
return retval;
}
-
mLatestRecvPacketID = packet_id;
+ }
// Set the change flags for scale
if (new_scale != getScale())
@@ -2058,7 +2262,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
{
- LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
+ record(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length()));
}
}
@@ -2181,7 +2385,21 @@ BOOL LLViewerObject::isActive() const
return TRUE;
}
+//load flags from cache or from message
+void LLViewerObject::loadFlags(U32 flags)
+{
+ if(flags == (U32)(-1))
+ {
+ return; //invalid
+ }
+
+ // keep local flags and overwrite remote-controlled flags
+ mFlags = (mFlags & FLAGS_LOCAL) | flags;
+ // ...new objects that should come in selected need to be added to the selected list
+ mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
+ return;
+}
void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
@@ -4061,7 +4279,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
{
LLPrimitive::setTE(te, texture_entry);
- const LLUUID& image_id = getTE(te)->getID();
+ const LLUUID& image_id = getTE(te)->getID();
mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (getTE(te)->getMaterialParams().notNull())
@@ -5485,6 +5703,17 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)
{
llwarns << "viewer object set region to NULL" << llendl;
}
+ if(regionp != mRegionp)
+ {
+ if(mRegionp)
+ {
+ mRegionp->removeFromCreatedList(getLocalID());
+ }
+ if(regionp)
+ {
+ regionp->addToCreatedList(getLocalID());
+ }
+ }
mLatestRecvPacketID = 0;
mRegionp = regionp;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index ea0d55cda5..5556a4c7d3 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -30,8 +30,7 @@
#include <map>
#include "llassetstorage.h"
-#include "lldarrayptr.h"
-#include "llhudicon.h"
+//#include "llhudicon.h"
#include "llinventory.h"
#include "llrefcount.h"
#include "llprimitive.h"
@@ -43,33 +42,30 @@
#include "v3math.h"
#include "llvertexbuffer.h"
#include "llbbox.h"
-#include "llbbox.h"
class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
class LLAudioSourceVO;
-class LLDataPacker;
class LLColor4;
-class LLFrameTimer;
+class LLDataPacker;
+class LLDataPackerBinaryBuffer;
class LLDrawable;
-class LLHost;
class LLHUDText;
-class LLWorld;
-class LLNameValue;
-class LLNetMap;
+class LLHost;
class LLMessageSystem;
+class LLNameValue;
class LLPartSysData;
-class LLPrimitive;
class LLPipeline;
class LLTextureEntry;
-class LLViewerTexture;
+class LLVOAvatar;
+class LLVOInventoryListener;
class LLViewerInventoryItem;
class LLViewerObject;
+class LLViewerObjectMedia;
class LLViewerPartSourceScript;
class LLViewerRegion;
-class LLViewerObjectMedia;
-class LLVOInventoryListener;
-class LLVOAvatar;
+class LLViewerTexture;
+class LLWorld;
typedef enum e_object_update_type
{
@@ -107,7 +103,11 @@ struct PotentialReturnableObject
//============================================================================
-class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
+class LLViewerObject
+: public LLPrimitive,
+ public LLRefCount,
+ public LLGLUpdate,
+ public LLTrace::MemTrackable<LLViewerObject>
{
protected:
~LLViewerObject(); // use unref()
@@ -157,6 +157,7 @@ public:
INVALID_UPDATE = 0x80000000
};
+ static U32 extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot);
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
@@ -303,7 +304,7 @@ public:
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
- S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ S32 setTETextureCore(const U8 te, LLViewerTexture *image);
S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
@@ -521,6 +522,7 @@ public:
virtual void updateRegion(LLViewerRegion *regionp);
void updateFlags(BOOL physics_changed = FALSE);
+ void loadFlags(U32 flags); //load flags from cache or from message
BOOL setFlags(U32 flag, BOOL state);
BOOL setFlagsWithoutUpdate(U32 flag, BOOL state);
void setPhysicsShapeType(U8 type);
@@ -551,6 +553,13 @@ public:
friend class LLViewerMediaList;
public:
+ static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name);
+ static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name);
+ static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name);
+ static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name);
+ static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id);
+
+public:
//counter-translation
void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ;
//counter-rotation
@@ -573,6 +582,8 @@ private:
// Motion prediction between updates
void interpolateLinearMotion(const F64 & time, const F32 & dt);
+ static void initObjectDataMap();
+
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@@ -623,6 +634,7 @@ private:
// Grabbed from UPDATE_FLAGS
U32 mFlags;
+ static std::map<std::string, U32> sObjectDataMap;
public:
// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
U8 mPhysicsShapeType;
@@ -646,9 +658,10 @@ public:
// TODO: Make all this stuff private. JC
LLPointer<LLHUDText> mText;
- LLPointer<LLHUDIcon> mIcon;
+ LLPointer<class LLHUDIcon> mIcon;
static BOOL sUseSharedDrawables;
+ static LLTrace::MemStatHandle sMemStat;
protected:
// delete an item in the inventory, but don't tell the
@@ -684,8 +697,6 @@ protected:
void deleteParticleSource();
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
-public:
-
private:
void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
void deleteTEImages(); // correctly deletes list of images
@@ -764,6 +775,7 @@ protected:
static S32 sAxisArrowLength;
+
// These two caches are only correct for non-parented objects right now!
mutable LLVector3 mPositionRegion;
mutable LLVector3 mPositionAgent;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index caacf26cb3..b215869a3e 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -47,6 +47,7 @@
#include "lltooltip.h"
#include "llworld.h"
#include "llstring.h"
+#include "llhudicon.h"
#include "llhudnametag.h"
#include "lldrawable.h"
#include "llflexibleobject.h"
@@ -76,6 +77,7 @@
#include "object_flags.h"
#include "llappviewer.h"
+#include "llvocache.h"
extern F32 gMinObjectDistance;
extern BOOL gAnimateTextures;
@@ -93,7 +95,7 @@ extern LLPipeline gPipeline;
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
-LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128);
+LLTrace::SampleStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits");
LLViewerObjectList::LLViewerObjectList()
{
@@ -106,7 +108,6 @@ LLViewerObjectList::LLViewerObjectList()
mNumNewObjects = 0;
mWasPaused = FALSE;
mNumDeadObjectUpdates = 0;
- mNumUnknownKills = 0;
mNumUnknownUpdates = 0;
}
@@ -228,9 +229,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
U32 i,
const EObjectUpdateType update_type,
LLDataPacker* dpp,
- BOOL just_created)
+ bool just_created,
+ bool from_cache)
{
- LLMessageSystem* msg = gMessageSystem;
+ LLMessageSystem* msg = NULL;
+
+ if(!from_cache)
+ {
+ msg = gMessageSystem;
+ }
// ignore returned flags
objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
@@ -254,7 +261,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
// RN: this must be called after we have a drawable
// (from gPipeline.addObject)
// so that the drawable parent is set properly
+ if(msg != NULL)
+ {
findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort());
+ }
+ else
+ {
+ LLViewerRegion* regionp = objectp->getRegion();
+ if(regionp != NULL)
+ {
+ findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort());
+ }
+ }
// If we're just wandering around, don't create new objects selected.
if (just_created
@@ -277,10 +295,90 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects");
+LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp)
+{
+ LLDataPacker *cached_dpp = entry->getDP();
+
+ if (!cached_dpp)
+ {
+ return NULL; //nothing cached.
+ }
+
+ LLViewerObject *objectp;
+ U32 local_id;
+ LLPCode pcode = 0;
+ LLUUID fullid;
+ LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
+
+ // Cache Hit.
+ cached_dpp->reset();
+ cached_dpp->unpackUUID(fullid, "ID");
+ cached_dpp->unpackU32(local_id, "LocalID");
+ cached_dpp->unpackU8(pcode, "PCode");
+
+ objectp = findObject(fullid);
+
+ if (objectp)
+ {
+ if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() ||
+ objectp->getRegion() != regionp))
+ {
+ removeFromLocalIDTable(objectp);
+ setUUIDAndLocal(fullid, entry->getLocalID(),
+ regionp->getHost().getAddress(),
+ regionp->getHost().getPort());
+
+ if (objectp->mLocalID != entry->getLocalID())
+ { // Update local ID in object with the one sent from the region
+ objectp->mLocalID = entry->getLocalID();
+ }
+
+ if (objectp->getRegion() != regionp)
+ { // Object changed region, so update it
+ objectp->updateRegion(regionp); // for LLVOAvatar
+ }
+ }
+ else
+ {
+ //should fall through if already loaded because may need to update the object.
+ //return objectp; //already loaded.
+ }
+ }
+
+ bool justCreated = false;
+ if (!objectp)
+ {
+ objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID());
+
+ if (!objectp)
+ {
+ llinfos << "createObject failure for object: " << fullid << llendl;
+ recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0);
+ return NULL;
+ }
+ justCreated = true;
+ mNumNewObjects++;
+ sample(sCacheHitRate, 100.f);
+ }
+
+ if (objectp->isDead())
+ {
+ llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;
+ }
+
+ processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true);
+ objectp->loadFlags(entry->getUpdateFlags()); //just in case, reload update flags from cache.
+
+ recorder.log(0.2f);
+ LLVOAvatar::cullAvatarsByPixelArea();
+
+ return objectp;
+}
+
void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
void **user_data,
const EObjectUpdateType update_type,
- bool cached, bool compressed)
+ bool compressed)
{
LLFastTimer t(FTM_PROCESS_OBJECTS);
@@ -298,7 +396,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
// I don't think this case is ever hit. TODO* Test this.
- if (!cached && !compressed && update_type != OUT_FULL)
+ if (!compressed && update_type != OUT_FULL)
{
//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
gTerseObjectUpdates += num_objects;
@@ -346,7 +444,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
U8 compressed_dpbuffer[2048];
LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
- LLDataPacker *cached_dpp = NULL;
LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
for (i = 0; i < num_objects; i++)
@@ -355,57 +452,37 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
LLTimer update_timer;
BOOL justCreated = FALSE;
S32 msg_size = 0;
+ bool remove_from_cache = false; //remove from object cache if it is a full-update or terse update
- if (cached)
- {
- U32 id;
- U32 crc;
- mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
- mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
- msg_size += sizeof(U32) * 2;
-
- // Lookup data packer and add this id to cache miss lists if necessary.
- U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
- cached_dpp = regionp->getDP(id, crc, cache_miss_type);
- if (cached_dpp)
- {
- // Cache Hit.
- cached_dpp->reset();
- cached_dpp->unpackUUID(fullid, "ID");
- cached_dpp->unpackU32(local_id, "LocalID");
- cached_dpp->unpackU8(pcode, "PCode");
- }
- else
- {
- // Cache Miss.
- recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
-
- continue; // no data packer, skip this object
- }
- }
- else if (compressed)
+ if (compressed)
{
S32 uncompressed_length = 2048;
compressed_dp.reset();
- U32 flags = 0;
- if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
- {
- mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
- }
-
uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
{
+ U32 flags = 0;
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
+
+ if(flags & FLAGS_TEMPORARY_ON_REZ)
+ {
compressed_dp.unpackUUID(fullid, "ID");
compressed_dp.unpackU32(local_id, "LocalID");
compressed_dp.unpackU8(pcode, "PCode");
}
+ else //send to object cache
+ {
+ regionp->cacheFullUpdate(compressed_dp, flags);
+ continue;
+ }
+ }
else
{
+ remove_from_cache = true;
compressed_dp.unpackU32(local_id, "LocalID");
getUUIDFromLocal(fullid,
local_id,
@@ -435,6 +512,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
}
else // OUT_FULL only?
{
+ remove_from_cache = true;
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
msg_size += sizeof(LLUUID);
@@ -443,6 +521,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
}
objectp = findObject(fullid);
+ if(remove_from_cache)
+ {
+ objectp = regionp->forceToRemoveFromCache(local_id, objectp);
+ }
+
// This looks like it will break if the local_id of the object doesn't change
// upon boundary crossing, but we check for region id matching later...
// Reset object local id and region pointer if things have changed
@@ -488,9 +571,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
continue;
}
}
- else if (cached) // Cache hit only?
- {
- }
else
{
if (update_type != OUT_FULL)
@@ -521,13 +601,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
recorder.objectUpdateFailure(local_id, update_type, msg_size);
continue;
}
+
justCreated = TRUE;
mNumNewObjects++;
- sCacheHitRate.addValue(cached ? 100.f : 0.f);
-
}
-
if (objectp->isDead())
{
llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl;
@@ -541,17 +619,21 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
objectp->mLocalID = local_id;
}
processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
+
+#if 0
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
{
+ U32 flags = 0;
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
+
+ if(!(flags & FLAGS_TEMPORARY_ON_REZ))
+ {
bCached = true;
- LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
+ LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp, flags);
recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
}
}
- else if (cached) // Cache hit only?
- {
- objectp->mLocalID = local_id;
- processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated);
+#endif
}
else
{
@@ -575,14 +657,53 @@ void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys,
void **user_data,
const EObjectUpdateType update_type)
{
- processObjectUpdate(mesgsys, user_data, update_type, false, true);
+ processObjectUpdate(mesgsys, user_data, update_type, true);
}
void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
void **user_data,
const EObjectUpdateType update_type)
{
- processObjectUpdate(mesgsys, user_data, update_type, true, false);
+ //processObjectUpdate(mesgsys, user_data, update_type, true, false);
+
+ S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);
+ gFullObjectUpdates += num_objects;
+
+ U64 region_handle;
+ mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);
+ if (!regionp)
+ {
+ llwarns << "Object update from unknown region! " << region_handle << llendl;
+ return;
+ }
+
+ LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
+
+ for (S32 i = 0; i < num_objects; i++)
+ {
+ S32 msg_size = 0;
+ U32 id;
+ U32 crc;
+ U32 flags;
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
+ mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
+ msg_size += sizeof(U32) * 2;
+
+ // Lookup data packer and add this id to cache miss lists if necessary.
+ U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
+ if(!regionp->probeCache(id, crc, flags, cache_miss_type))
+ {
+ // Cache Miss.
+ recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
+
+ continue; // no data packer, skip this object
+ }
+ sample(sCacheHitRate, 100.f);
+ }
+
+ return;
}
void LLViewerObjectList::dirtyAllObjectInventory()
@@ -853,6 +974,8 @@ private:
LLSD mObjectIDs;
};
+static LLFastTimer::DeclareTimer FTM_IDLE_COPY("Idle Copy");
+
void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
{
// Update globals
@@ -903,10 +1026,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
U32 idle_count = 0;
- static LLFastTimer::DeclareTimer idle_copy("Idle Copy");
-
{
- LLFastTimer t(idle_copy);
+ LLFastTimer t(FTM_IDLE_COPY);
for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
active_iter != mActiveObjects.end(); active_iter++)
@@ -1032,10 +1153,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
*/
- LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
- LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count);
- LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
- LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
+ sample(LLStatViewer::NUM_OBJECTS, mObjects.size());
+ sample(LLStatViewer::NUM_ACTIVE_OBJECTS, idle_count);
+ sample(LLStatViewer::NUM_SIZE_CULLED, mNumSizeCulled);
+ sample(LLStatViewer::NUM_VIS_CULLED, mNumVisCulled);
}
void LLViewerObjectList::fetchObjectCosts()
@@ -1248,16 +1369,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
if (objectp)
{
- if (objectp->isDead())
- {
- // This object is already dead. Don't need to do more.
- return TRUE;
- }
- else
- {
- objectp->markDead();
- }
-
+ objectp->markDead(); // does the right thing if object already dead
return TRUE;
}
@@ -1893,6 +2005,29 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi
return objectp;
}
+LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id)
+{
+ llassert_always(uuid.notNull());
+
+ LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp);
+ if (!objectp)
+ {
+// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl;
+ return NULL;
+ }
+
+ objectp->mLocalID = local_id;
+ mUUIDObjectMap[uuid] = objectp;
+ setUUIDAndLocal(uuid,
+ local_id,
+ regionp->getHost().getAddress(),
+ regionp->getHost().getPort());
+ mObjects.push_back(objectp);
+
+ updateActive(objectp);
+
+ return objectp;
+}
LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender)
@@ -1914,6 +2049,10 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl;
return NULL;
}
+ if(regionp)
+ {
+ regionp->addToCreatedList(local_id);
+ }
mUUIDObjectMap[fullid] = objectp;
setUUIDAndLocal(fullid,
@@ -1960,9 +2099,7 @@ S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const
void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port)
{
-#ifdef ORPHAN_SPAM
- llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl;
-#endif
+ LL_DEBUGS("ORPHANS") << "Orphaning object " << childp->getID() << " with parent " << parent_id << LL_ENDL;
// We're an orphan, flag things appropriately.
childp->mOrphaned = TRUE;
@@ -2015,6 +2152,12 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
return;
}
+ //search object cache to get orphans
+ if(objectp->getRegion())
+ {
+ objectp->getRegion()->findOrphans(objectp->getLocalID());
+ }
+
// See if we are a parent of an orphan.
// Note: This code is fairly inefficient but it should happen very rarely.
// It can be sped up if this is somehow a performance issue...
@@ -2050,11 +2193,11 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
continue;
}
+ LL_DEBUGS("ORPHANS") << "Reunited parent " << objectp->mID
+ << " with child " << childp->mID << LL_ENDL;
+ LL_DEBUGS("ORPHANS") << "Glob: " << objectp->getPositionGlobal() << LL_ENDL;
+ LL_DEBUGS("ORPHANS") << "Agent: " << objectp->getPositionAgent() << LL_ENDL;
#ifdef ORPHAN_SPAM
- llinfos << "Reunited parent " << objectp->mID
- << " with child " << childp->mID << llendl;
- llinfos << "Glob: " << objectp->getPositionGlobal() << llendl;
- llinfos << "Agent: " << objectp->getPositionAgent() << llendl;
addDebugBeacon(objectp->getPositionAgent(),"");
#endif
gPipeline.markMoved(objectp->mDrawable);
@@ -2142,3 +2285,10 @@ bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const
}
+LLDebugBeacon::~LLDebugBeacon()
+{
+ if (mHUDObject.notNull())
+ {
+ mHUDObject->markDead();
+ }
+}
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 449a4633ff..464554245e 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -31,8 +31,8 @@
#include <set>
// common includes
-#include "llstat.h"
#include "llstring.h"
+#include "lltrace.h"
// project includes
#include "llviewerobject.h"
@@ -40,6 +40,7 @@
class LLCamera;
class LLNetMap;
class LLDebugBeacon;
+class LLVOCacheEntry;
const U32 CLOSE_BIN_SIZE = 10;
const U32 NUM_BINS = 128;
@@ -65,6 +66,7 @@ public:
inline LLViewerObject *findObject(const LLUUID &id);
LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object
+ LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id);
LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp,
const LLUUID &uuid, const U32 local_id, const LLHost &sender);
@@ -78,8 +80,10 @@ public:
void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list.
// Simulator and viewer side object updates...
- void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, LLDataPacker* dpp, BOOL justCreated);
- void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool cached=false, bool compressed=false);
+ void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type,
+ LLDataPacker* dpp, bool justCreated, bool from_cache = false);
+ LLViewerObject* processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp);
+ void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false);
void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
void updateApparentAngles(LLAgent &agent);
@@ -188,14 +192,13 @@ public:
S32 mNumUnknownUpdates;
S32 mNumDeadObjectUpdates;
- S32 mNumUnknownKills;
S32 mNumDeadObjects;
protected:
std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
S32 mNumOrphans;
- static LLStat sCacheHitRate;
+ static LLTrace::SampleStatHandle<> sCacheHitRate;
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
@@ -234,20 +237,14 @@ protected:
class LLDebugBeacon
{
public:
- ~LLDebugBeacon()
- {
- if (mHUDObject.notNull())
- {
- mHUDObject->markDead();
- }
- }
+ ~LLDebugBeacon();
LLVector3 mPositionAgent;
std::string mString;
LLColor4 mColor;
LLColor4 mTextColor;
S32 mLineWidth;
- LLPointer<LLHUDObject> mHUDObject;
+ LLPointer<class LLHUDObject> mHUDObject;
};
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
new file mode 100644
index 0000000000..d631985e82
--- /dev/null
+++ b/indra/newview/llvieweroctree.cpp
@@ -0,0 +1,1459 @@
+/**
+ * @file llvieweroctree.cpp
+ * @brief LLViewerOctreeGroup class implementation and supporting functions
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llvieweroctree.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+#include "llviewercontrol.h"
+#include "llappviewer.h"
+#include "llglslshader.h"
+#include "llviewershadermgr.h"
+
+//-----------------------------------------------------------------------------------
+//static variables definitions
+//-----------------------------------------------------------------------------------
+U32 LLViewerOctreeEntryData::sCurVisible = 0;
+BOOL LLViewerOctreeDebug::sInDebug = FALSE;
+
+//-----------------------------------------------------------------------------------
+//some global functions definitions
+//-----------------------------------------------------------------------------------
+typedef enum
+{
+ b000 = 0x00,
+ b001 = 0x01,
+ b010 = 0x02,
+ b011 = 0x03,
+ b100 = 0x04,
+ b101 = 0x05,
+ b110 = 0x06,
+ b111 = 0x07,
+} eLoveTheBits;
+
+//contact Runitai Linden for a copy of the SL object used to write this table
+//basically, you give the table a bitmask of the look-at vector to a node and it
+//gives you a triangle fan index array
+static U16 sOcclusionIndices[] =
+{
+ //000
+ b111, b110, b010, b011, b001, b101, b100, b110,
+ //001
+ b011, b010, b000, b001, b101, b111, b110, b010,
+ //010
+ b101, b100, b110, b111, b011, b001, b000, b100,
+ //011
+ b001, b000, b100, b101, b111, b011, b010, b000,
+ //100
+ b110, b000, b010, b011, b111, b101, b100, b000,
+ //101
+ b010, b100, b000, b001, b011, b111, b110, b100,
+ //110
+ b100, b010, b110, b111, b101, b001, b000, b010,
+ //111
+ b000, b110, b100, b101, b001, b011, b010, b110,
+};
+
+U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
+{
+ LLVector4a origin;
+ origin.load3(camera->getOrigin().mV);
+
+ S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
+
+ return cypher*8;
+}
+
+U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
+{
+ LLVector4a origin;
+ origin.load3(camera->getOrigin().mV);
+
+ S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
+
+ return (U8*) (sOcclusionIndices+cypher*8);
+}
+
+//create a vertex buffer for efficiently rendering cubes
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
+{
+ LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
+
+ ret->allocateBuffer(8, 64, true);
+
+ LLStrider<LLVector3> pos;
+ LLStrider<U16> idx;
+
+ ret->getVertexStrider(pos);
+ ret->getIndexStrider(idx);
+
+ pos[0] = LLVector3(-1,-1,-1);
+ pos[1] = LLVector3(-1,-1, 1);
+ pos[2] = LLVector3(-1, 1,-1);
+ pos[3] = LLVector3(-1, 1, 1);
+ pos[4] = LLVector3( 1,-1,-1);
+ pos[5] = LLVector3( 1,-1, 1);
+ pos[6] = LLVector3( 1, 1,-1);
+ pos[7] = LLVector3( 1, 1, 1);
+
+ for (U32 i = 0; i < 64; i++)
+ {
+ idx[i] = sOcclusionIndices[i];
+ }
+
+ ret->flush();
+
+ return ret;
+}
+
+
+#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0
+
+const F32 SG_OCCLUSION_FUDGE = 0.25f;
+#define SG_DISCARD_TOLERANCE 0.01f
+
+
+S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
+{
+ return AABBSphereIntersectR2(min, max, origin, rad*rad);
+}
+
+S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r)
+{
+ F32 d = 0.f;
+ F32 t;
+
+ if ((min-origin).magVecSquared() < r &&
+ (max-origin).magVecSquared() < r)
+ {
+ return 2;
+ }
+
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (origin.mV[i] < min.mV[i])
+ {
+ t = min.mV[i] - origin.mV[i];
+ d += t*t;
+ }
+ else if (origin.mV[i] > max.mV[i])
+ {
+ t = origin.mV[i] - max.mV[i];
+ d += t*t;
+ }
+
+ if (d > r)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+
+S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad)
+{
+ return AABBSphereIntersectR2(min, max, origin, rad*rad);
+}
+
+S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r)
+{
+ F32 d = 0.f;
+ F32 t;
+
+ LLVector4a origina;
+ origina.load3(origin.mV);
+
+ LLVector4a v;
+ v.setSub(min, origina);
+
+ if (v.dot3(v) < r)
+ {
+ v.setSub(max, origina);
+ if (v.dot3(v) < r)
+ {
+ return 2;
+ }
+ }
+
+
+ for (U32 i = 0; i < 3; i++)
+ {
+ if (origin.mV[i] < min[i])
+ {
+ t = min[i] - origin.mV[i];
+ d += t*t;
+ }
+ else if (origin.mV[i] > max[i])
+ {
+ t = origin.mV[i] - max[i];
+ d += t*t;
+ }
+
+ if (d > r)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------------
+//class LLViewerOctreeEntry definitions
+//-----------------------------------------------------------------------------------
+LLViewerOctreeEntry::LLViewerOctreeEntry()
+ : mGroup(NULL),
+ mBinRadius(0.f),
+ mBinIndex(-1)
+{
+ mPositionGroup.clear();
+ mExtents[0].clear();
+ mExtents[1].clear();
+
+ for(S32 i = 0; i < NUM_DATA_TYPE; i++)
+ {
+ mData[i] = NULL;
+ }
+}
+
+LLViewerOctreeEntry::~LLViewerOctreeEntry()
+{
+ llassert(!mGroup);
+}
+
+void LLViewerOctreeEntry::addData(LLViewerOctreeEntryData* data)
+{
+ //llassert(mData[data->getDataType()] == NULL);
+ llassert(data != NULL);
+
+ mData[data->getDataType()] = data;
+}
+
+void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data)
+{
+ //llassert(data->getDataType() != LLVOCACHEENTRY); //can not remove VOCache entry
+
+ if(!mData[data->getDataType()])
+ {
+ return;
+ }
+
+ mData[data->getDataType()] = NULL;
+
+ if(mGroup != NULL && !mData[LLDRAWABLE])
+ {
+ LLviewerOctreeGroup* group = mGroup;
+ mGroup = NULL;
+ group->removeFromGroup(data);
+
+ llassert(mBinIndex == -1);
+ }
+}
+
+//called by group handleDestruction() ONLY when group is destroyed by octree.
+void LLViewerOctreeEntry::nullGroup()
+{
+ mGroup = NULL;
+}
+
+void LLViewerOctreeEntry::setGroup(LLviewerOctreeGroup* group)
+{
+ if(mGroup == group)
+ {
+ return;
+ }
+
+ if(mGroup)
+ {
+ LLviewerOctreeGroup* group = mGroup;
+ mGroup = NULL;
+ group->removeFromGroup(this);
+
+ llassert(mBinIndex == -1);
+ }
+
+ mGroup = group;
+}
+
+//-----------------------------------------------------------------------------------
+//class LLViewerOctreeEntryData definitions
+//-----------------------------------------------------------------------------------
+LLViewerOctreeEntryData::~LLViewerOctreeEntryData()
+{
+ if(mEntry)
+ {
+ mEntry->removeData(this);
+ }
+}
+
+LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type)
+ : mDataType(data_type),
+ mEntry(NULL)
+{
+}
+
+//virtual
+void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry)
+{
+ if(mEntry.notNull())
+ {
+ return;
+ }
+
+ if(!entry)
+ {
+ mEntry = new LLViewerOctreeEntry();
+ }
+ else
+ {
+ mEntry = entry;
+ }
+ mEntry->addData(this);
+}
+
+void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max)
+{
+ mEntry->mExtents[0].load3(min.mV);
+ mEntry->mExtents[1].load3(max.mV);
+}
+
+void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max)
+{
+ mEntry->mExtents[0] = min;
+ mEntry->mExtents[1] = max;
+}
+
+void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos)
+{
+ mEntry->mPositionGroup = pos;
+}
+
+const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const
+{
+ return mEntry->getSpatialExtents();
+}
+
+//virtual
+void LLViewerOctreeEntryData::setGroup(LLviewerOctreeGroup* group)
+{
+ mEntry->setGroup(group);
+}
+
+void LLViewerOctreeEntryData::shift(const LLVector4a &shift_vector)
+{
+ mEntry->mExtents[0].add(shift_vector);
+ mEntry->mExtents[1].add(shift_vector);
+ mEntry->mPositionGroup.add(shift_vector);
+}
+
+LLviewerOctreeGroup* LLViewerOctreeEntryData::getGroup()const
+{
+ return mEntry.notNull() ? mEntry->mGroup : NULL;
+}
+
+const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const
+{
+ return mEntry->getPositionGroup();
+}
+
+//virtual
+bool LLViewerOctreeEntryData::isVisible() const
+{
+ if(mEntry)
+ {
+ return mEntry->mVisible == sCurVisible;
+ }
+ return false;
+}
+
+//virtual
+bool LLViewerOctreeEntryData::isRecentlyVisible() const
+{
+ if(!mEntry)
+ {
+ return false;
+ }
+
+ if(isVisible())
+ {
+ return true;
+ }
+ if(getGroup() && getGroup()->isRecentlyVisible())
+ {
+ setVisible();
+ return true;
+ }
+
+ return (sCurVisible - mEntry->mVisible < getMinFrameRange());
+}
+
+void LLViewerOctreeEntryData::setVisible() const
+{
+ if(mEntry)
+ {
+ mEntry->mVisible = sCurVisible;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+//class LLviewerOctreeGroup definitions
+//-----------------------------------------------------------------------------------
+
+LLviewerOctreeGroup::~LLviewerOctreeGroup()
+{
+ //empty here
+}
+
+LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) :
+ mOctreeNode(node),
+ mState(CLEAN)
+{
+ LLVector4a tmp;
+ tmp.splat(0.f);
+ mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
+ mObjectExtents[0] = mObjectExtents[1] = tmp;
+
+ mBounds[0] = node->getCenter();
+ mBounds[1] = node->getSize();
+
+ mOctreeNode->addListener(this);
+}
+
+bool LLviewerOctreeGroup::hasElement(LLViewerOctreeEntryData* data)
+{
+ if(!data->getEntry())
+ {
+ return false;
+ }
+ return std::find(getDataBegin(), getDataEnd(), data->getEntry()) != getDataEnd();
+}
+
+bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntryData* data)
+{
+ return removeFromGroup(data->getEntry());
+}
+
+bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry)
+{
+ llassert(entry != NULL);
+ llassert(!entry->getGroup());
+
+ unbound();
+ if (mOctreeNode)
+ {
+ if (!mOctreeNode->remove(entry))
+ {
+ OCT_ERRS << "Could not remove LLVOCacheEntry from LLVOCacheOctreeGroup" << llendl;
+ return false;
+ }
+ }
+ setState(OBJECT_DIRTY);
+
+ return true;
+}
+
+//virtual
+void LLviewerOctreeGroup::unbound()
+{
+ if (isDirty())
+ {
+ return;
+ }
+
+ setState(DIRTY);
+
+ //all the parent nodes need to rebound this child
+ if (mOctreeNode)
+ {
+ OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent();
+ while (parent != NULL)
+ {
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) parent->getListener(0);
+ if (!group || group->isDirty())
+ {
+ return;
+ }
+
+ group->setState(DIRTY);
+ parent = (OctreeNode*) parent->getParent();
+ }
+ }
+}
+
+//virtual
+void LLviewerOctreeGroup::rebound()
+{
+ if (!isDirty())
+ {
+ return;
+ }
+
+ if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
+ {
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0);
+ group->rebound();
+
+ //copy single child's bounding box
+ mBounds[0] = group->mBounds[0];
+ mBounds[1] = group->mBounds[1];
+ mExtents[0] = group->mExtents[0];
+ mExtents[1] = group->mExtents[1];
+
+ group->setState(SKIP_FRUSTUM_CHECK);
+ }
+ else if (mOctreeNode->isLeaf())
+ { //copy object bounding box if this is a leaf
+ boundObjects(TRUE, mExtents[0], mExtents[1]);
+ mBounds[0] = mObjectBounds[0];
+ mBounds[1] = mObjectBounds[1];
+ }
+ else
+ {
+ LLVector4a& newMin = mExtents[0];
+ LLVector4a& newMax = mExtents[1];
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0);
+ group->clearState(SKIP_FRUSTUM_CHECK);
+ group->rebound();
+ //initialize to first child
+ newMin = group->mExtents[0];
+ newMax = group->mExtents[1];
+
+ //first, rebound children
+ for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
+ {
+ group = (LLviewerOctreeGroup*) mOctreeNode->getChild(i)->getListener(0);
+ group->clearState(SKIP_FRUSTUM_CHECK);
+ group->rebound();
+ const LLVector4a& max = group->mExtents[1];
+ const LLVector4a& min = group->mExtents[0];
+
+ newMax.setMax(newMax, max);
+ newMin.setMin(newMin, min);
+ }
+
+ boundObjects(FALSE, newMin, newMax);
+
+ mBounds[0].setAdd(newMin, newMax);
+ mBounds[0].mul(0.5f);
+ mBounds[1].setSub(newMax, newMin);
+ mBounds[1].mul(0.5f);
+ }
+
+ clearState(DIRTY);
+
+ return;
+}
+
+//virtual
+void LLviewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj)
+{
+ obj->setGroup(this);
+ unbound();
+ setState(OBJECT_DIRTY);
+}
+
+//virtual
+void LLviewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj)
+{
+ obj->setGroup(NULL);
+ unbound();
+ setState(OBJECT_DIRTY);
+}
+
+//virtual
+void LLviewerOctreeGroup::handleDestruction(const TreeNode* node)
+{
+ for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i)
+ {
+ LLViewerOctreeEntry* obj = *i;
+ if (obj && obj->getGroup() == this)
+ {
+ obj->nullGroup();
+ //obj->setGroup(NULL);
+ }
+ }
+ mOctreeNode = NULL;
+}
+
+//virtual
+void LLviewerOctreeGroup::handleStateChange(const TreeNode* node)
+{
+ //drop bounding box upon state change
+ if (mOctreeNode != node)
+ {
+ mOctreeNode = (OctreeNode*) node;
+ }
+ unbound();
+}
+
+//virtual
+void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
+{
+ if (child->getListenerCount() == 0)
+ {
+ new LLviewerOctreeGroup(child);
+ }
+ else
+ {
+ OCT_ERRS << "LLviewerOctreeGroup redundancy detected." << llendl;
+ }
+
+ unbound();
+
+ ((LLviewerOctreeGroup*)child->getListener(0))->unbound();
+}
+
+//virtual
+void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child)
+{
+ unbound();
+}
+
+LLviewerOctreeGroup* LLviewerOctreeGroup::getParent()
+{
+ if (isDead())
+ {
+ return NULL;
+ }
+
+ if(!mOctreeNode)
+ {
+ return NULL;
+ }
+
+ OctreeNode* parent = mOctreeNode->getOctParent();
+
+ if (parent)
+ {
+ return (LLviewerOctreeGroup*) parent->getListener(0);
+ }
+
+ return NULL;
+}
+
+//virtual
+bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut)
+{
+ const OctreeNode* node = mOctreeNode;
+
+ if (node->isEmpty())
+ { //don't do anything if there are no objects
+ if (empty && mOctreeNode->getParent())
+ { //only root is allowed to be empty
+ OCT_ERRS << "Empty leaf found in octree." << llendl;
+ }
+ return false;
+ }
+
+ LLVector4a& newMin = mObjectExtents[0];
+ LLVector4a& newMax = mObjectExtents[1];
+
+ if (hasState(OBJECT_DIRTY))
+ { //calculate new bounding box
+ clearState(OBJECT_DIRTY);
+
+ //initialize bounding box to first element
+ OctreeNode::const_element_iter i = node->getDataBegin();
+ LLViewerOctreeEntry* entry = *i;
+ const LLVector4a* minMax = entry->getSpatialExtents();
+
+ newMin = minMax[0];
+ newMax = minMax[1];
+
+ for (++i; i != node->getDataEnd(); ++i)
+ {
+ entry = *i;
+ minMax = entry->getSpatialExtents();
+
+ update_min_max(newMin, newMax, minMax[0]);
+ update_min_max(newMin, newMax, minMax[1]);
+ }
+
+ mObjectBounds[0].setAdd(newMin, newMax);
+ mObjectBounds[0].mul(0.5f);
+ mObjectBounds[1].setSub(newMax, newMin);
+ mObjectBounds[1].mul(0.5f);
+ }
+
+ if (empty)
+ {
+ minOut = newMin;
+ maxOut = newMax;
+ }
+ else
+ {
+ minOut.setMin(minOut, newMin);
+ maxOut.setMax(maxOut, newMax);
+ }
+
+ return TRUE;
+}
+
+//virtual
+BOOL LLviewerOctreeGroup::isVisible() const
+{
+ return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE;
+}
+
+//virtual
+BOOL LLviewerOctreeGroup::isRecentlyVisible() const
+{
+ return FALSE;
+}
+
+void LLviewerOctreeGroup::setVisible()
+{
+ mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
+}
+
+void LLviewerOctreeGroup::checkStates()
+{
+#if LL_OCTREE_PARANOIA_CHECK
+ //LLOctreeStateCheck checker;
+ //checker.traverse(mOctreeNode);
+#endif
+}
+
+//-------------------------------------------------------------------------------------------
+//occulsion culling functions and classes
+//-------------------------------------------------------------------------------------------
+std::set<U32> LLOcclusionCullingGroup::sPendingQueries;
+class LLOcclusionQueryPool : public LLGLNamePool
+{
+public:
+ LLOcclusionQueryPool()
+ {
+ mCurQuery = 1;
+ }
+
+protected:
+
+ std::list<GLuint> mAvailableName;
+ GLuint mCurQuery;
+
+ virtual GLuint allocateName()
+ {
+ GLuint ret = 0;
+
+ if (!mAvailableName.empty())
+ {
+ ret = mAvailableName.front();
+ mAvailableName.pop_front();
+ }
+ else
+ {
+ ret = mCurQuery++;
+ }
+
+ return ret;
+ }
+
+ virtual void releaseName(GLuint name)
+ {
+#if LL_TRACK_PENDING_OCCLUSION_QUERIES
+ LLSpatialGroup::sPendingQueries.erase(name);
+#endif
+ llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
+ mAvailableName.push_back(name);
+ }
+};
+
+static LLOcclusionQueryPool sQueryPool;
+U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName()
+{
+ return sQueryPool.allocate();
+}
+
+void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name)
+{
+ sQueryPool.release(name);
+}
+
+//=====================================
+// Occlusion State Set/Clear
+//=====================================
+class LLSpatialSetOcclusionState : public OctreeTraveler
+{
+public:
+ U32 mState;
+ LLSpatialSetOcclusionState(U32 state) : mState(state) { }
+ virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->setOcclusionState(mState); }
+};
+
+class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState
+{
+public:
+ LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { }
+
+ virtual void traverse(const OctreeNode* n)
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0);
+
+ if (!group->isOcclusionState(mState))
+ {
+ OctreeTraveler::traverse(n);
+ }
+ }
+};
+
+
+LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) :
+ LLviewerOctreeGroup(node),
+ mSpatialPartition(part)
+{
+ part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod;
+ mLODHash = part->mLODSeed;
+
+ OctreeNode* oct_parent = node->getOctParent();
+ LLOcclusionCullingGroup* parent = oct_parent ? (LLOcclusionCullingGroup*) oct_parent->getListener(0) : NULL;
+
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mOcclusionQuery[i] = 0;
+ mOcclusionIssued[i] = 0;
+ mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
+ mVisible[i] = 0;
+ }
+}
+
+LLOcclusionCullingGroup::~LLOcclusionCullingGroup()
+{
+ releaseOcclusionQueryObjectNames();
+}
+
+BOOL LLOcclusionCullingGroup::needsUpdate()
+{
+ return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE;
+}
+
+//virtual
+void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
+{
+ if (child->getListenerCount() == 0)
+ {
+ new LLOcclusionCullingGroup(child, mSpatialPartition);
+ }
+ else
+ {
+ OCT_ERRS << "LLOcclusionCullingGroup redundancy detected." << llendl;
+ }
+
+ unbound();
+
+ ((LLviewerOctreeGroup*)child->getListener(0))->unbound();
+}
+
+void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
+{
+ if (gGLManager.mHasOcclusionQuery)
+ {
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
+ {
+ if (mOcclusionQuery[i])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
+ }
+ }
+ }
+}
+
+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
+ {
+ mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
+ if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
+ }
+ }
+}
+
+class LLSpatialClearOcclusionState : public OctreeTraveler
+{
+public:
+ U32 mState;
+
+ LLSpatialClearOcclusionState(U32 state) : mState(state) { }
+ virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->clearOcclusionState(mState); }
+};
+
+class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState
+{
+public:
+ LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { }
+
+ virtual void traverse(const OctreeNode* n)
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0);
+
+ if (group->isOcclusionState(mState))
+ {
+ OctreeTraveler::traverse(n);
+ }
+ }
+};
+
+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
+ {
+ mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");
+
+BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera)
+{
+ if (camera->getOrigin().isExactlyZero())
+ {
+ return FALSE;
+ }
+
+ const F32 vel = SG_OCCLUSION_FUDGE*2.f;
+ LLVector4a fudge;
+ fudge.splat(vel);
+
+ const LLVector4a* bounds = getBounds();
+ const LLVector4a& c = bounds[0];
+ LLVector4a r;
+ r.setAdd(bounds[1], fudge);
+
+ /*if (r.magVecSquared() > 1024.0*1024.0)
+ {
+ return TRUE;
+ }*/
+
+ LLVector4a e;
+ e.load3(camera->getOrigin().mV);
+
+ LLVector4a min;
+ min.setSub(c,r);
+ LLVector4a max;
+ max.setAdd(c,r);
+
+ S32 lt = e.lessThan(min).getGatheredBits() & 0x7;
+ if (lt)
+ {
+ return FALSE;
+ }
+
+ S32 gt = e.greaterThan(max).getGatheredBits() & 0x7;
+ if (gt)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void LLOcclusionCullingGroup::checkOcclusion()
+{
+ if (LLPipeline::sUseOcclusion > 1)
+ {
+ LLFastTimer t(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");
+
+ if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+ { //query was issued last frame, wait until it's available
+ S32 max_loop = 1024;
+ LLFastTimer t(FTM_OCCLUSION_WAIT);
+ while (!available && max_loop-- > 0)
+ {
+ //do some usefu work while we wait
+ F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f);
+ LLAppViewer::instance()->updateTextureThreads(max_time);
+
+ 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 LL_TRACK_PENDING_OCCLUSION_QUERIES
+ 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);
+ }
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
+static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw");
+
+void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera)
+{
+ if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
+ {
+ // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
+ if (earlyFail(camera))
+ {
+ LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL);
+ setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY);
+ assert_states_valid(this);
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ assert_states_valid(this);
+ }
+ else
+ {
+ if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
+ {
+ { //no query pending, or previous query to be discarded
+ LLFastTimer t(FTM_RENDER_OCCLUSION);
+
+ if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
+ {
+ LLFastTimer t(FTM_OCCLUSION_ALLOCATE);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
+ }
+
+ // Depth clamp all water to avoid it being culled as a result of being
+ // 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);
+
+ LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
+
+#if !LL_DARWIN
+ U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
+#else
+ U32 mode = GL_SAMPLES_PASSED_ARB;
+#endif
+
+#if LL_TRACK_PENDING_OCCLUSION_QUERIES
+ sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+#endif
+
+ {
+ LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
+
+ //store which frame this query was issued on
+ mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
+
+ {
+ LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY);
+ glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ }
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+ shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr());
+ shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,
+ mBounds[1][1]+SG_OCCLUSION_FUDGE,
+ mBounds[1][2]+SG_OCCLUSION_FUDGE);
+
+ if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
+ {
+ LLFastTimer t(FTM_OCCLUSION_DRAW_WATER);
+
+ LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
+ if (camera->getOrigin().isExactlyZero())
+ { //origin is invalid, draw entire box
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ }
+ else
+ {
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ }
+ }
+ else
+ {
+ LLFastTimer t(FTM_OCCLUSION_DRAW);
+ if (camera->getOrigin().isExactlyZero())
+ { //origin is invalid, draw entire box
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ }
+ else
+ {
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ }
+ }
+
+
+ {
+ LLFastTimer t(FTM_OCCLUSION_END_QUERY);
+ glEndQueryARB(mode);
+ }
+ }
+ }
+
+ {
+ LLFastTimer t(FTM_SET_OCCLUSION_STATE);
+ setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING);
+ clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY);
+ }
+ }
+ }
+ }
+}
+//-------------------------------------------------------------------------------------------
+//end of occulsion culling functions and classes
+//-------------------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+//class LLViewerOctreePartition definitions
+//-----------------------------------------------------------------------------------
+LLViewerOctreePartition::LLViewerOctreePartition() :
+ mRegionp(NULL),
+ mOcclusionEnabled(TRUE),
+ mDrawableType(0),
+ mLODSeed(0),
+ mLODPeriod(1)
+{
+ LLVector4a center, size;
+ center.splat(0.f);
+ size.splat(1.f);
+
+ mOctree = new OctreeRoot(center,size, NULL);
+}
+
+LLViewerOctreePartition::~LLViewerOctreePartition()
+{
+ delete mOctree;
+ mOctree = NULL;
+}
+
+BOOL LLViewerOctreePartition::isOcclusionEnabled()
+{
+ return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2;
+}
+
+//-----------------------------------------------------------------------------------
+//class LLViewerOctreeCull definitions
+//-----------------------------------------------------------------------------------
+
+//virtual
+bool LLViewerOctreeCull::earlyFail(LLviewerOctreeGroup* group)
+{
+ return false;
+}
+
+//virtual
+void LLViewerOctreeCull::traverse(const OctreeNode* n)
+{
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) n->getListener(0);
+
+ if (earlyFail(group))
+ {
+ return;
+ }
+
+ if (mRes == 2 ||
+ (mRes && group->hasState(LLviewerOctreeGroup::SKIP_FRUSTUM_CHECK)))
+ { //fully in, just add everything
+ OctreeTraveler::traverse(n);
+ }
+ else
+ {
+ mRes = frustumCheck(group);
+
+ if (mRes)
+ { //at least partially in, run on down
+ OctreeTraveler::traverse(n);
+ }
+
+ mRes = 0;
+ }
+}
+
+//------------------------------------------
+//agent space group culling
+S32 LLViewerOctreeCull::AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group)
+{
+ return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist);
+}
+
+S32 LLViewerOctreeCull::AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]);
+}
+//------------------------------------------
+
+//------------------------------------------
+//agent space object set culling
+S32 LLViewerOctreeCull::AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group)
+{
+ return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist);
+}
+
+S32 LLViewerOctreeCull::AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]);
+}
+//------------------------------------------
+
+//------------------------------------------
+//local regional space group culling
+S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInRegionFrustumNoFarClip(group->mBounds[0], group->mBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInRegionFrustum(group->mBounds[0], group->mBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift)
+{
+ return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist);
+}
+//------------------------------------------
+
+//------------------------------------------
+//local regional space object culling
+S32 LLViewerOctreeCull::AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInRegionFrustum(group->mObjectBounds[0], group->mObjectBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group)
+{
+ return mCamera->AABBInRegionFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]);
+}
+
+S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift)
+{
+ return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist);
+}
+//------------------------------------------
+
+//virtual
+bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group)
+{
+ if (branch->getElementCount() == 0) //no elements
+ {
+ return false;
+ }
+ else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box
+ {
+ return true;
+ }
+ else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//virtual
+void LLViewerOctreeCull::preprocess(LLviewerOctreeGroup* group)
+{
+}
+
+//virtual
+void LLViewerOctreeCull::processGroup(LLviewerOctreeGroup* group)
+{
+}
+
+//virtual
+void LLViewerOctreeCull::visit(const OctreeNode* branch)
+{
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0);
+
+ preprocess(group);
+
+ if (checkObjects(branch, group))
+ {
+ processGroup(group);
+ }
+}
+
+//--------------------------------------------------------------
+//class LLViewerOctreeDebug
+//virtual
+void LLViewerOctreeDebug::visit(const OctreeNode* branch)
+{
+#if 0
+ llinfos << "Node: " << (U32)branch << " # Elements: " << branch->getElementCount() << " # Children: " << branch->getChildCount() << llendl;
+ for (U32 i = 0; i < branch->getChildCount(); i++)
+ {
+ llinfos << "Child " << i << " : " << (U32)branch->getChild(i) << llendl;
+ }
+#endif
+ LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0);
+ processGroup(group);
+}
+
+//virtual
+void LLViewerOctreeDebug::processGroup(LLviewerOctreeGroup* group)
+{
+#if 0
+ const LLVector4a* vec4 = group->getBounds();
+ LLVector3 vec[2];
+ vec[0].set(vec4[0].getF32ptr());
+ vec[1].set(vec4[1].getF32ptr());
+ llinfos << "Bounds: " << vec[0] << " : " << vec[1] << llendl;
+
+ vec4 = group->getExtents();
+ vec[0].set(vec4[0].getF32ptr());
+ vec[1].set(vec4[1].getF32ptr());
+ llinfos << "Extents: " << vec[0] << " : " << vec[1] << llendl;
+
+ vec4 = group->getObjectBounds();
+ vec[0].set(vec4[0].getF32ptr());
+ vec[1].set(vec4[1].getF32ptr());
+ llinfos << "ObjectBounds: " << vec[0] << " : " << vec[1] << llendl;
+
+ vec4 = group->getObjectExtents();
+ vec[0].set(vec4[0].getF32ptr());
+ vec[1].set(vec4[1].getF32ptr());
+ llinfos << "ObjectExtents: " << vec[0] << " : " << vec[1] << llendl;
+#endif
+}
+//--------------------------------------------------------------
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
new file mode 100644
index 0000000000..7f2ca6ed2d
--- /dev/null
+++ b/indra/newview/llvieweroctree.h
@@ -0,0 +1,422 @@
+/**
+ * @file llvieweroctree.h
+ * @brief LLViewerObjectOctree.cpp header file, defining all supporting classes.
+ *
+ * $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_VIEWEROCTREE_H
+#define LL_VIEWEROCTREE_H
+
+#include <vector>
+#include <map>
+
+#include "v2math.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "m4math.h"
+#include "llvector4a.h"
+#include "llquaternion.h"
+#include "lloctree.h"
+#include "llviewercamera.h"
+
+class LLViewerRegion;
+class LLViewerOctreeEntryData;
+class LLviewerOctreeGroup;
+class LLViewerOctreeEntry;
+class LLViewerOctreePartition;
+
+typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
+typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
+typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
+typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
+typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
+
+#if LL_OCTREE_PARANOIA_CHECK
+#define assert_octree_valid(x) x->validate()
+#define assert_states_valid(x) ((LLviewerOctreeGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates()
+#else
+#define assert_octree_valid(x)
+#define assert_states_valid(x)
+#endif
+
+// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
+U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
+U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
+
+S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad);
+S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared);
+
+S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
+S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);
+
+//defines data needed for octree of an entry
+LL_ALIGN_PREFIX(16)
+class LLViewerOctreeEntry : public LLRefCount
+{
+ friend class LLViewerOctreeEntryData;
+
+public:
+ typedef enum
+ {
+ LLDRAWABLE = 0,
+ LLVOCACHEENTRY,
+ NUM_DATA_TYPE
+ }eEntryDataType_t;
+
+ ~LLViewerOctreeEntry();
+public:
+ LLViewerOctreeEntry();
+
+ void nullGroup(); //called by group handleDestruction() only
+ void setGroup(LLviewerOctreeGroup* group);
+ void removeData(LLViewerOctreeEntryData* data);
+
+ LLViewerOctreeEntryData* getDrawable() const {return mData[LLDRAWABLE];}
+ bool hasDrawable() const {return mData[LLDRAWABLE] != NULL;}
+ LLViewerOctreeEntryData* getVOCacheEntry() const {return mData[LLVOCACHEENTRY];}
+ bool hasVOCacheEntry() const {return mData[LLVOCACHEENTRY] != NULL;}
+
+ const LLVector4a* getSpatialExtents() const {return mExtents;}
+ const LLVector4a& getPositionGroup() const {return mPositionGroup;}
+ LLviewerOctreeGroup* getGroup()const {return mGroup;}
+
+ F32 getBinRadius() const {return mBinRadius;}
+ S32 getBinIndex() const {return mBinIndex; }
+ void setBinIndex(S32 index) const {mBinIndex = index; }
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+private:
+ void addData(LLViewerOctreeEntryData* data);
+
+private:
+ LLViewerOctreeEntryData* mData[NUM_DATA_TYPE]; //do not use LLPointer here.
+ LLviewerOctreeGroup* mGroup;
+
+ //aligned members
+ LL_ALIGN_16(LLVector4a mExtents[2]);
+ LL_ALIGN_16(LLVector4a mPositionGroup);
+ F32 mBinRadius;
+ mutable S32 mBinIndex;
+ mutable U32 mVisible;
+
+} LL_ALIGN_POSTFIX(16);
+
+//defines an abstract class for entry data
+LL_ALIGN_PREFIX(16)
+class LLViewerOctreeEntryData : public LLRefCount
+{
+protected:
+ ~LLViewerOctreeEntryData();
+
+public:
+ LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs)
+ {
+ *this = rhs;
+ }
+ LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type);
+
+ LLViewerOctreeEntry::eEntryDataType_t getDataType() const {return mDataType;}
+ LLViewerOctreeEntry* getEntry() {return mEntry;}
+
+ virtual void setOctreeEntry(LLViewerOctreeEntry* entry);
+
+ virtual U32 getMinFrameRange()const = 0;
+
+ F32 getBinRadius() const {return mEntry->getBinRadius();}
+ const LLVector4a* getSpatialExtents() const;
+ LLviewerOctreeGroup* getGroup()const;
+ const LLVector4a& getPositionGroup() const;
+
+ void setBinRadius(F32 rad) {mEntry->mBinRadius = rad;}
+ void setSpatialExtents(const LLVector3& min, const LLVector3& max);
+ void setSpatialExtents(const LLVector4a& min, const LLVector4a& max);
+ void setPositionGroup(const LLVector4a& pos);
+
+ virtual void setGroup(LLviewerOctreeGroup* group);
+ void shift(const LLVector4a &shift_vector);
+
+ U32 getVisible() const {return mEntry ? mEntry->mVisible : 0;}
+ void setVisible() const;
+ virtual bool isVisible() const;
+ virtual bool isRecentlyVisible() const;
+
+ static S32 getCurrentFrame() { return sCurVisible; }
+
+protected:
+ LLVector4a& getGroupPosition() {return mEntry->mPositionGroup;}
+ void initVisible(U32 visible) {mEntry->mVisible = visible;}
+
+ static void incrementVisible() {sCurVisible++;}
+protected:
+ LLPointer<LLViewerOctreeEntry> mEntry;
+ LLViewerOctreeEntry::eEntryDataType_t mDataType;
+ static U32 sCurVisible; // Counter for what value of mVisible means currently visible
+}LL_ALIGN_POSTFIX(16);
+
+
+//defines an octree group for an octree node, which contains multiple entries.
+LL_ALIGN_PREFIX(16)
+class LLviewerOctreeGroup : public LLOctreeListener<LLViewerOctreeEntry>
+{
+ friend class LLViewerOctreeCull;
+protected:
+ ~LLviewerOctreeGroup();
+
+public:
+ enum
+ {
+ CLEAN = 0x00000000,
+ DIRTY = 0x00000001,
+ OBJECT_DIRTY = 0x00000002,
+ SKIP_FRUSTUM_CHECK = 0x00000004,
+ DEAD = 0x00000008,
+ INVALID_STATE = 0x00000010,
+ };
+
+public:
+ typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
+ typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+
+ LLviewerOctreeGroup(OctreeNode* node);
+ LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs)
+ {
+ *this = rhs;
+ }
+
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
+ bool removeFromGroup(LLViewerOctreeEntryData* data);
+ bool removeFromGroup(LLViewerOctreeEntry* entry);
+
+ virtual void unbound();
+ virtual void rebound();
+
+ BOOL isDead() { return hasState(DEAD); }
+
+ void setVisible();
+ BOOL isVisible() const;
+ virtual BOOL isRecentlyVisible() const;
+ bool isEmpty() const { return mOctreeNode->isEmpty(); }
+
+ U32 getState() {return mState; }
+ bool isDirty() const {return mState & DIRTY;}
+ bool hasState(U32 state) const {return mState & state;}
+ void setState(U32 state) {mState |= state;}
+ void clearState(U32 state) {mState &= ~state;}
+
+ //LISTENER FUNCTIONS
+ virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj);
+ virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj);
+ virtual void handleDestruction(const TreeNode* node);
+ virtual void handleStateChange(const TreeNode* node);
+ virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
+ virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
+
+ OctreeNode* getOctreeNode() {return mOctreeNode;}
+ LLviewerOctreeGroup* getParent();
+
+ const LLVector4a* getBounds() const {return mBounds;}
+ const LLVector4a* getExtents() const {return mExtents;}
+ const LLVector4a* getObjectBounds() const {return mObjectBounds;}
+ const LLVector4a* getObjectExtents() const {return mObjectExtents;}
+
+ //octree wrappers to make code more readable
+ element_list& getData() { return mOctreeNode->getData(); }
+ element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
+ element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
+ U32 getElementCount() const { return mOctreeNode->getElementCount(); }
+ bool hasElement(LLViewerOctreeEntryData* data);
+
+protected:
+ void checkStates();
+private:
+ virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut);
+
+protected:
+ U32 mState;
+ OctreeNode* mOctreeNode;
+
+ LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node
+ LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children
+ LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node
+
+public:
+ S32 mVisible[LLViewerCamera::NUM_CAMERAS];
+
+}LL_ALIGN_POSTFIX(16);
+
+//octree group which has capability to support occlusion culling
+//LL_ALIGN_PREFIX(16)
+class LLOcclusionCullingGroup : public LLviewerOctreeGroup
+{
+public:
+ typedef enum
+ {
+ OCCLUDED = 0x00010000,
+ QUERY_PENDING = 0x00020000,
+ ACTIVE_OCCLUSION = 0x00040000,
+ DISCARD_QUERY = 0x00080000,
+ EARLY_FAIL = 0x00100000,
+ } eOcclusionState;
+
+ typedef enum
+ {
+ STATE_MODE_SINGLE = 0, //set one node
+ STATE_MODE_BRANCH, //set entire branch
+ STATE_MODE_DIFF, //set entire branch as long as current state is different
+ STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras
+ } eSetStateMode;
+
+public:
+ LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part);
+ LLOcclusionCullingGroup(const LLOcclusionCullingGroup& rhs) : LLviewerOctreeGroup(rhs)
+ {
+ *this = rhs;
+ }
+ ~LLOcclusionCullingGroup();
+
+ void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
+ void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
+ void checkOcclusion(); //read back last occlusion query (if any)
+ void doOcclusion(LLCamera* camera); //issue occlusion query
+ BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
+
+ BOOL needsUpdate();
+
+ //virtual
+ void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
+
+ static U32 getNewOcclusionQueryObjectName();
+ static void releaseOcclusionQueryObjectName(U32 name);
+
+protected:
+ void releaseOcclusionQueryObjectNames();
+
+private:
+ BOOL earlyFail(LLCamera* camera);
+
+protected:
+ U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
+ U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
+
+ S32 mLODHash;
+
+ LLViewerOctreePartition* mSpatialPartition;
+ U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
+
+public:
+ static std::set<U32> sPendingQueries;
+};//LL_ALIGN_POSTFIX(16);
+
+class LLViewerOctreePartition
+{
+public:
+ LLViewerOctreePartition();
+ virtual ~LLViewerOctreePartition();
+
+ // Cull on arbitrary frustum
+ virtual S32 cull(LLCamera &camera) = 0;
+ BOOL isOcclusionEnabled();
+
+public:
+ U32 mPartitionType;
+ U32 mDrawableType;
+ OctreeNode* mOctree;
+ LLViewerRegion* mRegionp; // the region this partition belongs to.
+ BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
+ U32 mLODSeed;
+ U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
+};
+
+class LLViewerOctreeCull : public OctreeTraveler
+{
+public:
+ LLViewerOctreeCull(LLCamera* camera)
+ : mCamera(camera), mRes(0) { }
+
+ virtual bool earlyFail(LLviewerOctreeGroup* group);
+ virtual void traverse(const OctreeNode* n);
+
+ //agent space group cull
+ S32 AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group);
+ S32 AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group);
+ S32 AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group);
+
+ //agent space object set cull
+ S32 AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group);
+ S32 AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group);
+ S32 AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group);
+
+ //local region space group cull
+ S32 AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group);
+ S32 AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group);
+ S32 AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift);
+
+ //local region space object set cull
+ S32 AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group);
+ S32 AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group);
+ S32 AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift);
+
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group) = 0;
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) = 0;
+
+ virtual bool checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group);
+ virtual void preprocess(LLviewerOctreeGroup* group);
+ virtual void processGroup(LLviewerOctreeGroup* group);
+ virtual void visit(const OctreeNode* branch);
+
+protected:
+ LLCamera *mCamera;
+ S32 mRes;
+};
+
+//scan the octree, output the info of each node for debug use.
+class LLViewerOctreeDebug : public OctreeTraveler
+{
+public:
+ virtual void processGroup(LLviewerOctreeGroup* group);
+ virtual void visit(const OctreeNode* branch);
+
+public:
+ static BOOL sInDebug;
+};
+
+#endif
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6bd9f66b9c..a23a15da32 100755
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -151,8 +151,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
if (group != NULL)
{
- LLVector3 center(group->mOctreeNode->getCenter().getF32ptr());
- LLVector3 size(group->mOctreeNode->getSize().getF32ptr());
+ LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr());
+ LLVector3 size(group->getOctreeNode()->getSize().getF32ptr());
size += LLVector3(0.01f, 0.01f, 0.01f);
mMinObjPos = center - size;
mMaxObjPos = center + size;
@@ -467,6 +467,20 @@ LLViewerPartSim::LLViewerPartSim()
mID = ++id_seed;
}
+//enable/disable particle system
+void LLViewerPartSim::enable(bool enabled)
+{
+ if(!enabled && sMaxParticleCount > 0)
+ {
+ sMaxParticleCount = 0; //disable
+ }
+ else if(enabled && sMaxParticleCount < 1)
+ {
+ sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);
+ }
+
+ return;
+}
void LLViewerPartSim::destroyClass()
{
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index c91fcf0691..5c71b4c49e 100755
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -27,7 +27,6 @@
#ifndef LL_LLVIEWERPARTSIM_H
#define LL_LLVIEWERPARTSIM_H
-#include "lldarrayptr.h"
#include "llframetimer.h"
#include "llpointer.h"
#include "llpartdata.h"
@@ -36,7 +35,6 @@
class LLViewerTexture;
class LLViewerPart;
class LLViewerRegion;
-class LLViewerTexture;
class LLVOPartGroup;
#define LL_MAX_PARTICLE_COUNT 8192
@@ -134,6 +132,8 @@ public:
typedef std::vector<LLViewerPartGroup *> group_list_t;
typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t;
+ void enable(bool enabled);
+
void shift(const LLVector3 &offset);
void updateSimulation();
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index a565005f30..5df456dab6 100755
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -52,11 +52,9 @@
// Library headers from llcommon project:
#include "bitpack.h"
-#include "lldeleteutils.h"
#include "imageids.h"
#include "indra_constants.h"
#include "llinitparam.h"
-
#include "llallocator.h"
#include "llapp.h"
#include "llcriticaldamp.h"
@@ -65,11 +63,7 @@
#include "llerror.h"
#include "llfasttimer.h"
#include "llframetimer.h"
-#include "llhash.h"
-#include "lllocalidhashmap.h"
-#include "llnametable.h"
#include "llpointer.h"
-#include "llpriqueuemap.h"
#include "llprocessor.h"
#include "llrefcount.h"
#include "llsafehandle.h"
@@ -79,9 +73,7 @@
#include "llstrider.h"
#include "llstring.h"
#include "llsys.h"
-#include "llthread.h"
#include "lltimer.h"
-#include "lluuidhashmap.h"
#include "stdenums.h"
#include "stdtypes.h"
#include "timing.h"
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 8422708add..64b25f4b0b 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -70,6 +70,7 @@
#include "stringize.h"
#include "llviewercontrol.h"
#include "llsdserialize.h"
+#include "llvieweroctree.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -85,6 +86,8 @@ const F32 CAP_REQUEST_TIMEOUT = 18;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
+BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
+
typedef std::map<std::string, std::string> CapabilityMap;
class LLViewerRegionImpl {
@@ -97,6 +100,10 @@ public:
mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
mSeedCapAttempts(0),
mHttpResponderID(0),
+ mLastCameraUpdate(0),
+ mLastCameraOrigin(),
+ mVOCachePartition(NULL),
+ mLandp(NULL),
// I'd prefer to set the LLCapabilityListener name to match the region
// name -- it's disappointing that's not available at construction time.
// We could instead store an LLCapabilityListener*, making
@@ -108,8 +115,7 @@ public:
// construction time.
mCapabilityListener(host.getString(), gMessageSystem, *region,
gAgent.getID(), gAgent.getSessionID())
- {
- }
+ {}
void buildCapabilityNames(LLSD& capabilityNames);
@@ -133,7 +139,15 @@ public:
// Misc
LLVLComposition *mCompositionp; // Composition layer for the surface
- LLVOCacheEntry::vocache_entry_map_t mCacheMap;
+ LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries
+ LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries;
+ LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated.
+ std::set< LLPointer<LLviewerOctreeGroup> > mVisibleGroups; //visible groupa
+ LLVOCachePartition* mVOCachePartition;
+ LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation.
+ LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation.
+ std::set<U32> mNonCacheableCreatedList; //list of local ids of all non-cacheable objects
+
// time?
// LRU info?
@@ -143,7 +157,7 @@ public:
CapabilityMap mCapabilities;
CapabilityMap mSecondCapabilitiesTracker;
-
+
LLEventPoll* mEventPoll;
S32 mSeedCapMaxAttempts;
@@ -158,7 +172,10 @@ public:
LLCapabilityListener mCapabilityListener;
//spatial partitions for objects in this region
- std::vector<LLSpatialPartition*> mObjectPartition;
+ std::vector<LLViewerOctreePartition*> mObjectPartition;
+
+ LLVector3 mLastCameraOrigin;
+ U32 mLastCameraUpdate;
};
// support for secondlife:///app/region/{REGION} SLapps
@@ -220,7 +237,7 @@ public:
}
}
- void result(const LLSD& content)
+ void result(const LLSD& content)
{
LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
if(!regionp) //region was removed
@@ -350,7 +367,10 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheLoaded(FALSE),
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
- mCapabilitiesReceived(false)
+ mCapabilitiesReceived(false),
+ mBitsReceived(0.f),
+ mPacketsReceived(0.f),
+ mDead(FALSE)
{
mWidth = region_width_meters;
mImpl->mOriginGlobal = from_region_handle(handle);
@@ -382,17 +402,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
//create object partitions
//MUST MATCH declaration of eObjectPartitions
- mImpl->mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD
- mImpl->mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN
- mImpl->mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER
- mImpl->mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER
- mImpl->mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE
- mImpl->mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE
- mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS
- mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME
- mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
- mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
+ mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD
+ mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN
+ mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER
+ mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER
+ mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE
+ mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE
+ mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
+ mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
+ mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
+ mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE
+ mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
+
+ mImpl->mVOCachePartition = getVOCachePartition();
}
@@ -413,6 +436,12 @@ void LLViewerRegion::initStats()
LLViewerRegion::~LLViewerRegion()
{
+ mDead = TRUE;
+ mImpl->mActiveSet.clear();
+ mImpl->mVisibleEntries.clear();
+ mImpl->mVisibleGroups.clear();
+ mImpl->mWaitingSet.clear();
+
gVLManager.cleanupData(this);
// Can't do this on destruction, because the neighbor pointers might be invalid.
// This should be reference counted...
@@ -427,10 +456,10 @@ LLViewerRegion::~LLViewerRegion()
delete mImpl->mEventPoll;
LLHTTPSender::clearSender(mImpl->mHost);
- saveObjectCache();
-
std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
+ saveObjectCache();
+
delete mImpl;
mImpl = NULL;
}
@@ -471,9 +500,13 @@ void LLViewerRegion::loadObjectCache()
// Presume success. If it fails, we don't want to try again.
mCacheLoaded = TRUE;
- if(LLVOCache::hasInstance())
+ if(LLVOCache::instanceExists())
{
LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
+ if (mImpl->mCacheMap.empty())
+ {
+ mCacheDirty = TRUE;
+ }
}
}
@@ -490,16 +523,15 @@ void LLViewerRegion::saveObjectCache()
return;
}
- if(LLVOCache::hasInstance())
+ if(LLVOCache::instanceExists())
{
- LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;
+ const F32 start_time_threshold = 600.0f; //seconds
+ bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file.
+
+ LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ;
mCacheDirty = FALSE;
}
- for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
- {
- delete iter->second;
- }
mImpl->mCacheMap.clear();
}
@@ -765,8 +797,365 @@ void LLViewerRegion::dirtyHeights()
}
}
+void LLViewerRegion::replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry)
+{
+ //save old entry
+ old_entry->moveTo(new_entry);
+ U32 state = old_entry->getState();
+ U32 old_parent_id = old_entry->getParentID();
+
+ //kill old entry
+ killCacheEntry(old_entry);
+
+ //parse new entry
+ U32 new_parent_id = 0;
+ LLViewerObject::unpackParentID(new_entry->getDP(), new_parent_id);
+
+ //store new entry
+ mImpl->mCacheMap[new_entry->getLocalID()] = new_entry;
+
+ //process entry state
+ new_entry->setState(state);
+ if(state == LLVOCacheEntry::ACTIVE)
+ {
+ llassert(new_entry->getEntry()->hasDrawable());
+ mImpl->mActiveSet.insert(new_entry);
+ }
+ else if(state == LLVOCacheEntry::WAITING)
+ {
+ mImpl->mWaitingSet.insert(new_entry);
+ }
+
+ //process parent info
+ if(!old_parent_id && new_parent_id > 0) //becomes a child
+ {
+ new_entry->clearChildrenList();
+ }
+ new_entry->setParentID(new_parent_id);
+
+ //update the object
+ gObjectList.processObjectUpdateFromCache(new_entry, this);
+}
+
+//physically delete the cache entry
+void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
+{
+ if(!entry)
+ {
+ return;
+ }
+
+ //remove from active list and waiting list
+ if(entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ mImpl->mActiveSet.erase(entry);
+ }
+ else
+ {
+ if(entry->isState(LLVOCacheEntry::WAITING))
+ {
+ mImpl->mWaitingSet.erase(entry);
+ }
+
+ //remove from mVOCachePartition
+ removeFromVOCacheTree(entry);
+ }
+
+ //remove from the forced visible list
+ mImpl->mVisibleEntries.erase(entry);
+
+ //kill LLViewerObject if exists
+ //this should be done by the rendering pipeline automatically.
+
+ entry->setState(LLVOCacheEntry::INACTIVE);
+
+ //remove from mCacheMap, real deletion
+ mImpl->mCacheMap.erase(entry->getLocalID());
+}
+
+//physically delete the cache entry
+void LLViewerRegion::killCacheEntry(U32 local_id)
+{
+ killCacheEntry(getCacheEntry(local_id));
+}
+
+U32 LLViewerRegion::getNumOfActiveCachedObjects() const
+{
+ return mImpl->mActiveSet.size();
+}
+
+void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
+{
+ if(!entry || mDead)
+ {
+ return;
+ }
+
+ if(entry->isState(LLVOCacheEntry::WAITING))
+ {
+ mImpl->mWaitingSet.erase(entry);
+ }
+
+ entry->setState(LLVOCacheEntry::ACTIVE);
+ entry->setVisible();
+
+ llassert(entry->getEntry()->hasDrawable());
+ mImpl->mActiveSet.insert(entry);
+}
+
+void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep)
+{
+ if(mDead)
+ {
+ return;
+ }
+
+ if(entry->getParentID() > 0) //is a child
+ {
+ LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
+ if(parent)
+ {
+ parent->addChild(entry);
+ }
+ else //parent is not in the cache, put into the orphan list.
+ {
+ mOrphanMap[entry->getParentID()].push_back(entry->getLocalID());
+ }
+ }
+ else //insert to vo cache tree.
+ {
+ //shift to the local regional space from agent space
+ const LLVector3 pos = drawablep->getVObj()->getPositionRegion();
+ LLVector4a vec(pos[0], pos[1], pos[2]);
+ LLVector4a shift;
+ shift.setSub(vec, entry->getPositionGroup());
+ entry->shift(shift);
+
+ addToVOCacheTree(entry);
+ }
+
+ mImpl->mVisibleEntries.erase(entry);
+ mImpl->mActiveSet.erase(entry);
+ mImpl->mWaitingSet.erase(entry);
+ entry->setState(LLVOCacheEntry::INACTIVE);
+}
+
+void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group)
+{
+ if(mDead || group->isEmpty())
+ {
+ return;
+ }
+ group->setVisible();
+ mImpl->mVisibleGroups.insert(group);
+}
+
+void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
+{
+ if(!sVOCacheCullingEnabled)
+ {
+ return;
+ }
+
+ if(mDead || !entry || !entry->getEntry())
+ {
+ return;
+ }
+ if(entry->getGroup()) //already in octree.
+ {
+ return;
+ }
+ if(entry->getParentID() > 0)
+ {
+ return; //no child prim in cache octree.
+ }
+
+ llassert(!entry->getEntry()->hasDrawable());
+
+ mImpl->mVOCachePartition->addEntry(entry->getEntry());
+}
+
+void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
+{
+ if(mDead || !entry || !entry->getEntry())
+ {
+ return;
+ }
+ if(!entry->getGroup())
+ {
+ return;
+ }
+
+ mImpl->mVOCachePartition->removeEntry(entry->getEntry());
+}
+
+//add the visible entries
+void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry)
+{
+ if(mDead || !entry)
+ {
+ return;
+ }
+
+ if(entry->isState(LLVOCacheEntry::IN_QUEUE))
+ {
+ return;
+ }
+
+ if(entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ entry->setState(LLVOCacheEntry::IN_QUEUE);
+ }
+ mImpl->mVisibleEntries.insert(entry);
+}
+
+F32 LLViewerRegion::updateVisibleEntries(F32 max_time)
+{
+ if(mDead)
+ {
+ return max_time;
+ }
+
+ if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty())
+ {
+ return max_time;
+ }
+
+ LLTimer update_timer;
+
+ const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin();
+ const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
+ bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);
+
+ //process visible entries
+ max_time *= 0.5f; //only use up to half available time to update entries.
+
+#if 1
+ for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
+ {
+ LLVOCacheEntry* vo_entry = *iter;
+ vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate);
+
+ if(vo_entry->getState() < LLVOCacheEntry::WAITING)
+ {
+ mImpl->mWaitingList.insert(vo_entry);
+ }
+
+ LLVOCacheEntry* child;
+ S32 num_child = vo_entry->getNumOfChildren();
+ S32 num_done = 0;
+ for(S32 i = 0; i < num_child; i++)
+ {
+ child = vo_entry->getChild(i);
+ if(child->getState() < LLVOCacheEntry::WAITING)
+ {
+ child->setSceneContribution(vo_entry->getSceneContribution());
+ mImpl->mWaitingList.insert(child);
+ }
+ else
+ {
+ num_done++;
+ }
+ }
+ if(num_done == num_child)
+ {
+ vo_entry->clearChildrenList();
+ }
+
+ if(!vo_entry->getNumOfChildren())
+ {
+ if(vo_entry->getState() >= LLVOCacheEntry::WAITING)
+ {
+ LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
+ ++next_iter;
+ mImpl->mVisibleEntries.erase(iter);
+ iter = next_iter;
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+#endif
+
+ //process visible groups
+ std::set< LLPointer<LLviewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin();
+ for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter)
+ {
+ LLPointer<LLviewerOctreeGroup> group = *group_iter;
+ if(group->getNumRefs() < 3 || //group to be deleted
+ !group->getOctreeNode() || group->isEmpty()) //group empty
+ {
+ continue;
+ }
+
+ for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ if((*i)->hasVOCacheEntry())
+ {
+ LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry();
+
+ if(vo_entry->getParentID() > 0) //is a child
+ {
+ //child visibility depends on its parent.
+ continue;
+ }
+
+ vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate);
+ mImpl->mWaitingList.insert(vo_entry);
+ }
+ }
+ }
+
+ if(needs_update)
+ {
+ mImpl->mLastCameraOrigin = camera_origin;
+ mImpl->mLastCameraUpdate = cur_frame;
+ }
+
+ return 2.0f * max_time - update_timer.getElapsedTimeF32();
+}
+
+F32 LLViewerRegion::createVisibleObjects(F32 max_time)
+{
+ if(mDead)
+ {
+ return max_time;
+ }
+ if(mImpl->mWaitingList.empty())
+ {
+ return max_time;
+ }
+
+ LLTimer update_timer;
+ S32 max_num_objects = 64; //minimum number of new objects to be added
+ for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
+ iter != mImpl->mWaitingList.end(); ++iter)
+ {
+ LLVOCacheEntry* vo_entry = *iter;
+
+ if(vo_entry->getState() < LLVOCacheEntry::WAITING)
+ {
+ addNewObject(vo_entry);
+ if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+ }
+
+ return max_time - update_timer.getElapsedTimeF32();
+}
+
BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
{
+ LLTimer update_timer;
+
// did_update returns TRUE if we did at least one significant update
BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
@@ -776,9 +1165,152 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
mParcelOverlay->idleUpdate();
}
+ max_update_time -= update_timer.getElapsedTimeF32();
+ if(max_update_time < 0.f || mImpl->mCacheMap.empty())
+ {
return did_update;
}
+ if(!sVOCacheCullingEnabled)
+ {
+ return did_update;
+ }
+
+ //kill invisible objects
+ max_update_time = killInvisibleObjects(max_update_time);
+
+ max_update_time = updateVisibleEntries(max_update_time);
+ createVisibleObjects(max_update_time);
+
+ mImpl->mWaitingList.clear();
+ mImpl->mVisibleGroups.clear();
+
+ return did_update;
+}
+
+F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
+{
+#if 1
+ if(!sVOCacheCullingEnabled)
+ {
+ return max_time;
+ }
+ if(mImpl->mActiveSet.empty())
+ {
+ return max_time;
+ }
+
+ static LLVOCacheEntry* last_visited_entry = NULL;
+
+ const size_t MAX_UPDATE = 32;
+ std::vector<LLDrawable*> delete_list;
+ S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size());
+ LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry);
+
+ for(; update_counter > 0; --update_counter, ++iter)
+ {
+ if(iter == mImpl->mActiveSet.end())
+ {
+ iter = mImpl->mActiveSet.begin();
+ }
+
+ if(!(*iter)->isRecentlyVisible())
+ {
+ killObject((*iter), delete_list);
+ }
+ }
+
+ if(iter == mImpl->mActiveSet.end())
+ {
+ last_visited_entry = NULL;
+ }
+ else
+ {
+ last_visited_entry = *iter;
+ }
+
+ for(S32 i = 0; i < delete_list.size(); i++)
+ {
+ gObjectList.killObject(delete_list[i]->getVObj());
+ }
+ delete_list.clear();
+#endif
+ return max_time;
+}
+
+void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
+{
+ //kill the object.
+ LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
+ llassert(drawablep);
+
+ if(!drawablep->getParent())
+ {
+ LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); iter++)
+ {
+ LLViewerObject* child = *iter;
+ if(child->mDrawable->isRecentlyVisible())
+ {
+ //set the parent group visible if any of its children visible.
+ ((LLViewerOctreeEntryData*)drawablep)->setVisible();
+ return;
+ }
+ }
+ delete_list.push_back(drawablep);
+ }
+}
+
+LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
+{
+ LLViewerObject* obj = NULL;
+ if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
+ {
+ //add the object
+ obj = gObjectList.processObjectUpdateFromCache(entry, this);
+ if(obj)
+ {
+ if(!entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ mImpl->mWaitingSet.insert(entry);
+ entry->setState(LLVOCacheEntry::WAITING);
+ }
+ }
+ }
+ else
+ {
+ //should not hit here any more, but does not hurt either, just put it back to active list
+ addActiveCacheEntry(entry);
+
+ //object is already created, crash here for debug use.
+ llwarns << "Object is already created." << llendl;
+ llassert(!entry->getEntry()->hasDrawable());
+ }
+ return obj;
+}
+
+//remove from object cache if the object receives a full-update or terse update
+LLViewerObject* LLViewerRegion::forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp)
+{
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
+ if (!entry)
+ {
+ return objectp; //not in the cache, do nothing.
+ }
+ if(!objectp) //object not created
+ {
+ entry->setTouched(FALSE); //mark this entry invalid
+
+ //create a new object before delete it from cache.
+ objectp = gObjectList.processObjectUpdateFromCache(entry, this);
+ }
+
+ //remove from cache.
+ killCacheEntry(entry);
+
+ return objectp;
+}
// As above, but forcibly do the update.
void LLViewerRegion::forceUpdate()
@@ -956,9 +1488,8 @@ void LLViewerRegion::updateNetStats()
mPacketsLost = cdp->getPacketsLost();
mPingDelay = cdp->getPingDelay();
- mBitStat.addValue(mBitsIn - mLastBitsIn);
- mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
- mPacketsLostStat.addValue(mPacketsLost);
+ mBitsReceived += mBitsIn - mLastBitsIn;
+ mPacketsReceived += mPacketsIn - mLastPacketsIn;
}
@@ -1234,12 +1765,146 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
mSimulatorFeatures = sim_features;
}
-LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
+//this is called when the parent is not cacheable.
+//move all orphan children out of cache and insert to rendering octree.
+void LLViewerRegion::findOrphans(U32 parent_id)
+{
+ orphan_list_t::iterator iter = mOrphanMap.find(parent_id);
+ if(iter != mOrphanMap.end())
+ {
+ std::vector<U32>* children = &mOrphanMap[parent_id];
+ for(S32 i = 0; i < children->size(); i++)
+ {
+ //parent is visible, so is the child.
+ LLVOCacheEntry* child = getCacheEntry((*children)[i]);
+ addVisibleCacheEntry(child);
+ }
+ children->clear();
+ mOrphanMap.erase(parent_id);
+ }
+}
+
+void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
+{
+ if(!sVOCacheCullingEnabled)
+ {
+ gObjectList.processObjectUpdateFromCache(entry, this);
+ return;
+ }
+
+ if(entry != NULL && !entry->getEntry())
+ {
+ entry->setOctreeEntry(NULL);
+
+ if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline
+ {
+ addActiveCacheEntry(entry);
+
+ //set parent id
+ U32 parent_id = 0;
+ LLViewerObject::unpackParentID(entry->getDP(), parent_id);
+ if(parent_id > 0)
+ {
+ entry->setParentID(parent_id);
+ }
+
+ //update the object
+ gObjectList.processObjectUpdateFromCache(entry, this);
+ return; //done
+ }
+ }
+ else if(entry->getGroup() != NULL)
+ {
+ return; //already in octree, no post processing.
+ }
+
+ LLVector3 pos;
+ LLVector3 scale;
+ LLQuaternion rot;
+
+ //decode spatial info and parent info
+ U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot);
+
+ if(parent_id > 0) //has parent
+ {
+ entry->setParentID(parent_id);
+
+ //1, find the parent in cache
+ LLVOCacheEntry* parent = getCacheEntry(parent_id);
+
+ //2, parent is not in the cache, put into the orphan list.
+ if(!parent)
+ {
+ //check if parent is non-cacheable and already created
+ if(isNonCacheableObjectCreated(parent_id))
+ {
+ //parent is visible, so is the child.
+ addVisibleCacheEntry(entry);
+ }
+ else
+ {
+ mOrphanMap[parent_id].push_back(entry->getLocalID());
+ }
+ }
+ else //parent in cache
+ {
+ if(!parent->isState(LLVOCacheEntry::INACTIVE))
+ {
+ //parent is visible, so is the child.
+ addVisibleCacheEntry(entry);
+ }
+ else
+ {
+ parent->addChild(entry);
+ }
+ }
+
+ return;
+ }
+
+ //
+ //no parent
+ //
+ entry->setBoundingInfo(pos, scale);
+ if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ addToVOCacheTree(entry);
+ }
+
+ if(!parent_id) //a potential parent
+ {
+ //find all children and update their bounding info
+ orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID());
+ if(iter != mOrphanMap.end())
+ {
+ std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()];
+ S32 size = orphans->size();
+ for(S32 i = 0; i < size; i++)
+ {
+ LLVOCacheEntry* child = getCacheEntry((*orphans)[i]);
+ if(child)
+ {
+ entry->addChild(child);
+ }
+ }
+ orphans->clear();
+ mOrphanMap.erase(entry->getLocalID());
+ }
+ }
+
+ return ;
+}
+
+LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags)
{
- U32 local_id = objectp->getLocalID();
- U32 crc = objectp->getCRC();
+ eCacheUpdateResult result;
+ U32 crc;
+ U32 local_id;
- LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+ LLViewerObject::unpackU32(&dp, local_id, "LocalID");
+ LLViewerObject::unpackU32(&dp, crc, "CRC");
+
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
if (entry)
{
@@ -1248,41 +1913,140 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec
{
// Record a hit
entry->recordDupe();
- return CACHE_UPDATE_DUPE;
+ result = CACHE_UPDATE_DUPE;
+ }
+ else
+ {
+ // Update the cache entry
+ LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc, dp);
+
+ //if visible, update it
+ if(!entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ replaceVisibleCacheEntry(entry, new_entry);
+ }
+ else //invisible
+ {
+ //remove old entry
+ killCacheEntry(entry);
+ entry = new_entry;
+
+ mImpl->mCacheMap[local_id] = entry;
+ decodeBoundingInfo(entry);
}
- // Update the cache entry
- mImpl->mCacheMap.erase(local_id);
- delete entry;
+ result = CACHE_UPDATE_CHANGED;
+ }
+ }
+ else
+ {
+ // we haven't seen this object before
+ // Create new entry and add to map
+ result = CACHE_UPDATE_ADDED;
entry = new LLVOCacheEntry(local_id, crc, dp);
+
mImpl->mCacheMap[local_id] = entry;
- return CACHE_UPDATE_CHANGED;
+
+ decodeBoundingInfo(entry);
}
+ entry->setUpdateFlags(flags);
- // we haven't seen this object before
+ return result;
+ }
+
+LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags)
+{
+ eCacheUpdateResult result = cacheFullUpdate(dp, flags);
- // Create new entry and add to map
- eCacheUpdateResult result = CACHE_UPDATE_ADDED;
- if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
+#if 0
+ LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()];
+ if(!entry)
{
- delete mImpl->mCacheMap.begin()->second ;
- mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
- result = CACHE_UPDATE_REPLACED;
+ return result;
+ }
+ if(objectp->mDrawable.notNull() && !entry->getEntry())
+ {
+ entry->setOctreeEntry(objectp->mDrawable->getEntry());
}
- entry = new LLVOCacheEntry(local_id, crc, dp);
+ if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ addActiveCacheEntry(entry);
+ }
+#endif
- mImpl->mCacheMap[local_id] = entry;
return result;
}
+LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
+{
+ if(!sVOCacheCullingEnabled)
+ {
+ return NULL;
+ }
+
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
+ removeFromVOCacheTree(entry);
+
+ return entry;
+}
+
+LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id)
+{
+ LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id);
+ if(iter != mImpl->mCacheMap.end())
+ {
+ return iter->second;
+ }
+ return NULL;
+}
+
+void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type)
+{
+#if 0
+ mCacheMissList.insert(CacheMissItem(id, miss_type));
+#else
+ mCacheMissList.push_back(CacheMissItem(id, miss_type));
+#endif
+}
+
+//check if a non-cacheable object is already created.
+bool LLViewerRegion::isNonCacheableObjectCreated(U32 local_id)
+{
+ if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end())
+ {
+ return true;
+ }
+ return false;
+}
+
+void LLViewerRegion::removeFromCreatedList(U32 local_id)
+{
+ if(mImpl && local_id > 0)
+ {
+ std::set<U32>::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id);
+ if(iter != mImpl->mNonCacheableCreatedList.end())
+ {
+ mImpl->mNonCacheableCreatedList.erase(iter);
+ }
+ }
+}
+
+void LLViewerRegion::addToCreatedList(U32 local_id)
+{
+ if(mImpl && local_id > 0)
+ {
+ mImpl->mNonCacheableCreatedList.insert(local_id);
+ }
+}
+
// Get data packer for this object, if we have cached data
// AND the CRC matches. JC
-LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
+bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type)
{
//llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18
- LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+ LLVOCacheEntry* entry = getCacheEntry(local_id);
if (entry)
{
@@ -1292,70 +2056,56 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
// Record a hit
entry->recordHit();
cache_miss_type = CACHE_MISS_TYPE_NONE;
- return entry->getDP(crc);
+ entry->setUpdateFlags(flags);
+
+ if(entry->isState(LLVOCacheEntry::ACTIVE))
+ {
+ ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags);
+ return true;
+ }
+
+ if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE))
+ {
+ return true;
+ }
+
+ decodeBoundingInfo(entry);
+ return true;
}
else
{
// llinfos << "CRC miss for " << local_id << llendl;
- cache_miss_type = CACHE_MISS_TYPE_CRC;
- mCacheMissCRC.put(local_id);
+
+ addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);
}
}
else
{
// llinfos << "Cache miss for " << local_id << llendl;
- cache_miss_type = CACHE_MISS_TYPE_FULL;
- mCacheMissFull.put(local_id);
+ addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
}
- return NULL;
+ return false;
}
void LLViewerRegion::addCacheMissFull(const U32 local_id)
{
- mCacheMissFull.put(local_id);
+ addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
}
void LLViewerRegion::requestCacheMisses()
{
- S32 full_count = mCacheMissFull.count();
- S32 crc_count = mCacheMissCRC.count();
- if (full_count == 0 && crc_count == 0) return;
+ if (!mCacheMissList.size())
+ {
+ return;
+ }
LLMessageSystem* msg = gMessageSystem;
BOOL start_new_message = TRUE;
S32 blocks = 0;
- S32 i;
-
- // Send full cache miss updates. For these, we KNOW we don't
- // have a viewer object.
- for (i = 0; i < full_count; i++)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_RequestMultipleObjects);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- start_new_message = FALSE;
- }
-
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
- msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
- blocks++;
-
- if (blocks >= 255)
- {
- sendReliableMessage();
- start_new_message = TRUE;
- blocks = 0;
- }
- }
- // Send CRC miss updates. For these, we _might_ have a viewer object,
- // but probably not.
- for (i = 0; i < crc_count; i++)
+ //send requests for all cache-missed objects
+ for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)
{
if (start_new_message)
{
@@ -1367,8 +2117,8 @@ void LLViewerRegion::requestCacheMisses()
}
msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
- msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
+ msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType);
+ msg->addU32Fast(_PREHASH_ID, (*iter).mID);
blocks++;
if (blocks >= 255)
@@ -1384,13 +2134,13 @@ void LLViewerRegion::requestCacheMisses()
{
sendReliableMessage();
}
- mCacheMissFull.reset();
- mCacheMissCRC.reset();
mCacheDirty = TRUE ;
// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
- LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count);
+ LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());
LLViewerStatsRecorder::instance().log(0.2f);
+
+ mCacheMissList.clear();
}
void LLViewerRegion::dumpCache()
@@ -1568,8 +2318,20 @@ void LLViewerRegion::unpackRegionHandshake()
msg->addUUID("AgentID", gAgent.getID());
msg->addUUID("SessionID", gAgent.getSessionID());
msg->nextBlock("RegionInfo");
- msg->addU32("Flags", 0x0 );
+
+ U32 flags = 0;
+ if(sVOCacheCullingEnabled)
+ {
+ flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects.
+ if(mImpl->mCacheMap.empty())
+ {
+ flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes.
+ }
+ }
+ msg->addU32("Flags", flags );
msg->sendReliable(host);
+
+ mRegionTimer.reset(); //reset region timer.
}
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
@@ -1587,7 +2349,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EventQueueGet");
if (gSavedSettings.getBOOL("UseHTTPInventory"))
- {
+ {
capabilityNames.append("FetchLib2");
capabilityNames.append("FetchLibDescendents2");
capabilityNames.append("FetchInventory2");
@@ -1606,7 +2368,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("LandResources");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
- capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("MeshUploadFlag");
capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ObjectMedia");
@@ -1647,7 +2409,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ViewerMetrics");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
-
+
// Please add new capabilities alphabetically to reduce
// merge conflicts.
}
@@ -1655,8 +2417,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
void LLViewerRegion::setSeedCapability(const std::string& url)
{
if (getCapability("Seed") == url)
- {
- // llwarns << "Ignoring duplicate seed capability" << llendl;
+ {
+ //llwarns << "Ignoring duplicate seed capability" << llendl;
//Instead of just returning we build up a second set of seed caps and compare them
//to the "original" seed cap received and determine why there is problem!
LLSD capabilityNames = LLSD::emptyArray();
@@ -1865,9 +2627,18 @@ void LLViewerRegion::logActiveCapabilities() const
LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
{
- if (type < mImpl->mObjectPartition.size())
+ if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE)
+ {
+ return (LLSpatialPartition*)mImpl->mObjectPartition[type];
+ }
+ return NULL;
+}
+
+LLVOCachePartition* LLViewerRegion::getVOCachePartition()
+{
+ if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())
{
- return mImpl->mObjectPartition[type];
+ return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];
}
return NULL;
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 56cd0c9ea1..29483662e8 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -34,7 +34,6 @@
#include "lldarray.h"
#include "llwind.h"
-#include "llstat.h"
#include "v3dmath.h"
#include "llstring.h"
#include "llregionflags.h"
@@ -66,8 +65,11 @@ class LLDataPacker;
class LLDataPackerBinaryBuffer;
class LLHost;
class LLBBox;
-
+class LLSpatialGroup;
+class LLDrawable;
class LLViewerRegionImpl;
+class LLviewerOctreeGroup;
+class LLVOCachePartition;
class LLViewerRegion: public LLCapabilityProvider // implements this interface
{
@@ -85,6 +87,7 @@ public:
PARTITION_VOLUME,
PARTITION_BRIDGE,
PARTITION_HUD_PARTICLE,
+ PARTITION_VO_CACHE,
PARTITION_NONE,
NUM_PARTITIONS
} eObjectPartitions;
@@ -223,6 +226,11 @@ public:
F32 getWidth() const { return mWidth; }
BOOL idleUpdate(F32 max_update_time);
+ void addVisibleGroup(LLviewerOctreeGroup* group);
+ void addVisibleCacheEntry(LLVOCacheEntry* entry);
+ void addActiveCacheEntry(LLVOCacheEntry* entry);
+ void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
+ void killCacheEntry(U32 local_id); //physically delete the cache entry
// Like idleUpdate, but forces everything to complete regardless of
// how long it takes.
@@ -315,10 +323,16 @@ public:
} eCacheUpdateResult;
// handle a full update message
- eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp);
- LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type);
+ eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags);
+ eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
+ LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
+ LLVOCacheEntry* getCacheEntry(U32 local_id);
+ bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
void requestCacheMisses();
void addCacheMissFull(const U32 local_id);
+ //remove from object cache if the object receives a full-update or terse update
+ LLViewerObject* forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp);
+ void findOrphans(U32 parent_id);
void dumpCache();
@@ -332,7 +346,9 @@ public:
virtual std::string getDescription() const;
std::string getHttpUrl() const { return mHttpUrl ;}
+ U32 getNumOfActiveCachedObjects() const;
LLSpatialPartition* getSpatialPartition(U32 type);
+ LLVOCachePartition* getVOCachePartition();
bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const;
@@ -342,7 +358,26 @@ public:
void getNeighboringRegionsStatus( std::vector<S32>& regions );
const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
-
+
+ void removeFromCreatedList(U32 local_id);
+ void addToCreatedList(U32 local_id);
+
+private:
+ void addToVOCacheTree(LLVOCacheEntry* entry);
+ LLViewerObject* addNewObject(LLVOCacheEntry* entry);
+ void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list);
+ void removeFromVOCacheTree(LLVOCacheEntry* entry);
+ void replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
+ void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry
+
+ F32 killInvisibleObjects(F32 max_time);
+ F32 createVisibleObjects(F32 max_time);
+ F32 updateVisibleEntries(F32 max_time); //update visible entries
+
+ void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type);
+ void decodeBoundingInfo(LLVOCacheEntry* entry);
+ bool isNonCacheableObjectCreated(U32 local_id);
+
public:
struct CompareDistance
{
@@ -362,9 +397,8 @@ public:
LLWind mWind;
LLViewerParcelOverlay *mParcelOverlay;
- LLStat mBitStat;
- LLStat mPacketsStat;
- LLStat mPacketsLostStat;
+ F32 mBitsReceived;
+ F32 mPacketsReceived;
LLMatrix4 mRenderMatrix;
@@ -376,8 +410,10 @@ public:
LLDynamicArray<U32> mMapAvatars;
LLDynamicArray<LLUUID> mMapAvatarIDs;
+ static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
private:
LLViewerRegionImpl * mImpl;
+ LLFrameTimer mRegionTimer;
F32 mWidth; // Width of region on a side (meters)
U64 mHandle;
@@ -423,16 +459,27 @@ private:
// a structure of size 2^14 = 16,000
BOOL mCacheLoaded;
BOOL mCacheDirty;
+ BOOL mAlive; // can become false if circuit disconnects
+ BOOL mCapabilitiesReceived;
+ BOOL mReleaseNotesRequested;
+ BOOL mDead; //if true, this region is in the process of deleting.
- LLDynamicArray<U32> mCacheMissFull;
- LLDynamicArray<U32> mCacheMissCRC;
+ typedef std::map<U32, std::vector<U32> > orphan_list_t;
+ orphan_list_t mOrphanMap;
- bool mAlive; // can become false if circuit disconnects
- bool mCapabilitiesReceived;
- caps_received_signal_t mCapabilitiesReceivedSignal;
+ class CacheMissItem
+ {
+ public:
+ CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type){}
- BOOL mReleaseNotesRequested;
+ U32 mID; //local object id
+ LLViewerRegion::eCacheMissType mType; //cache miss type
+
+ typedef std::list<CacheMissItem> cache_miss_list_t;
+ };
+ CacheMissItem::cache_miss_list_t mCacheMissList;
+ caps_received_signal_t mCapabilitiesReceivedSignal;
LLSD mSimulatorFeatures;
};
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index b9e0847935..e31d47fe93 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -90,6 +90,8 @@ LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
+LLGLSLShader gTwoTextureCompareProgram;
+LLGLSLShader gOneTextureFilterProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
LLGLSLShader gClipProgram;
@@ -711,6 +713,8 @@ void LLViewerShaderMgr::unloadShaders()
gSplatTextureRectProgram.unload();
gGlowCombineFXAAProgram.unload();
gTwoTextureAddProgram.unload();
+ gTwoTextureCompareProgram.unload();
+ gOneTextureFilterProgram.unload();
gOneTextureNoColorProgram.unload();
gSolidColorProgram.unload();
@@ -871,7 +875,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
-
+
boost::unordered_map<std::string, std::string> attribs;
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
@@ -926,7 +930,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) );
-
+
for (U32 i = 0; i < shaders.size(); i++)
{
// Note usage of GL_FRAGMENT_SHADER_ARB
@@ -1275,7 +1279,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredBumpProgram.createShader(NULL, NULL);
}
-
+
gDeferredMaterialProgram[1].mFeatures.hasLighting = false;
gDeferredMaterialProgram[5].mFeatures.hasLighting = false;
gDeferredMaterialProgram[9].mFeatures.hasLighting = false;
@@ -1710,7 +1714,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
}
-
+
if (success)
{
gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
@@ -2932,6 +2936,38 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
+ gTwoTextureCompareProgram.mShaderFiles.clear();
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureCompareProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gTwoTextureCompareProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gTwoTextureCompareProgram.bind();
+ gTwoTextureCompareProgram.uniform1i("tex0", 0);
+ gTwoTextureCompareProgram.uniform1i("tex1", 1);
+ gTwoTextureCompareProgram.uniform1i("dither_tex", 2);
+ }
+ }
+
+ if (success)
+ {
+ gOneTextureFilterProgram.mName = "One Texture Filter Shader";
+ gOneTextureFilterProgram.mShaderFiles.clear();
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gOneTextureFilterProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gOneTextureFilterProgram.bind();
+ gOneTextureFilterProgram.uniform1i("tex0", 0);
+ }
+ }
+
+ if (success)
+ {
gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
gOneTextureNoColorProgram.mShaderFiles.clear();
gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 8c7de05062..7fb90b26c6 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -233,6 +233,10 @@ extern LLGLSLShader gClipProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
+//output tex0[tc0] - tex1[tc1]
+extern LLGLSLShader gTwoTextureCompareProgram;
+//discard some fragments based on user-set color tolerance
+extern LLGLSLShader gOneTextureFilterProgram;
extern LLGLSLShader gOneTextureNoColorProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 35bba4184e..7ddee48b38 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -61,363 +61,242 @@
#include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
-
-class StatAttributes
+namespace LLStatViewer
{
-public:
- StatAttributes(const char* name,
- const BOOL enabled,
- const BOOL is_timer)
- : mName(name),
- mEnabled(enabled),
- mIsTimer(is_timer)
- {
- }
+
+LLTrace::CountStatHandle<> FPS("framesrendered"),
+ PACKETS_IN("packetsinstat"),
+ PACKETS_LOST("packetsloststat"),
+ PACKETS_OUT("packetsoutstat"),
+ TEXTURE_PACKETS("texturepacketsstat"),
+ TRIANGLES_DRAWN("trianglesdrawnstat"),
+ CHAT_COUNT("chatcount", "Chat messages sent"),
+ IM_COUNT("imcount", "IMs sent"),
+ OBJECT_CREATE("objectcreate"),
+ OBJECT_REZ("objectrez", "Object rez count"),
+ LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"),
+ LSL_SAVES("lslsaves", "Number of times user has saved a script"),
+ ANIMATION_UPLOADS("animationuploads", "Animations uploaded"),
+ FLY("fly", "Fly count"),
+ TELEPORT("teleport", "Teleport count"),
+ DELETE_OBJECT("deleteobject", "Objects deleted"),
+ SNAPSHOT("snapshot", "Snapshots taken"),
+ UPLOAD_SOUND("uploadsound", "Sounds uploaded"),
+ UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"),
+ EDIT_TEXTURE("edittexture", "Changes to textures on objects"),
+ KILLED("killed", "Number of times killed"),
+ FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"),
+ TEX_BAKES("texbakes"),
+ TEX_REBAKES("texrebakes"),
+ NUM_NEW_OBJECTS("numnewobjectsstat");
+LLTrace::CountStatHandle<LLTrace::Kibibits> KBIT("kbitstat"),
+ LAYERS_KBIT("layerskbitstat"),
+ OBJECT_KBIT("objectkbitstat"),
+ ASSET_KBIT("assetkbitstat"),
+ TEXTURE_KBIT("texturekbitstat"),
+ ACTUAL_IN_KBIT("actualinkbitstat"),
+ ACTUAL_OUT_KBIT("actualoutkbitstat");
+
+LLTrace::CountStatHandle<LLTrace::Seconds> SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"),
+ SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"),
+ LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%");
+
+SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION),
+ SIM_FPS("simfps", "", LL_SIM_STAT_FPS),
+ SIM_PHYSICS_FPS("simphysicsfps", "", LL_SIM_STAT_PHYSFPS),
+ SIM_AGENT_UPS("simagentups", "", LL_SIM_STAT_AGENTUPS),
+ SIM_SCRIPT_EPS("simscripteps", "", LL_SIM_STAT_SCRIPT_EPS),
+ SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps", "", LL_SIM_STAT_SKIPPEDAISILSTEPS_PS),
+ SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS),
+ SIM_MAIN_AGENTS("simmainagents", "", LL_SIM_STAT_NUMAGENTMAIN),
+ SIM_CHILD_AGENTS("simchildagents", "", LL_SIM_STAT_NUMAGENTCHILD),
+ SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS),
+ SIM_ACTIVE_OBJECTS("simactiveobjects", "", LL_SIM_STAT_NUMTASKSACTIVE),
+ SIM_ACTIVE_SCRIPTS("simactivescripts", "", LL_SIM_STAT_NUMSCRIPTSACTIVE),
+ SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN),
+ SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS),
+ SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS),
+ SIM_PENDING_DOWNLOADS("simpendingdownloads", "", LL_SIM_STAT_PENDING_DOWNLOADS),
+ SIM_PENDING_UPLOADS("simpendinguploads", "", LL_SIM_STAT_PENDING_UPLOADS),
+ SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads", "", LL_SIM_STAT_PENDING_LOCAL_UPLOADS),
+ SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS),
+ SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS);
+
+LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"),
+ NUM_IMAGES("numimagesstat"),
+ NUM_RAW_IMAGES("numrawimagesstat"),
+ NUM_OBJECTS("numobjectsstat"),
+ NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
+ NUM_SIZE_CULLED("numsizeculledstat"),
+ NUM_VIS_CULLED("numvisculledstat"),
+ ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"),
+ LIGHTING_DETAIL("lightingdetail", "Lighting Detail"),
+ VISIBLE_AVATARS("visibleavatars", "Visible Avatars"),
+ SHADER_OBJECTS("shaderobjects", "Object Shaders"),
+ DRAW_DISTANCE("drawdistance", "Draw Distance"),
+ PENDING_VFS_OPERATIONS("vfspendingoperations"),
+ PACKETS_LOST_PERCENT("packetslostpercentstat"),
+ WINDOW_WIDTH("windowwidth", "Window width"),
+ WINDOW_HEIGHT("windowheight", "Window height");
- std::string mName;
- BOOL mEnabled;
- BOOL mIsTimer;
-};
+static LLTrace::SampleStatHandle<S64> CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled");
-const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] =
-{
- // ST_VERSION
- StatAttributes("Version", TRUE, FALSE),
- // ST_AVATAR_EDIT_SECONDS
- StatAttributes("Seconds in Edit Appearence", FALSE, TRUE),
- // ST_TOOLBOX_SECONDS
- StatAttributes("Seconds using Toolbox", FALSE, TRUE),
- // ST_CHAT_COUNT
- StatAttributes("Chat messages sent", FALSE, FALSE),
- // ST_IM_COUNT
- StatAttributes("IMs sent", FALSE, FALSE),
- // ST_FULLSCREEN_BOOL
- StatAttributes("Fullscreen mode", FALSE, FALSE),
- // ST_RELEASE_COUNT
- StatAttributes("Object release count", FALSE, FALSE),
- // ST_CREATE_COUNT
- StatAttributes("Object create count", FALSE, FALSE),
- // ST_REZ_COUNT
- StatAttributes("Object rez count", FALSE, FALSE),
- // ST_FPS_10_SECONDS
- StatAttributes("Seconds below 10 FPS", FALSE, TRUE),
- // ST_FPS_2_SECONDS
- StatAttributes("Seconds below 2 FPS", FALSE, TRUE),
- // ST_MOUSELOOK_SECONDS
- StatAttributes("Seconds in Mouselook", FALSE, TRUE),
- // ST_FLY_COUNT
- StatAttributes("Fly count", FALSE, FALSE),
- // ST_TELEPORT_COUNT
- StatAttributes("Teleport count", FALSE, FALSE),
- // ST_OBJECT_DELETE_COUNT
- StatAttributes("Objects deleted", FALSE, FALSE),
- // ST_SNAPSHOT_COUNT
- StatAttributes("Snapshots taken", FALSE, FALSE),
- // ST_UPLOAD_SOUND_COUNT
- StatAttributes("Sounds uploaded", FALSE, FALSE),
- // ST_UPLOAD_TEXTURE_COUNT
- StatAttributes("Textures uploaded", FALSE, FALSE),
- // ST_EDIT_TEXTURE_COUNT
- StatAttributes("Changes to textures on objects", FALSE, FALSE),
- // ST_KILLED_COUNT
- StatAttributes("Number of times killed", FALSE, FALSE),
- // ST_FRAMETIME_JITTER
- StatAttributes("Average delta between sucessive frame times", FALSE, FALSE),
- // ST_FRAMETIME_SLEW
- StatAttributes("Average delta between frame time and mean", FALSE, FALSE),
- // ST_INVENTORY_TOO_LONG
- StatAttributes("Inventory took too long to load", FALSE, FALSE),
- // ST_WEARABLES_TOO_LONG
- StatAttributes("Wearables took too long to load", FALSE, FALSE),
- // ST_LOGIN_SECONDS
- StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE),
- // ST_LOGIN_TIMEOUT_COUNT
- StatAttributes("Number of login attempts that timed out", FALSE, FALSE),
- // ST_HAS_BAD_TIMER
- StatAttributes("Known bad timer if != 0.0", FALSE, FALSE),
- // ST_DOWNLOAD_FAILED
- StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE),
- // ST_LSL_SAVE_COUNT
- StatAttributes("Number of times user has saved a script", FALSE, FALSE),
- // ST_UPLOAD_ANIM_COUNT
- StatAttributes("Animations uploaded", FALSE, FALSE),
- // ST_FPS_8_SECONDS
- StatAttributes("Seconds below 8 FPS", FALSE, TRUE),
- // ST_SIM_FPS_20_SECONDS
- StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE),
- // ST_PHYS_FPS_20_SECONDS
- StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE),
- // ST_LOSS_05_SECONDS
- StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE),
- // ST_FPS_DROP_50_RATIO
- StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE),
- // ST_ENABLE_VBO
- StatAttributes("Vertex Buffers Enabled", TRUE, FALSE),
- // ST_DELTA_BANDWIDTH
- StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE),
- // ST_MAX_BANDWIDTH
- StatAttributes("Max bandwidth setting", FALSE, FALSE),
- // ST_LIGHTING_DETAIL
- StatAttributes("Lighting Detail", FALSE, FALSE),
- // ST_VISIBLE_AVATARS
- StatAttributes("Visible Avatars", FALSE, FALSE),
- // ST_SHADER_OJECTS
- StatAttributes("Object Shaders", FALSE, FALSE),
- // ST_SHADER_ENVIRONMENT
- StatAttributes("Environment Shaders", FALSE, FALSE),
- // ST_VISIBLE_DRAW_DIST
- StatAttributes("Draw Distance", FALSE, FALSE),
- // ST_VISIBLE_CHAT_BUBBLES
- StatAttributes("Chat Bubbles Enabled", FALSE, FALSE),
- // ST_SHADER_AVATAR
- StatAttributes("Avatar Shaders", FALSE, FALSE),
- // ST_FRAME_SECS
- StatAttributes("FRAME_SECS", FALSE, FALSE),
- // ST_UPDATE_SECS
- StatAttributes("UPDATE_SECS", FALSE, FALSE),
- // ST_NETWORK_SECS
- StatAttributes("NETWORK_SECS", FALSE, FALSE),
- // ST_IMAGE_SECS
- StatAttributes("IMAGE_SECS", FALSE, FALSE),
- // ST_REBUILD_SECS
- StatAttributes("REBUILD_SECS", FALSE, FALSE),
- // ST_RENDER_SECS
- StatAttributes("RENDER_SECS", FALSE, FALSE),
- // ST_CROSSING_AVG
- StatAttributes("CROSSING_AVG", FALSE, FALSE),
- // ST_CROSSING_MAX
- StatAttributes("CROSSING_MAX", FALSE, FALSE),
- // ST_LIBXUL_WIDGET_USED
- StatAttributes("LibXUL Widget used", FALSE, FALSE), // Unused
- // ST_WINDOW_WIDTH
- StatAttributes("Window width", FALSE, FALSE),
- // ST_WINDOW_HEIGHT
- StatAttributes("Window height", FALSE, FALSE),
- // ST_TEX_BAKES
- StatAttributes("Texture Bakes", FALSE, FALSE),
- // ST_TEX_REBAKES
- StatAttributes("Texture Rebakes", FALSE, FALSE)
+LLTrace::SampleStatHandle<LLTrace::Bytes> GL_TEX_MEM("gltexmemstat"),
+ GL_BOUND_MEM("glboundmemstat"),
+ RAW_MEM("rawmemstat"),
+ FORMATTED_MEM("formattedmemstat"),
+ DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
+ MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting");
-};
+
+SimMeasurement<LLTrace::Milliseconds> SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS),
+ SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS),
+ SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS),
+ SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS),
+ SIM_PHYSICS_STEP_TIME("simsimphysicsstepmsec", "", LL_SIM_STAT_SIMPHYSICSSTEPMS),
+ SIM_PHYSICS_SHAPE_UPDATE_TIME("simsimphysicsshapeupdatemsec", "", LL_SIM_STAT_SIMPHYSICSSHAPEMS),
+ SIM_PHYSICS_OTHER_TIME("simsimphysicsothermsec", "", LL_SIM_STAT_SIMPHYSICSOTHERMS),
+ SIM_AI_TIME("simsimaistepmsec", "", LL_SIM_STAT_SIMAISTEPTIMEMS),
+ SIM_AGENTS_TIME("simagentmsec", "", LL_SIM_STAT_AGENTMS),
+ SIM_IMAGES_TIME("simimagesmsec", "", LL_SIM_STAT_IMAGESMS),
+ SIM_SCRIPTS_TIME("simscriptmsec", "", LL_SIM_STAT_SCRIPTMS),
+ SIM_SPARE_TIME("simsparemsec", "", LL_SIM_STAT_SIMSPARETIME),
+ SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME),
+ SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME);
+
+SimMeasurement<LLTrace::Bytes> SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES),
+ SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY);
-LLViewerStats::LLViewerStats() :
- mKBitStat("kbitstat"),
- mLayersKBitStat("layerskbitstat"),
- mObjectKBitStat("objectkbitstat"),
- mAssetKBitStat("assetkbitstat"),
- mTextureKBitStat("texturekbitstat"),
- mVFSPendingOperations("vfspendingoperations"),
- mObjectsDrawnStat("objectsdrawnstat"),
- mObjectsCulledStat("objectsculledstat"),
- mObjectsTestedStat("objectstestedstat"),
- mObjectsComparedStat("objectscomparedstat"),
- mObjectsOccludedStat("objectsoccludedstat"),
- mFPSStat("fpsstat"),
- mPacketsInStat("packetsinstat"),
- mPacketsLostStat("packetsloststat"),
- mPacketsOutStat("packetsoutstat"),
- mPacketsLostPercentStat("packetslostpercentstat", 64),
- mTexturePacketsStat("texturepacketsstat"),
- mActualInKBitStat("actualinkbitstat"),
- mActualOutKBitStat("actualoutkbitstat"),
- mTrianglesDrawnStat("trianglesdrawnstat"),
- mSimTimeDilation("simtimedilation"),
- mSimFPS("simfps"),
- mSimPhysicsFPS("simphysicsfps"),
- mSimAgentUPS("simagentups"),
- mSimScriptEPS("simscripteps"),
- mSimFrameMsec("simframemsec"),
- mSimNetMsec("simnetmsec"),
- mSimSimOtherMsec("simsimothermsec"),
- mSimSimPhysicsMsec("simsimphysicsmsec"),
- mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
- mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
- mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
- mSimSimAIStepMsec("simsimaistepmsec"),
- mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"),
- mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"),
- mSimAgentMsec("simagentmsec"),
- mSimImagesMsec("simimagesmsec"),
- mSimScriptMsec("simscriptmsec"),
- mSimSpareMsec("simsparemsec"),
- mSimSleepMsec("simsleepmsec"),
- mSimPumpIOMsec("simpumpiomsec"),
- mSimMainAgents("simmainagents"),
- mSimChildAgents("simchildagents"),
- mSimObjects("simobjects"),
- mSimActiveObjects("simactiveobjects"),
- mSimActiveScripts("simactivescripts"),
- mSimPctScriptsRun("simpctscriptsrun"),
- mSimInPPS("siminpps"),
- mSimOutPPS("simoutpps"),
- mSimPendingDownloads("simpendingdownloads"),
- mSimPendingUploads("simpendinguploads"),
- mSimPendingLocalUploads("simpendinglocaluploads"),
- mSimTotalUnackedBytes("simtotalunackedbytes"),
- mPhysicsPinnedTasks("physicspinnedtasks"),
- mPhysicsLODTasks("physicslodtasks"),
- mPhysicsMemoryAllocated("physicsmemoryallocated"),
- mSimPingStat("simpingstat"),
- mNumImagesStat("numimagesstat", 32, TRUE),
- mNumRawImagesStat("numrawimagesstat", 32, TRUE),
- mGLTexMemStat("gltexmemstat", 32, TRUE),
- mGLBoundMemStat("glboundmemstat", 32, TRUE),
- mRawMemStat("rawmemstat", 32, TRUE),
- mFormattedMemStat("formattedmemstat", 32, TRUE),
- mNumObjectsStat("numobjectsstat"),
- mNumActiveObjectsStat("numactiveobjectsstat"),
- mNumNewObjectsStat("numnewobjectsstat"),
- mNumSizeCulledStat("numsizeculledstat"),
- mNumVisCulledStat("numvisculledstat"),
- mLastTimeDiff(0.0)
-{
- for (S32 i = 0; i < ST_COUNT; i++)
- {
- mStats[i] = 0.0;
- }
+LLTrace::SampleStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
+ FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
+ SIM_PING("simpingstat");
+
+LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections");
+
+LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load");
- if (LLTimer::knownBadTimer())
- {
- mStats[ST_HAS_BAD_TIMER] = 1.0;
- }
+LLTrace::EventStatHandle<LLTrace::Milliseconds> REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"),
+ FRAME_STACKTIME("framestacktime", "FRAME_SECS"),
+ UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"),
+ NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"),
+ IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"),
+ REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"),
+ RENDER_STACKTIME("renderstacktime", "RENDER_SECS");
- mAgentPositionSnaps.reset();
-}
+LLTrace::EventStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"),
+ TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"),
+ MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"),
+ FPS_10_TIME("fps10time", "Seconds below 10 FPS"),
+ FPS_8_TIME("fps8time", "Seconds below 8 FPS"),
+ FPS_2_TIME("fps2time", "Seconds below 2 FPS");
-LLViewerStats::~LLViewerStats()
-{
-}
-void LLViewerStats::resetStats()
-{
- LLViewerStats& stats = LLViewerStats::instance();
- stats.mKBitStat.reset();
- stats.mLayersKBitStat.reset();
- stats.mObjectKBitStat.reset();
- stats.mTextureKBitStat.reset();
- stats.mVFSPendingOperations.reset();
- stats.mAssetKBitStat.reset();
- stats.mPacketsInStat.reset();
- stats.mPacketsLostStat.reset();
- stats.mPacketsOutStat.reset();
- stats.mFPSStat.reset();
- stats.mTexturePacketsStat.reset();
- stats.mAgentPositionSnaps.reset();
}
-
-F64 LLViewerStats::getStat(EStatType type) const
+LLViewerStats::LLViewerStats()
+: mLastTimeDiff(0.0)
{
- return mStats[type];
+ mRecording.start();
+ LLTrace::get_frame_recording().start();
}
-F64 LLViewerStats::setStat(EStatType type, F64 value)
+LLViewerStats::~LLViewerStats()
{
- mStats[type] = value;
- return mStats[type];
}
-F64 LLViewerStats::incStat(EStatType type, F64 value)
+void LLViewerStats::resetStats()
{
- mStats[type] += value;
- return mStats[type];
+ LLViewerStats::instance().mRecording.reset();
}
void LLViewerStats::updateFrameStats(const F64 time_diff)
{
- if (mPacketsLostPercentStat.getCurrent() > 5.0)
+ LLTrace::Seconds time_diff_seconds(time_diff);
+ if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0)
{
- incStat(ST_LOSS_05_SECONDS, time_diff);
+ add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff_seconds);
}
- if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
+ F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS);
+ if (0.f < sim_fps && sim_fps < 20.f)
{
- incStat(ST_SIM_FPS_20_SECONDS, time_diff);
+ add(LLStatViewer::SIM_20_FPS_TIME, time_diff_seconds);
}
- if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
+ F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS);
+
+ if (0.f < sim_physics_fps && sim_physics_fps < 20.f)
{
- incStat(ST_PHYS_FPS_20_SECONDS, time_diff);
+ add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff_seconds);
}
if (time_diff >= 0.5)
{
- incStat(ST_FPS_2_SECONDS, time_diff);
+ record(LLStatViewer::FPS_2_TIME, time_diff_seconds);
}
if (time_diff >= 0.125)
{
- incStat(ST_FPS_8_SECONDS, time_diff);
+ record(LLStatViewer::FPS_8_TIME, time_diff_seconds);
}
if (time_diff >= 0.1)
{
- incStat(ST_FPS_10_SECONDS, time_diff);
+ record(LLStatViewer::FPS_10_TIME, time_diff_seconds);
}
if (gFrameCount && mLastTimeDiff > 0.0)
{
// new "stutter" meter
- setStat(ST_FPS_DROP_50_RATIO,
- (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
- (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
-
+ add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);
// old stats that were never really used
- setStat(ST_FRAMETIME_JITTER,
- (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
- fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
+ sample(LLStatViewer::FRAMETIME_JITTER, LLTrace::Milliseconds(mLastTimeDiff - time_diff));
F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
- setStat(ST_FRAMETIME_SLEW,
- (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
- fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
+ sample(LLStatViewer::FRAMETIME_SLEW, LLTrace::Milliseconds(average_frametime - time_diff));
F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
- setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
-
- setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
-
+ sample(LLStatViewer::DELTA_BANDWIDTH, LLTrace::Bits(delta_bandwidth));
+ sample(LLStatViewer::MAX_BANDWIDTH, LLTrace::Bits(max_bandwidth));
}
mLastTimeDiff = time_diff;
-
}
-void LLViewerStats::addToMessage(LLSD &body) const
+void LLViewerStats::addToMessage(LLSD &body)
{
LLSD &misc = body["misc"];
- for (S32 i = 0; i < ST_COUNT; i++)
- {
- if (STAT_INFO[i].mEnabled)
- {
- // TODO: send timer value so dataserver can normalize
- misc[STAT_INFO[i].mName] = mStats[i];
- llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i]
- << llendl;
- }
- }
+ misc["Version"] = TRUE;
+ //TODO RN: get last value, not mean
+ misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO);
- body["AgentPositionSnaps"] = mAgentPositionSnaps.getData();
- llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev()
- << "; Count = " << mAgentPositionSnaps.getCount() << llendl;
+ body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD();
+ llinfos << "STAT: AgentPositionSnaps: Mean = " << getRecording().getMean(LLStatViewer::AGENT_POSITION_SNAP).value() << "; StdDev = " << getRecording().getStandardDeviation(LLStatViewer::AGENT_POSITION_SNAP).value()
+ << "; Count = " << getRecording().getSampleCount(LLStatViewer::AGENT_POSITION_SNAP) << llendl;
}
// *NOTE:Mani The following methods used to exist in viewer.cpp
// Moving them here, but not merging them into LLViewerStats yet.
-U32 gTotalLandIn = 0, gTotalLandOut = 0;
-U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
-
-F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
-F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
-F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
-
-
-
-U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
-U32 gObjectBits = 0;
+U32 gTotalLandIn = 0,
+ gTotalLandOut = 0,
+ gTotalWaterIn = 0,
+ gTotalWaterOut = 0;
+
+F32 gAveLandCompression = 0.f,
+ gAveWaterCompression = 0.f,
+ gBestLandCompression = 1.f,
+ gBestWaterCompression = 1.f,
+ gWorstLandCompression = 0.f,
+ gWorstWaterCompression = 0.f;
+
+LLUnit<U32, LLUnits::Bytes> gTotalWorldData = 0,
+ gTotalObjectData = 0,
+ gTotalTextureData = 0;
+U32 gSimPingCount = 0;
+LLUnit<U32, LLUnits::Bits> gObjectData = 0;
F32 gAvgSimPing = 0.f;
-U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};
+LLUnit<U32, LLUnits::Bytes> gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};
extern U32 gVisCompared;
extern U32 gVisTested;
@@ -426,59 +305,68 @@ LLFrameTimer gTextureTimer;
void update_statistics()
{
- gTotalWorldBytes += gVLManager.getTotalBytes();
- gTotalObjectBytes += gObjectBits / 8;
-
- LLViewerStats& stats = LLViewerStats::instance();
+ gTotalWorldData += gVLManager.getTotalBytes();
+ gTotalObjectData += gObjectData;
// make sure we have a valid time delta for this frame
if (gFrameIntervalSeconds > 0.f)
{
if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
+ record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds);
}
else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
+ record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds);
}
else if (LLFloaterReg::instanceVisible("build"))
{
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
+ record(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds);
}
}
- stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
- stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
- stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
- stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
-
- stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
- F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
- F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
- stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
- stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
- stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
- stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
- stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
+
+ LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
+
+ sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+ sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
+ sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip"));
+ sample(LLStatViewer::CHAT_BUBBLES, gSavedSettings.getBOOL("UseChatBubbles"));
+
+ typedef LLInstanceTracker<LLTrace::TraceType<LLTrace::TimeBlockAccumulator>, std::string> trace_type_t;
+
+ LLUnit<F64, LLUnits::Seconds> idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle"));
+ LLUnit<F64, LLUnits::Seconds> network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network"));
+
+ record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame")));
+ record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs);
+ record(LLStatViewer::NETWORK_STACKTIME, network_secs);
+ record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Update Images")));
+ record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Sort Draw State")));
+ record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Render Geometry")));
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
if (cdp)
{
- stats.mSimPingStat.addValue(cdp->getPingDelay());
+ sample(LLStatViewer::SIM_PING, LLTrace::Milliseconds(cdp->getPingDelay()));
gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
gSimPingCount++;
}
else
{
- stats.mSimPingStat.addValue(10000);
+ sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10));
+ }
+
+ if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS))
+ {
+ sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS));
}
+ add(LLStatViewer::FPS, 1);
- stats.mFPSStat.addValue(1);
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
- stats.mLayersKBitStat.addValue(layer_bits/1024.f);
- stats.mObjectKBitStat.addValue(gObjectBits/1024.f);
- stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
- stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
+ add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits));
+ add(LLStatViewer::OBJECT_KBIT, gObjectData);
+ sample(LLStatViewer::PENDING_VFS_OPERATIONS, LLVFile::getVFSThread()->getPending());
+ add(LLStatViewer::ASSET_KBIT, LLTrace::Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET)));
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
@@ -499,14 +387,14 @@ void update_statistics()
visible_avatar_frames = 1.f;
avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
}
- stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
+ sample(LLStatViewer::VISIBLE_AVATARS, (F64)avg_visible_avatars);
}
LLWorld::getInstance()->updateNetStats();
LLWorld::getInstance()->requestCacheMisses();
// Reset all of these values.
gVLManager.resetBitCounts();
- gObjectBits = 0;
+ gObjectData = 0;
// gDecodedBits = 0;
// Only update texture stats periodically so that they are less noisy
@@ -515,11 +403,7 @@ void update_statistics()
static LLFrameTimer texture_stats_timer;
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
{
- stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
- stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
- gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
- LLViewerTextureList::sTextureBits = 0;
- LLViewerTextureList::sTexturePackets = 0;
+ gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT));
texture_stats_timer.reset();
}
}
@@ -668,9 +552,9 @@ void send_stats()
LLSD &download = body["downloads"];
- download["world_kbytes"] = gTotalWorldBytes / 1024.0;
- download["object_kbytes"] = gTotalObjectBytes / 1024.0;
- download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
+ download["world_kbytes"] = LLTrace::Kibibytes(gTotalWorldData).value();
+ download["object_kbytes"] = LLTrace::Kibibytes(gTotalObjectData).value();
+ download["texture_kbytes"] = LLTrace::Kibibytes(gTotalTextureData).value();
download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0;
LLSD &in = body["stats"]["net"]["in"];
@@ -775,7 +659,7 @@ void LLViewerStats::PhaseMap::clearPhases()
mPhaseMap.clear();
}
-LLSD LLViewerStats::PhaseMap::dumpPhases()
+LLSD LLViewerStats::PhaseMap::asLLSD()
{
LLSD result;
for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 6b2461be41..4e48a61264 100755
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -1,5 +1,5 @@
/**
- * @file llviewerstats.h
+ * @file llviewerim_peningtats.h
* @brief LLViewerStats class header file
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
@@ -27,171 +27,187 @@
#ifndef LL_LLVIEWERSTATS_H
#define LL_LLVIEWERSTATS_H
-#include "llstat.h"
+#include "llstatenums.h"
#include "lltextureinfo.h"
+#include "lltracerecording.h"
+#include "lltrace.h"
+
+namespace LLStatViewer
+{
+
+struct SimMeasurementSampler : public LLInstanceTracker<SimMeasurementSampler, ESimStatID>
+{
+ SimMeasurementSampler(ESimStatID id)
+ : LLInstanceTracker<SimMeasurementSampler, ESimStatID>(id)
+ {}
+ virtual ~SimMeasurementSampler() {}
+
+ virtual void sample(F64 value) = 0;
+};
+
+template<typename T = F64>
+struct SimMeasurement : public LLTrace::SampleStatHandle<T>, public SimMeasurementSampler
+{
+ SimMeasurement(const char* name, const char* description, ESimStatID stat_id)
+ : LLTrace::SampleStatHandle<T>(name, description),
+ SimMeasurementSampler(stat_id)
+ {}
+
+ using SimMeasurementSampler::getInstance;
+
+ /*virtual*/ void sample(F64 value)
+ {
+ LLTrace::sample(*this, value);
+ }
+};
+
+template<typename T, typename VALUE_T>
+void sample(SimMeasurement<T>& measurement, VALUE_T value)
+{
+ LLTrace::sample(measurement, value);
+}
+
+extern LLTrace::CountStatHandle<> FPS,
+ PACKETS_IN,
+ PACKETS_LOST,
+ PACKETS_OUT,
+ TEXTURE_PACKETS,
+ TRIANGLES_DRAWN,
+ CHAT_COUNT,
+ IM_COUNT,
+ OBJECT_CREATE,
+ OBJECT_REZ,
+ LOGIN_TIMEOUTS,
+ LSL_SAVES,
+ ANIMATION_UPLOADS,
+ FLY,
+ TELEPORT,
+ DELETE_OBJECT,
+ SNAPSHOT,
+ UPLOAD_SOUND,
+ UPLOAD_TEXTURE,
+ EDIT_TEXTURE,
+ KILLED,
+ FRAMETIME_DOUBLED,
+ TEX_BAKES,
+ TEX_REBAKES,
+ NUM_NEW_OBJECTS;
+
+
+extern LLTrace::CountStatHandle<LLTrace::Kibibits> KBIT,
+ LAYERS_KBIT,
+ OBJECT_KBIT,
+ ASSET_KBIT,
+ TEXTURE_KBIT,
+ ACTUAL_IN_KBIT,
+ ACTUAL_OUT_KBIT;
+
+extern LLTrace::CountStatHandle<LLTrace::Seconds> SIM_20_FPS_TIME,
+ SIM_PHYSICS_20_FPS_TIME,
+ LOSS_5_PERCENT_TIME;
+
+extern SimMeasurement<> SIM_TIME_DILATION,
+ SIM_FPS,
+ SIM_PHYSICS_FPS,
+ SIM_AGENT_UPS,
+ SIM_SCRIPT_EPS,
+ SIM_SKIPPED_SILHOUETTE,
+ SIM_SKIPPED_CHARACTERS_PERCENTAGE,
+ SIM_MAIN_AGENTS,
+ SIM_CHILD_AGENTS,
+ SIM_OBJECTS,
+ SIM_ACTIVE_OBJECTS,
+ SIM_ACTIVE_SCRIPTS,
+ SIM_PERCENTAGE_SCRIPTS_RUN,
+ SIM_IN_PACKETS_PER_SEC,
+ SIM_OUT_PACKETS_PER_SEC,
+ SIM_PENDING_DOWNLOADS,
+ SIM_PENDING_UPLOADS,
+ SIM_PENDING_LOCAL_UPLOADS,
+ SIM_PHYSICS_PINNED_TASKS,
+ SIM_PHYSICS_LOD_TASKS;
+
+extern LLTrace::SampleStatHandle<> FPS_SAMPLE,
+ NUM_IMAGES,
+ NUM_RAW_IMAGES,
+ NUM_OBJECTS,
+ NUM_ACTIVE_OBJECTS,
+ NUM_SIZE_CULLED,
+ NUM_VIS_CULLED,
+ ENABLE_VBO,
+ LIGHTING_DETAIL,
+ VISIBLE_AVATARS,
+ SHADER_OBJECTS,
+ DRAW_DISTANCE,
+ PENDING_VFS_OPERATIONS,
+ PACKETS_LOST_PERCENT,
+ WINDOW_WIDTH,
+ WINDOW_HEIGHT;
+
+extern LLTrace::SampleStatHandle<LLTrace::Bytes> DELTA_BANDWIDTH,
+ MAX_BANDWIDTH,
+ GL_TEX_MEM,
+ GL_BOUND_MEM,
+ RAW_MEM,
+ FORMATTED_MEM;
+
+extern SimMeasurement<LLTrace::Milliseconds> SIM_FRAME_TIME,
+ SIM_NET_TIME,
+ SIM_OTHER_TIME,
+ SIM_PHYSICS_TIME,
+ SIM_PHYSICS_STEP_TIME,
+ SIM_PHYSICS_SHAPE_UPDATE_TIME,
+ SIM_PHYSICS_OTHER_TIME,
+ SIM_AI_TIME,
+ SIM_AGENTS_TIME,
+ SIM_IMAGES_TIME,
+ SIM_SCRIPTS_TIME,
+ SIM_SPARE_TIME,
+ SIM_SLEEP_TIME,
+ SIM_PUMP_IO_TIME;
+
+extern SimMeasurement<LLTrace::Bytes> SIM_UNACKED_BYTES,
+ SIM_PHYSICS_MEM;
+
+
+extern LLTrace::SampleStatHandle<LLTrace::Milliseconds> FRAMETIME_JITTER,
+ FRAMETIME_SLEW,
+ SIM_PING;
+
+extern LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP;
+
+extern LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY;
+
+extern LLTrace::EventStatHandle<LLTrace::Milliseconds> REGION_CROSSING_TIME,
+ FRAME_STACKTIME,
+ UPDATE_STACKTIME,
+ NETWORK_STACKTIME,
+ IMAGE_STACKTIME,
+ REBUILD_STACKTIME,
+ RENDER_STACKTIME;
+
+extern LLTrace::EventStatHandle<LLTrace::Seconds> AVATAR_EDIT_TIME,
+ TOOLBOX_TIME,
+ MOUSELOOK_TIME,
+ FPS_10_TIME,
+ FPS_8_TIME,
+ FPS_2_TIME;
+
+}
class LLViewerStats : public LLSingleton<LLViewerStats>
{
public:
- LLStat mKBitStat,
- mLayersKBitStat,
- mObjectKBitStat,
- mAssetKBitStat,
- mTextureKBitStat,
- mVFSPendingOperations,
- mObjectsDrawnStat,
- mObjectsCulledStat,
- mObjectsTestedStat,
- mObjectsComparedStat,
- mObjectsOccludedStat,
- mFPSStat,
- mPacketsInStat,
- mPacketsLostStat,
- mPacketsOutStat,
- mPacketsLostPercentStat,
- mTexturePacketsStat,
- mActualInKBitStat, // From the packet ring (when faking a bad connection)
- mActualOutKBitStat, // From the packet ring (when faking a bad connection)
- mTrianglesDrawnStat;
-
- // Simulator stats
- LLStat mSimTimeDilation,
-
- mSimFPS,
- mSimPhysicsFPS,
- mSimAgentUPS,
- mSimScriptEPS,
-
- mSimFrameMsec,
- mSimNetMsec,
- mSimSimOtherMsec,
- mSimSimPhysicsMsec,
-
- mSimSimPhysicsStepMsec,
- mSimSimPhysicsShapeUpdateMsec,
- mSimSimPhysicsOtherMsec,
- mSimSimAIStepMsec,
- mSimSimSkippedSilhouetteSteps,
- mSimSimPctSteppedCharacters,
-
- mSimAgentMsec,
- mSimImagesMsec,
- mSimScriptMsec,
- mSimSpareMsec,
- mSimSleepMsec,
- mSimPumpIOMsec,
-
- mSimMainAgents,
- mSimChildAgents,
- mSimObjects,
- mSimActiveObjects,
- mSimActiveScripts,
- mSimPctScriptsRun,
-
- mSimInPPS,
- mSimOutPPS,
- mSimPendingDownloads,
- mSimPendingUploads,
- mSimPendingLocalUploads,
- mSimTotalUnackedBytes,
-
- mPhysicsPinnedTasks,
- mPhysicsLODTasks,
- mPhysicsMemoryAllocated,
-
- mSimPingStat,
-
- mNumImagesStat,
- mNumRawImagesStat,
- mGLTexMemStat,
- mGLBoundMemStat,
- mRawMemStat,
- mFormattedMemStat,
-
- mNumObjectsStat,
- mNumActiveObjectsStat,
- mNumNewObjectsStat,
- mNumSizeCulledStat,
- mNumVisCulledStat;
-
void resetStats();
+
public:
- // If you change this, please also add a corresponding text label in llviewerstats.cpp
- enum EStatType
- {
- ST_VERSION = 0,
- ST_AVATAR_EDIT_SECONDS = 1,
- ST_TOOLBOX_SECONDS = 2,
- ST_CHAT_COUNT = 3,
- ST_IM_COUNT = 4,
- ST_FULLSCREEN_BOOL = 5,
- ST_RELEASE_COUNT= 6,
- ST_CREATE_COUNT = 7,
- ST_REZ_COUNT = 8,
- ST_FPS_10_SECONDS = 9,
- ST_FPS_2_SECONDS = 10,
- ST_MOUSELOOK_SECONDS = 11,
- ST_FLY_COUNT = 12,
- ST_TELEPORT_COUNT = 13,
- ST_OBJECT_DELETE_COUNT = 14,
- ST_SNAPSHOT_COUNT = 15,
- ST_UPLOAD_SOUND_COUNT = 16,
- ST_UPLOAD_TEXTURE_COUNT = 17,
- ST_EDIT_TEXTURE_COUNT = 18,
- ST_KILLED_COUNT = 19,
- ST_FRAMETIME_JITTER = 20,
- ST_FRAMETIME_SLEW = 21,
- ST_INVENTORY_TOO_LONG = 22,
- ST_WEARABLES_TOO_LONG = 23,
- ST_LOGIN_SECONDS = 24,
- ST_LOGIN_TIMEOUT_COUNT = 25,
- ST_HAS_BAD_TIMER = 26,
- ST_DOWNLOAD_FAILED = 27,
- ST_LSL_SAVE_COUNT = 28,
- ST_UPLOAD_ANIM_COUNT = 29,
- ST_FPS_8_SECONDS = 30,
- ST_SIM_FPS_20_SECONDS = 31,
- ST_PHYS_FPS_20_SECONDS = 32,
- ST_LOSS_05_SECONDS = 33,
- ST_FPS_DROP_50_RATIO = 34,
- ST_ENABLE_VBO = 35,
- ST_DELTA_BANDWIDTH = 36,
- ST_MAX_BANDWIDTH = 37,
- ST_LIGHTING_DETAIL = 38,
- ST_VISIBLE_AVATARS = 39,
- ST_SHADER_OBJECTS = 40,
- ST_SHADER_ENVIRONMENT = 41,
- ST_DRAW_DIST = 42,
- ST_CHAT_BUBBLES = 43,
- ST_SHADER_AVATAR = 44,
- ST_FRAME_SECS = 45,
- ST_UPDATE_SECS = 46,
- ST_NETWORK_SECS = 47,
- ST_IMAGE_SECS = 48,
- ST_REBUILD_SECS = 49,
- ST_RENDER_SECS = 50,
- ST_CROSSING_AVG = 51,
- ST_CROSSING_MAX = 52,
- ST_LIBXUL_WIDGET_USED = 53, // Unused
- ST_WINDOW_WIDTH = 54,
- ST_WINDOW_HEIGHT = 55,
- ST_TEX_BAKES = 56,
- ST_TEX_REBAKES = 57,
-
- ST_COUNT = 58
- };
LLViewerStats();
~LLViewerStats();
- // all return latest value of given stat
- F64 getStat(EStatType type) const;
- F64 setStat(EStatType type, F64 value); // set the stat to value
- F64 incStat(EStatType type, F64 value = 1.f); // add value to the stat
-
void updateFrameStats(const F64 time_diff);
- void addToMessage(LLSD &body) const;
+ void addToMessage(LLSD &body);
struct StatsAccumulator
{
@@ -263,7 +279,7 @@ public:
mCountOfNextUpdatesToIgnore = 0;
}
- inline LLSD getData() const
+ inline LLSD asLLSD() const
{
LLSD data;
data["mean"] = getMean();
@@ -275,8 +291,6 @@ public:
}
};
- StatsAccumulator mAgentPositionSnaps;
-
// Phase tracking (originally put in for avatar rezzing), tracking
// progress of active/completed phases for activities like outfit changing.
typedef std::map<std::string,LLFrameTimer> phase_map_t;
@@ -294,16 +308,18 @@ public:
void stopPhase(const std::string& phase_name);
void stopAllPhases();
void clearPhases();
- LLSD dumpPhases();
+ LLSD asLLSD();
static StatsAccumulator& getPhaseStats(const std::string& phase_name);
static void recordPhaseStat(const std::string& phase_name, F32 value);
phase_map_t::iterator begin() { return mPhaseMap.begin(); }
phase_map_t::iterator end() { return mPhaseMap.end(); }
};
+ LLTrace::Recording& getRecording() { return mRecording; }
+ const LLTrace::Recording& getRecording() const { return mRecording; }
private:
- F64 mStats[ST_COUNT];
+ LLTrace::Recording mRecording;
F64 mLastTimeDiff; // used for time stat updates
};
@@ -315,7 +331,7 @@ void update_statistics();
void send_stats();
extern LLFrameTimer gTextureTimer;
-extern U32 gTotalTextureBytes;
-extern U32 gTotalObjectBytes;
-extern U32 gTotalTextureBytesPerBoostLevel[] ;
+extern LLUnit<U32, LLUnits::Bytes> gTotalTextureData;
+extern LLUnit<U32, LLUnits::Bytes> gTotalObjectData;
+extern LLUnit<U32, LLUnits::Bytes> gTotalTextureBytesPerBoostLevel[] ;
#endif // LL_LLVIEWERSTATS_H
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index 2b3e293229..0e78bdc04c 100755
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -225,7 +225,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
}
else
{
- llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
+ //llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
return;
}
}
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
index 777e1f9c76..4cd4375146 100755
--- a/indra/newview/llviewertexlayer.cpp
+++ b/indra/newview/llviewertexlayer.cpp
@@ -364,7 +364,7 @@ void LLViewerTexLayerSetBuffer::doUpload()
{
LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->getBodyRegionName() << llendl;
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+ add(LLStatViewer::TEX_BAKES, 1);
// Don't need caches since we're baked now. (note: we won't *really* be baked
// until this image is sent to the server and the Avatar Appearance message is received.)
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 6cc9f4ace1..2872c277b1 100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -63,6 +63,11 @@
#include "lltexturecache.h"
///////////////////////////////////////////////////////////////////////////////
+// extern
+const LLUnit<S32, LLUnits::Mibibytes> gMinVideoRam = 32;
+const LLUnit<S32, LLUnits::Mibibytes> gMaxVideoRam = 512;
+
+
// statics
LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL;
@@ -82,11 +87,11 @@ S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
-S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0;
-S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0;
-S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
-S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
-S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
+LLUnit<S32, LLUnits::Bytes> LLViewerTexture::sBoundTextureMemory = 0;
+LLUnit<S32, LLUnits::Bytes> LLViewerTexture::sTotalTextureMemory = 0;
+LLUnit<S32, LLUnits::Mibibytes> LLViewerTexture::sMaxBoundTextureMem = 0;
+LLUnit<S32, LLUnits::Mibibytes> LLViewerTexture::sMaxTotalTextureMem = 0;
+LLUnit<S32, LLUnits::Bytes> LLViewerTexture::sMaxDesiredTextureMem = 0 ;
S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ;
F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
@@ -275,7 +280,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
}
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
- const std::string& filename,
+ const std::string& filename,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -288,7 +293,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
}
//static
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -395,7 +400,7 @@ void LLViewerTextureManager::init()
LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
LLViewerTexture::initClass() ;
-
+
// Create a texture manager bridge.
gTextureManagerBridgep = new LLViewerTextureManagerBridge;
@@ -526,17 +531,17 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
LLViewerMediaTexture::updateClass() ;
}
- sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
- sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
- sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB
- sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB
- sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small.
+ sBoundTextureMemory = LLImageGL::sBoundTextureMemory;//in bytes
+ sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;//in bytes
+ sMaxBoundTextureMem = gTextureList.getMaxResidentTexMem();//in MB
+ sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem() ;//in MB
+ sMaxDesiredTextureMem = sMaxTotalTextureMem ; //in Bytes, by default and when total used texture memory is small.
- if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes ||
- BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes)
+ if (sBoundTextureMemory >= sMaxBoundTextureMem ||
+ sTotalTextureMemory >= sMaxTotalTextureMem)
{
- //when texture memory overflows, lower down the threashold to release the textures more aggressively.
- sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB
+ //when texture memory overflows, lower down the threshold to release the textures more aggressively.
+ sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit<S32, LLUnits::Bytes>(gMaxVideoRam));
// If we are using more texture memory than we should,
// scale up the desired discard level
@@ -552,8 +557,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
sEvaluationTimer.reset();
}
else if (sDesiredDiscardBias > 0.0f &&
- BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale &&
- BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale)
+ sBoundTextureMemory < sMaxBoundTextureMem * texmem_lower_bound_scale &&
+ sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale)
{
// If we are using less texture memory than we should,
// scale down the desired discard level
@@ -564,14 +569,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
-
+
F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
- LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&
- (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ;
+ LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMem * texmem_middle_bound_scale) &&
+ (sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale) ;
}
//end of static functions
@@ -681,6 +686,30 @@ void LLViewerTexture::setBoostLevel(S32 level)
{
mSelectedTime = gFrameTimeSeconds;
}
+
+}
+
+bool LLViewerTexture::isActiveFetching()
+{
+ return false;
+}
+
+bool LLViewerTexture::bindDebugImage(const S32 stage)
+{
+ if (stage < 0) return false;
+
+ bool res = true;
+ if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get()))
+ {
+ res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep);
+ }
+
+ if(!res)
+ {
+ return bindDefaultImage(stage);
+ }
+
+ return res;
}
bool LLViewerTexture::bindDefaultImage(S32 stage)
@@ -865,16 +894,16 @@ void LLViewerTexture::reorganizeFaceList()
if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
{
- return;
+ return ;
}
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
if(mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
- {
- return ;
- }
-
+ {
+ return ;
+ }
+
mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i], mFaceList[i].end());
}
@@ -1207,7 +1236,7 @@ void LLViewerFetchedTexture::destroyTexture()
{
return ;
}
-
+
//LL_DEBUGS("Avatar") << mID << llendl;
destroyGLTexture() ;
mFullyLoaded = FALSE ;
@@ -1229,7 +1258,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
llassert(mNumFaces[j] <= mFaceList[j].size());
for(U32 i = 0 ; i < mNumFaces[j]; i++)
- {
+ {
mFaceList[j][i]->dirtyTexture() ;
}
}
@@ -1375,7 +1404,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+ res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
setActive() ;
@@ -1666,31 +1695,31 @@ void LLViewerFetchedTexture::updateVirtualSize()
}
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
+ {
llassert(mNumFaces[ch] <= mFaceList[ch].size());
for(U32 i = 0 ; i < mNumFaces[ch]; i++)
{
LLFace* facep = mFaceList[ch][i] ;
- if( facep )
+ if( facep )
+ {
+ LLDrawable* drawable = facep->getDrawable();
+ if (drawable)
{
- LLDrawable* drawable = facep->getDrawable();
- if (drawable)
+ if(drawable->isRecentlyVisible())
{
- if(drawable->isRecentlyVisible())
+ if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
+ drawable->getVObj() && drawable->getVObj()->isSelected())
{
- if (getBoostLevel() == LLViewerTexture::BOOST_NONE &&
- drawable->getVObj() && drawable->getVObj()->isSelected())
- {
- setBoostLevel(LLViewerTexture::BOOST_SELECTED);
- }
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
+ setBoostLevel(LLViewerTexture::BOOST_SELECTED);
}
+ addTextureStats(facep->getVirtualSize()) ;
+ setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
}
}
}
}
+ }
//reset whether or not a face was selected after 10 seconds
const F32 SELECTION_RESET_TIME = 10.f;
@@ -1740,6 +1769,13 @@ bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level)
return true;
}
+bool LLViewerFetchedTexture::isActiveFetching()
+{
+ static LLCachedControl<bool> monitor_enabled(gSavedSettings,"DebugShowTextureInfo");
+
+ return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.
+}
+
bool LLViewerFetchedTexture::updateFetch()
{
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
@@ -2916,13 +2952,13 @@ void LLViewerLODTexture::processTextureStats()
scaleDown() ;
}
// Limit the amount of GL memory bound each frame
- else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
+ else if ( sBoundTextureMemory > sMaxBoundTextureMem * texmem_middle_bound_scale &&
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown() ;
}
// Only allow GL to have 2x the video card memory
- else if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale &&
+ else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale &&
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown() ;
@@ -3125,12 +3161,12 @@ BOOL LLViewerMediaTexture::findFaces()
{
const ll_face_list_t* face_list = tex->getFaceList(ch) ;
U32 end = tex->getNumFaces(ch) ;
- for(U32 i = 0 ; i < end ; i++)
- {
- mMediaFaceList.push_back((*face_list)[i]) ;
- }
+ for(U32 i = 0 ; i < end ; i++)
+ {
+ mMediaFaceList.push_back((*face_list)[i]) ;
}
}
+ }
if(!mMediaImplp)
{
@@ -3273,9 +3309,9 @@ void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
for (U32 ch = 0; ch < 3; ++ch)
{
- //
- //we have some trouble here: the texture of the face is changed.
- //we need to find the former texture, and remove it from the list to avoid memory leaking.
+ //
+ //we have some trouble here: the texture of the face is changed.
+ //we need to find the former texture, and remove it from the list to avoid memory leaking.
llassert(mNumFaces[ch] <= mFaceList[ch].size());
@@ -3451,12 +3487,12 @@ F32 LLViewerMediaTexture::getMaxVirtualSize()
for(U32 i = 0 ; i < mNumFaces[ch] ; i++)
{
LLFace* facep = mFaceList[ch][i] ;
- if(facep->getDrawable()->isRecentlyVisible())
- {
- addTextureStats(facep->getVirtualSize()) ;
- }
- }
- }
+ if(facep->getDrawable()->isRecentlyVisible())
+ {
+ addTextureStats(facep->getVirtualSize()) ;
+ }
+ }
+ }
}
else //media is not in playing
{
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index c96f89017f..6948c6699b 100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -34,13 +34,12 @@
#include "llgltypes.h"
#include "llrender.h"
#include "llmetricperformancetester.h"
-#include "llface.h"
#include <map>
#include <list>
-#define MIN_VIDEO_RAM_IN_MEGA_BYTES 32
-#define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons.
+extern const LLUnit<S32, LLUnits::Mibibytes> gMinVideoRam;
+extern const LLUnit<S32, LLUnits::Mibibytes> gMaxVideoRam;
class LLImageGL ;
class LLImageRaw;
@@ -101,7 +100,7 @@ public:
INVALID_TEXTURE_TYPE
};
- typedef std::vector<LLFace*> ll_face_list_t;
+ typedef std::vector<class LLFace*> ll_face_list_t;
typedef std::vector<LLVOVolume*> ll_volume_list_t;
@@ -123,7 +122,9 @@ public:
virtual void dump(); // debug info to llinfos
/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
+ /*virtual*/ bool bindDebugImage(const S32 stage = 0) ;
/*virtual*/ void forceImmediateUpdate() ;
+ /*virtual*/ bool isActiveFetching();
/*virtual*/ const LLUUID& getID() const { return mID; }
void setBoostLevel(S32 level);
@@ -204,11 +205,11 @@ public:
static LLFrameTimer sEvaluationTimer;
static F32 sDesiredDiscardBias;
static F32 sDesiredDiscardScale;
- static S32 sBoundTextureMemoryInBytes;
- static S32 sTotalTextureMemoryInBytes;
- static S32 sMaxBoundTextureMemInMegaBytes;
- static S32 sMaxTotalTextureMemInMegaBytes;
- static S32 sMaxDesiredTextureMemInBytes ;
+ static LLUnit<S32, LLUnits::Bytes> sBoundTextureMemory;
+ static LLUnit<S32, LLUnits::Bytes> sTotalTextureMemory;
+ static LLUnit<S32, LLUnits::Mibibytes> sMaxBoundTextureMem;
+ static LLUnit<S32, LLUnits::Mibibytes> sMaxTotalTextureMem;
+ static LLUnit<S32, LLUnits::Bytes> sMaxDesiredTextureMem ;
static S8 sCameraMovingDiscardBias;
static F32 sCameraMovingBias;
static S32 sMaxSculptRez ;
@@ -216,7 +217,7 @@ public:
static S32 sMaxSmallImageSize ;
static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
static F32 sCurrentTime ;
-
+
enum EDebugTexels
{
DEBUG_TEXELS_OFF,
@@ -396,12 +397,15 @@ public:
void loadFromFastCache();
void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
bool isInFastCacheList() { return mInFastCacheList; }
+
+ /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline.
+
protected:
/*virtual*/ void switchToCachedImage();
S32 getCurrentDiscardLevelForFetching() ;
private:
- void init(bool firstinit) ;
+ void init(bool firstinit) ;
void cleanup() ;
void saveRawImage() ;
@@ -443,7 +447,7 @@ protected:
S8 mHasFetcher; // We've made a fecth request
S8 mIsFetching; // Fetch request is active
bool mCanUseHTTP ; //This texture can be fetched through http if true.
-
+
FTType mFTType; // What category of image is this - map tile, server bake, etc?
mutable S8 mIsMissingAsset; // True if we know that there is no image asset with this image id in the database.
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d9f3548a29..5003ec7e7b 100755
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -58,21 +58,14 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llxuiparser.h"
+#include "lltracerecording.h"
#include "llviewerdisplay.h"
-
+#include "llstartup.h"
////////////////////////////////////////////////////////////////////////////
void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
-U32 LLViewerTextureList::sTextureBits = 0;
-U32 LLViewerTextureList::sTexturePackets = 0;
S32 LLViewerTextureList::sNumImages = 0;
-LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE);
-LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE);
-LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE);
-LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE);
-LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE);
-LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE);
LLViewerTextureList gTextureList;
static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images");
@@ -327,7 +320,7 @@ void LLViewerTextureList::restoreGL()
///////////////////////////////////////////////////////////////////////////////
-LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -379,7 +372,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
}
LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
-
+
if (!imagep.isNull())
{
LLViewerFetchedTexture *texture = imagep.get();
@@ -435,7 +428,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
}
-LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -478,7 +471,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
{
llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;
}
-
+
}
if (imagep.isNull())
{
@@ -491,7 +484,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
}
//when this function is called, there is no such texture in the gTextureList with image_id.
-LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
FTType f_type,
BOOL usemipmaps,
LLViewerTexture::EBoostLevel boost_priority,
@@ -652,9 +645,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch");
static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");
static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");
static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats");
+static LLFastTimer::DeclareTimer FTM_UPDATE_IMAGES("Update Images");
void LLViewerTextureList::updateImages(F32 max_time)
{
+ LLFastTimer _(FTM_UPDATE_IMAGES);
static BOOL cleared = FALSE;
if(gTeleportDisplay)
{
@@ -668,14 +663,17 @@ void LLViewerTextureList::updateImages(F32 max_time)
}
cleared = FALSE;
- LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
+ LLAppViewer::getTextureFetch()->setTextureBandwidth(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_KBIT));
- LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
- LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
- LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes));
- LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes));
- LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
- LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
+ {
+ using namespace LLStatViewer;
+ sample(NUM_IMAGES, sNumImages);
+ sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount);
+ sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory);
+ sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory);
+ sample(RAW_MEM, LLTrace::Bytes(LLImageRaw::sGlobalRawMemory));
+ sample(FORMATTED_MEM, LLTrace::Bytes(LLImageFormatted::sGlobalFormattedMemory));
+ }
{
//loading from fast cache
@@ -756,8 +754,18 @@ void LLViewerTextureList::updateImagesDecodePriorities()
{
// Update the decode priority for N images each frame
{
+ F32 lazy_flush_timeout = 30.f; // stop decoding
+ F32 max_inactive_time = 20.f; // actually delete
+ S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
+ if(LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ //do not remove pre-fetched images if viewer does not finish logging in.
+ lazy_flush_timeout = 30000.f;
+ max_inactive_time = 20000.f;
+ }
+
static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
- const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES);
+ const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
S32 update_counter = llmin(max_update_count, mUUIDMap.size());
uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID);
while ((update_counter-- > 0) && !mUUIDMap.empty())
@@ -779,14 +787,10 @@ void LLViewerTextureList::updateImagesDecodePriorities()
//
// Flush formatted images using a lazy flush
//
- const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding
- const F32 MAX_INACTIVE_TIME = 20.f; // actually delete
- S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
-
S32 num_refs = imagep->getNumRefs();
if (num_refs == min_refs)
{
- if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT)
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
{
// Remove the unused image from the image list
deleteImage(imagep);
@@ -798,7 +802,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
{
if(imagep->hasSavedRawImage())
{
- if(imagep->getElapsedLastReferencedSavedRawImageTime() > MAX_INACTIVE_TIME)
+ if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
{
imagep->destroySavedRawImage() ;
}
@@ -815,7 +819,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
}
else if(imagep->isInactive())
{
- if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME)
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
{
imagep->setDeletionCandidate() ;
}
@@ -991,11 +995,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false
- size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT);
+ size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT);
max_priority_count = llmin(max_priority_count, mImageList.size());
size_t total_update_count = mUUIDMap.size();
- size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT);
+ size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT);
max_update_count = llmin(max_update_count, total_update_count);
// MAX_HIGH_PRIO_COUNT high priority entries
@@ -1232,7 +1236,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting()
{
S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());
//min texture mem sets to 64M if total physical mem is more than 1.5GB
- return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ;
+ return (system_ram > 1500) ? 64 : gMinVideoRam.value() ;
}
//static
@@ -1282,7 +1286,7 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended)
else
max_texmem = llmin(max_texmem, (S32)(system_ram));
- max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES);
+ max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam.value());
return max_texmem;
}
@@ -1370,8 +1374,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
{
received_size = msg->getReceiveSize() ;
}
- gTextureList.sTextureBits += received_size * 8;
- gTextureList.sTexturePackets++;
+ add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size));
+ add(LLStatViewer::TEXTURE_PACKETS, 1);
U8 codec;
U16 packets;
@@ -1443,8 +1447,9 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
{
received_size = msg->getReceiveSize() ;
}
- gTextureList.sTextureBits += received_size * 8;
- gTextureList.sTexturePackets++;
+
+ add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size));
+ add(LLStatViewer::TEXTURE_PACKETS, 1);
//llprintline("Start decode, image header...");
msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id);
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 136042620d..5b6e927e32 100755
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -1,5 +1,5 @@
/**
- * @file llviewertexturelist.h
+ * @file llviewertexturelinumimagest.h
* @brief Object for managing the list of images within a region
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
@@ -30,11 +30,11 @@
#include "lluuid.h"
//#include "message.h"
#include "llgl.h"
-#include "llstat.h"
#include "llviewertexture.h"
#include "llui.h"
#include <list>
#include <set>
+#include "lluiimage.h"
const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128;
@@ -204,17 +204,6 @@ private:
S32 mMaxTotalTextureMemInMegaBytes;
LLFrameTimer mForceDecodeTimer;
-public:
- static U32 sTextureBits;
- static U32 sTexturePackets;
-
- static LLStat sNumImagesStat;
- static LLStat sNumRawImagesStat;
- static LLStat sGLTexMemStat;
- static LLStat sGLBoundMemStat;
- static LLStat sRawMemStat;
- static LLStat sFormattedMemStat;
-
private:
static S32 sNumImages;
static void (*sUUIDCallback)(void**, const LLUUID &);
diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp
index 5147272122..34f2c8f6e6 100755
--- a/indra/newview/llviewerthrottle.cpp
+++ b/indra/newview/llviewerthrottle.cpp
@@ -304,7 +304,8 @@ void LLViewerThrottle::updateDynamicThrottle()
}
mUpdateTimer.reset();
- if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() > TIGHTEN_THROTTLE_THRESHOLD)
+ F32 mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT);
+ if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD)
{
if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH)
{
@@ -317,7 +318,7 @@ void LLViewerThrottle::updateDynamicThrottle()
mCurrent.sendToSim();
llinfos << "Tightening network throttle to " << mCurrentBandwidth << llendl;
}
- else if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() <= EASE_THROTTLE_THRESHOLD)
+ else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD)
{
if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH)
{
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index e8425dc76a..c7e97cfe94 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -30,6 +30,7 @@
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llfloatersidepanelcontainer.h"
+#include "lllocaltextureobject.h"
#include "llnotificationsutil.h"
#include "llsidepanelappearance.h"
#include "lltextureentry.h"
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 65a906d3c0..85e4e6bc08 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -40,6 +40,7 @@
#include "llagentcamera.h"
#include "llcommunicationchannel.h"
#include "llfloaterreg.h"
+#include "llhudicon.h"
#include "llmeshrepository.h"
#include "llnotificationhandler.h"
#include "llpanellogin.h"
@@ -81,7 +82,6 @@
#include "llmediaentry.h"
#include "llurldispatcher.h"
#include "raytrace.h"
-#include "llstat.h"
// newview includes
#include "llagent.h"
@@ -230,10 +230,10 @@ BOOL gShowOverlayTitle = FALSE;
LLViewerObject* gDebugRaycastObject = NULL;
LLVector4a gDebugRaycastIntersection;
-LLVector2 gDebugRaycastTexCoord;
+LLVector2 gDebugRaycastTexCoord;
LLVector4a gDebugRaycastNormal;
LLVector4a gDebugRaycastTangent;
-S32 gDebugRaycastFaceHit;
+S32 gDebugRaycastFaceHit;
LLVector4a gDebugRaycastStart;
LLVector4a gDebugRaycastEnd;
@@ -253,6 +253,9 @@ std::string LLViewerWindow::sSnapshotDir;
std::string LLViewerWindow::sMovieBaseName;
+LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity");
+
+
class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
{
public:
@@ -457,6 +460,8 @@ public:
if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
{
+ LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
+
if (gPipeline.getUseVertexShaders() == 0)
{
addText(xpos, ypos, "Shaders Disabled");
@@ -562,7 +567,7 @@ public:
addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
ypos += y_inc;
- addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount));
+ addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize)));
ypos += y_inc;
addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects()));
@@ -577,14 +582,9 @@ public:
gPipeline.mTextureMatrixOps = 0;
gPipeline.mMatrixOpCount = 0;
- if (gPipeline.mBatchCount > 0)
+ if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0)
{
- addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize,
- gPipeline.mTrianglesDrawn/gPipeline.mBatchCount));
-
- gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize;
- gPipeline.mMaxBatchSize = 0;
- gPipeline.mBatchCount = 0;
+ addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize)));
}
ypos += y_inc;
@@ -596,9 +596,9 @@ public:
ypos += y_inc;
- if (!LLSpatialGroup::sPendingQueries.empty())
+ if (!LLOcclusionCullingGroup::sPendingQueries.empty())
{
- addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size()));
+ addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size()));
ypos += y_inc;
}
@@ -738,7 +738,7 @@ public:
{
if(gTotalTextureBytesPerBoostLevel[i] > 0)
{
- addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024)));
+ addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, LLUnit<F32, LLUnits::Mibibytes>(gTotalTextureBytesPerBoostLevel[i]).value()));
ypos += y_inc;
}
}
@@ -1409,10 +1409,11 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S
FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
std::string temp_str;
+ LLTrace::Recording& recording = LLViewerStats::instance().getRecording();
temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */
- LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
- LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
- LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
+ recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(),
+ recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS),
+ recording.getLastValue(LLStatViewer::SIM_TIME_DILATION));
S32 len = temp_str.length();
TextOutA(hdc, 0, 0, temp_str.c_str(), len);
@@ -1547,8 +1548,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mResDirty(false),
mStatesDirty(false),
mCurrResolutionIndex(0),
- mProgressView(NULL),
- mMouseVelocityStat(new LLStat("Mouse Velocity"))
+ mProgressView(NULL)
{
// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
// pass its value right now. Instead, pass it a nullary function that
@@ -2089,8 +2089,6 @@ LLViewerWindow::~LLViewerWindow()
delete mDebugText;
mDebugText = NULL;
-
- delete mMouseVelocityStat;
}
@@ -2201,8 +2199,8 @@ void LLViewerWindow::reshape(S32 width, S32 height)
}
}
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
+ sample(LLStatViewer::WINDOW_WIDTH, width);
+ sample(LLStatViewer::WINDOW_HEIGHT, height);
LLLayoutStack::updateClass();
}
@@ -2796,11 +2794,12 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
}
}
+static LLFastTimer::DeclareTimer ftm("Update UI");
+
// Update UI based on stored mouse position from mouse-move
// event processing.
void LLViewerWindow::updateUI()
{
- static LLFastTimer::DeclareTimer ftm("Update UI");
LLFastTimer t(ftm);
static std::string last_handle_msg;
@@ -3268,8 +3267,8 @@ void LLViewerWindow::updateMouseDelta()
static F32 fdy = 0.f;
F32 amount = 16.f;
- fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f);
- fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f);
+ fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
+ fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f);
mCurrentMouseDelta.set(llround(fdx), llround(fdy));
mouse_vel.setVec(fdx,fdy);
@@ -3280,7 +3279,7 @@ void LLViewerWindow::updateMouseDelta()
mouse_vel.setVec((F32) dx, (F32) dy);
}
- mMouseVelocityStat->addValue(mouse_vel.magVec());
+ sample(sMouseVelocityStat, mouse_vel.magVec());
}
void LLViewerWindow::updateKeyboardFocus()
@@ -3868,7 +3867,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
}
}
-
+
return found;
}
@@ -4784,7 +4783,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
gGLManager.mIsDisabled = TRUE;
stop_glerror();
- llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemoryInBytes << " bytes" << llendl;
+ llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << llendl;
}
}
@@ -5292,7 +5291,7 @@ void LLPickInfo::getSurfaceInfo()
tangent.clear();
normal.clear();
intersection.clear();
-
+
LLViewerObject* objectp = getObject();
if (objectp)
@@ -5313,7 +5312,7 @@ void LLPickInfo::getSurfaceInfo()
if (facep)
{
mUVCoords = facep->surfaceToTexture(mSTCoords, intersection, normal);
- }
+ }
}
mIntersection.set(intersection.getF32ptr());
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 89f6e3bc26..930ed9d5a9 100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -45,12 +45,12 @@
#include "llnotifications.h"
#include "llhandle.h"
#include "llinitparam.h"
+#include "lltrace.h"
#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include <boost/scoped_ptr.hpp>
-class LLStat;
class LLView;
class LLViewerObject;
class LLUUID;
@@ -252,7 +252,7 @@ public:
S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; }
S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; }
LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; }
- LLStat* getMouseVelocityStat() { return mMouseVelocityStat; }
+ static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; }
BOOL getLeftMouseDown() const { return mLeftMouseDown; }
BOOL getMiddleMouseDown() const { return mMiddleMouseDown; }
BOOL getRightMouseDown() const { return mRightMouseDown; }
@@ -433,7 +433,6 @@ private:
LLCoordGL mCurrentMousePoint; // last mouse position in GL coords
LLCoordGL mLastMousePoint; // Mouse point at last frame.
LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame
- LLStat* mMouseVelocityStat;
BOOL mLeftMouseDown;
BOOL mMiddleMouseDown;
BOOL mRightMouseDown;
@@ -488,6 +487,8 @@ private:
// Object temporarily hovered over while dragging
LLPointer<LLViewerObject> mDragHoveredObject;
+
+ static LLTrace::SampleStatHandle<> sMouseVelocityStat;
};
//
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1a050800b4..11b027a417 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -51,7 +51,6 @@
#include "llpolyskeletaldistortion.h"
#include "lleditingmotion.h"
#include "llemote.h"
-//#include "llfirstuse.h"
#include "llfloatertools.h"
#include "llheadrotmotion.h"
#include "llhudeffecttrail.h"
@@ -81,6 +80,7 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llviewerwearable.h"
@@ -100,6 +100,7 @@
#include "lldebugmessagebox.h"
#include "llsdutil.h"
+#include "llscenemonitor.h"
#include "llsdserialize.h"
extern F32 SPEED_ADJUST_MAX;
@@ -769,6 +770,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mLastPelvisToFoot = 0.0f;
mPelvisFixup = 0.0f;
mLastPelvisFixup = 0.0f;
+
+ if(LLSceneMonitor::getInstance()->isEnabled())
+ {
+ LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
+ }
}
std::string LLVOAvatar::avString() const
@@ -802,17 +808,17 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
//------------------------------------------------------------------------
LLVOAvatar::~LLVOAvatar()
{
- if (!mFullyLoaded)
- {
+ if (!mFullyLoaded)
+ {
debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
- }
- else
- {
+ }
+ else
+ {
debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
- }
+ }
logPendingPhases();
-
+
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
@@ -1196,7 +1202,7 @@ void LLVOAvatar::initInstance(void)
registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
}
-
+
LLAvatarAppearance::initInstance();
// preload specific motions here
@@ -1543,7 +1549,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
return hit;
}
-
+
LLVOAvatar* LLVOAvatar::asAvatar()
{
return this;
@@ -1878,22 +1884,22 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU
}
if (!result)
-{
+ {
const std::string url = getImageURL(te,uuid);
if (!url.empty())
- {
+ {
LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;
result = LLViewerTextureManager::getFetchedTextureFromUrl(
url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
- }
- else
- {
+ }
+ else
+ {
LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;
LLHost host = getObjectHost();
result = LLViewerTextureManager::getFetchedTexture(
uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+ }
}
-}
return result;
}
@@ -2447,7 +2453,7 @@ void LLVOAvatar::idleUpdateWindEffect()
LLVector3 velocity = getVelocity();
F32 speed = velocity.length();
//RN: velocity varies too much frame to frame for this to work
- mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f));
+ mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f));
mLastVel = velocity;
LLVector4 wind;
wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity);
@@ -2470,11 +2476,11 @@ void LLVOAvatar::idleUpdateWindEffect()
F32 interp;
if (wind.mV[VW] > mWindVec.mV[VW])
{
- interp = LLCriticalDamp::getInterpolant(0.2f);
+ interp = LLSmoothInterpolation::getInterpolant(0.2f);
}
else
{
- interp = LLCriticalDamp::getInterpolant(0.4f);
+ interp = LLSmoothInterpolation::getInterpolant(0.4f);
}
mWindVec = lerp(mWindVec, wind, interp);
@@ -2900,7 +2906,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
mTargetRootToHeadOffset = head_offset;
}
- mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+ mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f));
LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
@@ -3365,7 +3371,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// Set the root rotation, but do so incrementally so that it
// lags in time by some fixed amount.
- //F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG);
+ //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG);
F32 pelvis_lag_time = 0.f;
if (self_in_mouselook)
{
@@ -3708,7 +3714,7 @@ bool LLVOAvatar::shouldAlphaMask()
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
-U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
+U32 LLVOAvatar::renderSkinned()
{
U32 num_indices = 0;
@@ -3869,12 +3875,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
//--------------------------------------------------------------------
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
- static LLStat render_stat;
-
- LLViewerJointMesh::sRenderPass = pass;
-
- if (pass == AVATAR_RENDER_PASS_SINGLE)
- {
bool should_alpha_mask = shouldAlphaMask();
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
@@ -3931,13 +3931,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
LLGLState test(GL_ALPHA_TEST, !mIsDummy);
num_indices += renderTransparent(first_pass);
}
- }
-
- LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
-
- //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl;
-
- //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f);
return num_indices;
}
@@ -3980,7 +3973,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
{
LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
if (hair_mesh)
- {
+ {
num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
}
first_pass = FALSE;
@@ -3990,7 +3983,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
}
-
+
return num_indices;
}
@@ -5107,9 +5100,9 @@ BOOL LLVOAvatar::loadSkeletonNode ()
{
if (!LLAvatarAppearance::loadSkeletonNode())
{
- return FALSE;
- }
-
+ return FALSE;
+ }
+
// ATTACHMENTS
{
LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
@@ -5826,18 +5819,18 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
if (texture_dict->mWearableType == type)
- {
+ {
// Thus, you must check to see if the corresponding baked texture is defined.
// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
// gets baked into a texture that always exists (upper or lower).
if (texture_dict->mIsUsedByBakedTexture)
- {
+ {
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
- }
+ }
return FALSE;
- }
+ }
}
return FALSE;
}
@@ -5880,7 +5873,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( color );
}
}
@@ -5948,9 +5941,9 @@ void LLVOAvatar::updateRezzedStatusTimers()
{
// load level has decreased. start phase timers for higher load levels.
for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
- {
+ {
startPhase("load_" + LLVOAvatar::rezStatusToString(i));
- }
+ }
}
else if (rez_status > mLastRezzedStatus)
{
@@ -5959,16 +5952,16 @@ void LLVOAvatar::updateRezzedStatusTimers()
{
stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
- }
+ }
if (rez_status == 3)
- {
+ {
// "fully loaded", mark any pending appearance change complete.
selfStopPhase("update_appearance_from_cof");
selfStopPhase("wear_inventory_category", false);
selfStopPhase("process_initial_wearables_update", false);
}
}
-
+
mLastRezzedStatus = rez_status;
}
}
@@ -5995,7 +5988,7 @@ void LLVOAvatar::startPhase(const std::string& phase_name)
}
void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
- {
+{
F32 elapsed;
bool completed;
if (getPhases().getPhaseValues(phase_name, elapsed, completed))
@@ -6027,7 +6020,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
void LLVOAvatar::logPendingPhases()
{
if (!isAgentAvatarValid())
- {
+ {
return;
}
@@ -6043,14 +6036,14 @@ void LLVOAvatar::logPendingPhases()
if (!completed)
{
logMetricsTimerRecord(phase_name, elapsed, completed);
- }
+ }
}
}
- }
+}
//static
void LLVOAvatar::logPendingPhasesAllAvatars()
- {
+{
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
{
@@ -6061,14 +6054,14 @@ void LLVOAvatar::logPendingPhasesAllAvatars()
}
inst->logPendingPhases();
}
- }
+}
void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
- {
+{
if (!isAgentAvatarValid())
- {
+ {
return;
- }
+ }
LLSD record;
record["timer_name"] = phase_name;
@@ -6077,15 +6070,15 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
record["completed"] = completed;
U32 grid_x(0), grid_y(0);
if (getRegion())
- {
+ {
record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
- }
+ }
record["grid_x"] = LLSD::Integer(grid_x);
record["grid_y"] = LLSD::Integer(grid_y);
record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
record["is_self"] = isSelf();
-
+
if (isAgentAvatarValid())
{
gAgentAvatarp->addMetricsTimerRecord(record);
@@ -6293,28 +6286,28 @@ void LLVOAvatar::updateMeshTextures()
use_lkg_baked_layer[i],
last_id_string.c_str());
}
-
+
for (U32 i=0; i < mBakedTextureDatas.size(); i++)
{
debugColorizeSubMeshes(i, LLColor4::white);
LLViewerTexLayerSet* layerset = getTexLayerSet(i);
if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
- {
+ {
LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
mBakedTextureDatas[i].mIsUsed = TRUE;
debugColorizeSubMeshes(i,LLColor4::red);
-
+
avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
for (; iter != end; ++iter)
- {
+ {
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setTexture( baked_img );
- }
+ }
}
}
else if (!isUsingLocalAppearance() && is_layer_baked[i])
@@ -6358,7 +6351,7 @@ void LLVOAvatar::updateMeshTextures()
if (mesh)
{
mesh->setLayerSet( layerset );
- }
+ }
}
}
else
@@ -6380,7 +6373,7 @@ void LLVOAvatar::updateMeshTextures()
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( color );
mesh->setTexture( hair_img );
}
@@ -6468,13 +6461,13 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com
for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
-{
+ {
const LLMaskedMorph* maskedMorph = (*iter);
LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
if (morph_target)
- {
+ {
morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
-}
+ }
}
}
@@ -6757,12 +6750,12 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
// param_location_name(vparam->getParamLocation()).c_str()
);
- }
-
+}
+
void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
const LLAppearanceMessageContents& contents)
- {
+{
std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
const std::vector<F32>& params_for_dump = contents.mParamWeights;
const LLTEContents& tec = contents.mTEContents;
@@ -6772,9 +6765,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
outfile.open(fullpath, LL_APR_WB );
apr_file_t* file = outfile.getFileHandle();
if (!file)
- {
- return;
- }
+ {
+ return;
+ }
else
{
LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;
@@ -6808,7 +6801,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
}
apr_file_printf(file, "</textures>\n");
- }
+}
void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
{
@@ -6825,7 +6818,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
// For future use:
//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
}
-
+
// Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
@@ -7053,19 +7046,19 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
LLVisualParam* param = contents.mParams[i];
F32 newWeight = contents.mParamWeights[i];
- if (is_first_appearance_message || (param->getWeight() != newWeight))
+ if (is_first_appearance_message || (param->getWeight() != newWeight))
+ {
+ params_changed = TRUE;
+ if(is_first_appearance_message)
{
- params_changed = TRUE;
- if(is_first_appearance_message)
- {
- param->setWeight(newWeight, FALSE);
- }
- else
- {
- interp_params = TRUE;
- param->setAnimationTarget(newWeight, FALSE);
- }
+ param->setWeight(newWeight, FALSE);
+ }
+ else
+ {
+ interp_params = TRUE;
+ param->setAnimationTarget(newWeight, FALSE);
}
+ }
}
const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
if (num_params != expected_tweakable_count)
@@ -7321,12 +7314,12 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
for (; iter != end; ++iter)
- {
+ {
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setTexture( image_baked );
- }
+ }
}
}
@@ -7350,7 +7343,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( LLColor4::white );
}
}
@@ -7369,7 +7362,7 @@ std::string get_sequential_numbered_file_name(const std::string& prefix,
file_num_type::iterator it = file_nums.find(prefix);
S32 num = 0;
if (it != file_nums.end())
-{
+ {
num = it->second;
}
file_nums[prefix] = num+1;
@@ -7386,7 +7379,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
outprefix = getFullname() + (isSelf()?"_s":"_o");
}
if (outprefix.empty())
-{
+ {
outprefix = getFullname() + (isSelf()?"_s":"_o");
}
if (outprefix.empty())
@@ -7415,36 +7408,36 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
if (group_by_wearables)
{
for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
- {
- const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
- apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
+ {
+ const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+ apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
- {
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- if( (viewer_param->getWearableType() == type) &&
- (viewer_param->isTweakable() ) )
{
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ if( (viewer_param->getWearableType() == type) &&
+ (viewer_param->isTweakable() ) )
+ {
dump_visual_param(file, viewer_param, viewer_param->getWeight());
+ }
}
- }
- for (U8 te = 0; te < TEX_NUM_INDICES; te++)
- {
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- // MULTIPLE_WEARABLES: extend to multiple wearables?
- LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
- if( te_image )
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
{
- std::string uuid_str;
- te_image->getID().toString( uuid_str );
- apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ // MULTIPLE_WEARABLES: extend to multiple wearables?
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+ if( te_image )
+ {
+ std::string uuid_str;
+ te_image->getID().toString( uuid_str );
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ }
}
}
}
}
- }
else
{
// Just dump all params sequentially.
@@ -7565,14 +7558,14 @@ void LLVOAvatar::cullAvatarsByPixelArea()
if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
{
sUnbakedUpdateTime = gFrameTimeSeconds;
- sUnbakedTime += gFrameIntervalSeconds;
+ sUnbakedTime += gFrameIntervalSeconds.value();
}
if (grey_avatars > 0)
{
if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame
{
sGreyUpdateTime = gFrameTimeSeconds;
- sGreyTime += gFrameIntervalSeconds;
+ sGreyTime += gFrameIntervalSeconds.value();
}
}
}
@@ -7588,14 +7581,14 @@ void LLVOAvatar::startAppearanceAnimation()
}
}
-// virtual
+//virtual
void LLVOAvatar::bodySizeChanged()
-{
+{
if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
{ // notify simulator of change in size
// but not if we are in the middle of updating appearance
gAgent.sendAgentSetAppearance();
-}
+ }
}
BOOL LLVOAvatar::isUsingServerBakes() const
@@ -7607,25 +7600,25 @@ BOOL LLVOAvatar::isUsingServerBakes() const
F32 wt = appearance_version_param->getWeight();
F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;
if (!is_approx_equal(wt,expect_wt))
-{
+ {
llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;
}
#endif
return mUseServerBakes;
- }
-
+}
+
void LLVOAvatar::setIsUsingServerBakes(BOOL newval)
- {
+{
mUseServerBakes = newval;
LLVisualParam* appearance_version_param = getVisualParam(11000);
llassert(appearance_version_param);
appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);
- }
+}
// virtual
void LLVOAvatar::removeMissingBakedTextures()
- {
+{
}
//virtual
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index b05eed344b..0544d7395d 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -33,7 +33,7 @@
#include <string>
#include <vector>
-#include <boost/signals2.hpp>
+#include <boost/signals2/trackable.hpp>
#include "imageids.h" // IMG_INVISIBLE
#include "llavatarappearance.h"
@@ -74,6 +74,7 @@ struct LLVOAvatarChildJoint;
//class LLViewerJoint;
struct LLAppearanceMessageContents;
struct LLVOAvatarSkeletonInfo;
+class LLViewerJointMesh;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatar
@@ -128,15 +129,15 @@ protected:
public:
/*virtual*/ void updateGL();
/*virtual*/ LLVOAvatar* asAvatar();
- virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
+ virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num,
const EObjectUpdateType update_type,
LLDataPacker *dp);
- virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
/*virtual*/ BOOL updateLOD();
- BOOL updateJointLODs();
- void updateLODRiggedAttachments( void );
+ BOOL updateJointLODs();
+ void updateLODRiggedAttachments( void );
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
S32 totalTextureMemForUUIDS(std::set<LLUUID>& ids);
bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
@@ -372,7 +373,7 @@ public:
bool isVisuallyMuted() const;
U32 renderRigid();
- U32 renderSkinned(EAvatarRenderPass pass);
+ U32 renderSkinned();
F32 getLastSkinTime() { return mLastSkinTime; }
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 15628d5ab2..7d99b11360 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -43,6 +43,7 @@
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventoryfunctions.h"
+#include "lllocaltextureobject.h"
#include "llnotificationsutil.h"
#include "llselectmgr.h"
#include "lltoolgrab.h" // for needsRenderBeam
@@ -602,7 +603,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
** **
*********************************************************************************/
-//virtual
+// virtual
BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
{
// update screen joint size
@@ -789,7 +790,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
updateMeshTextures();
// unpack the texture UUIDs to the texture slots
+ if(mesgsys != NULL)
+ {
retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
+ }
// need to trigger a few operations to get the avatar to use the new bakes
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
@@ -866,10 +870,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
updateMeshTextures();
if (getRegion() && !getRegion()->getCentralBakeVersion())
{
- requestLayerSetUploads();
+ requestLayerSetUploads();
+ }
}
}
-}
//virtual
void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
@@ -896,17 +900,11 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
if (mLastRegionHandle != 0)
{
++mRegionCrossingCount;
- F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32();
- F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG);
- F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
-
- F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
- max = llmax(delta, max);
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
+ LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32();
+ record(LLStatViewer::REGION_CROSSING_TIME, delta);
// Diagnostics
- llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl;
+ llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl;
}
if (regionp)
{
@@ -1310,7 +1308,7 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
- requestLayerSetUpdate(index);
+ requestLayerSetUpdate(index);
if (isEditingAppearance())
{
LLVisualParamHint::requestHintUpdates();
@@ -1799,11 +1797,11 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
{
requestLayerSetUpdate(type);
if (isEditingAppearance())
- {
- LLVisualParamHint::requestHintUpdates();
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
}
}
- }
else
{
tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
@@ -2233,7 +2231,7 @@ LLSD LLVOAvatarSelf::metricsData()
result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();
result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32();
- result["startup"] = LLStartUp::getPhases().dumpPhases();
+ result["startup"] = LLStartUp::getPhases().asLLSD();
return result;
}
@@ -2351,7 +2349,7 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records,
accum_it != accum.end(); ++accum_it)
{
LLSD out_record = accum_it->first;
- out_record["stats"] = accum_it->second.getData();
+ out_record["stats"] = accum_it->second.asLLSD();
result.append(out_record);
}
return result;
@@ -2580,25 +2578,25 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
//if (!covered_by_baked)
{
if (imagep->getID() != IMG_DEFAULT_AVATAR)
- {
+ {
imagep->setNoDelete();
if (imagep->getDiscardLevel() != 0)
- {
- F32 desired_pixels;
- desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
-
- imagep->setBoostLevel(getAvatarBoostLevel());
- imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
- imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
- imagep->addTextureStats( desired_pixels / texel_area_ratio );
- imagep->forceUpdateBindStats() ;
- if (imagep->getDiscardLevel() < 0)
{
- mHasGrey = TRUE; // for statistics gathering
+ F32 desired_pixels;
+ desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+
+ imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
+ imagep->resetTextureStats();
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+ imagep->addTextureStats( desired_pixels / texel_area_ratio );
+ imagep->forceUpdateBindStats() ;
+ if (imagep->getDiscardLevel() < 0)
+ {
+ mHasGrey = TRUE; // for statistics gathering
+ }
}
}
- }
else
{
// texture asset is missing
@@ -2851,7 +2849,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
gAgentAvatarp->invalidateComposite(layer_set, TRUE);
found = TRUE;
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+ add(LLStatViewer::TEX_REBAKES, 1);
}
}
}
@@ -2887,7 +2885,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
}
invalidateComposite(layer_set, TRUE);
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+ add(LLStatViewer::TEX_REBAKES, 1);
}
else
{
@@ -2921,17 +2919,17 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
{
- /* switch(index)
- case TEX_HEAD_BAKED:
- case TEX_HEAD_BODYPAINT:
- return mHeadLayerSet; */
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
return getLayerSet(baked_index);
- }
- return NULL;
+ }
+ return NULL;
}
LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
@@ -2959,7 +2957,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
gAgentAvatarp->mUseLocalAppearance = true;
if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
-{
+ {
gAgentCamera.changeCameraToCustomizeAvatar();
}
@@ -3076,7 +3074,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
sScratchTexNames.deleteAllData();
sScratchTexLastBindTime.deleteAllData();
- LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes;
+ LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;
sScratchTexBytes = 0;
}
}
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 7db19c5c1b..93daf2e171 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -29,6 +29,12 @@
#include "llerror.h"
#include "llregionhandle.h"
#include "llviewercontrol.h"
+#include "llviewerobjectlist.h"
+#include "lldrawable.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+
+LLTrace::MemStatHandle LLVOCachePartition::sMemStat("LLVOCachePartition");
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
@@ -44,39 +50,67 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
//---------------------------------------------------------------------------
// LLVOCacheEntry
//---------------------------------------------------------------------------
+//return number of frames invisible objects should stay in memory
+//static
+U32 LLVOCacheEntry::getInvisibleObjectsLiveTime()
+{
+ static LLCachedControl<U32> inv_obj_time(gSavedSettings,"InvisibleObjectsInMemoryTime");
+
+ return inv_obj_time - 1; //make 0 to be the maximum
+}
LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp)
- :
+ : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
mLocalID(local_id),
mCRC(crc),
+ mUpdateFlags(-1),
mHitCount(0),
mDupeCount(0),
- mCRCChangeCount(0)
+ mCRCChangeCount(0),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mTouched(TRUE),
+ mParentID(0)
{
mBuffer = new U8[dp.getBufferSize()];
mDP.assignBuffer(mBuffer, dp.getBufferSize());
mDP = dp;
+ mMinFrameRange = getInvisibleObjectsLiveTime();
}
LLVOCacheEntry::LLVOCacheEntry()
- :
+ : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
mLocalID(0),
mCRC(0),
+ mUpdateFlags(-1),
mHitCount(0),
mDupeCount(0),
mCRCChangeCount(0),
- mBuffer(NULL)
+ mBuffer(NULL),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mTouched(TRUE),
+ mParentID(0)
{
mDP.assignBuffer(mBuffer, 0);
+ mMinFrameRange = getInvisibleObjectsLiveTime();
}
LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
- : mBuffer(NULL)
+ : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),
+ mBuffer(NULL),
+ mUpdateFlags(-1),
+ mState(INACTIVE),
+ mSceneContrib(0.f),
+ mTouched(FALSE),
+ mParentID(0)
{
S32 size = -1;
BOOL success;
+ mMinFrameRange = getInvisibleObjectsLiveTime();
mDP.assignBuffer(mBuffer, 0);
+
success = check_read(apr_file, &mLocalID, sizeof(U32));
if(success)
{
@@ -132,32 +166,88 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
mDupeCount = 0;
mCRCChangeCount = 0;
mBuffer = NULL;
+ mEntry = NULL;
+ mState = 0;
}
}
LLVOCacheEntry::~LLVOCacheEntry()
{
mDP.freeBuffer();
+ //llassert(mState == INACTIVE);
}
+//virtual
+void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry)
+{
+ if(!entry && mDP.getBufferSize() > 0)
+ {
+ LLUUID fullid;
+ LLViewerObject::unpackUUID(&mDP, fullid, "ID");
+
+ LLViewerObject* obj = gObjectList.findObject(fullid);
+ if(obj && obj->mDrawable)
+ {
+ entry = obj->mDrawable->getEntry();
+ }
+ }
+
+ LLViewerOctreeEntryData::setOctreeEntry(entry);
+}
-// New CRC means the object has changed.
-void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp)
+void LLVOCacheEntry::moveTo(LLVOCacheEntry* new_entry)
{
- if ( (mCRC != crc)
- ||(mDP.getBufferSize() == 0))
+ //copy LLViewerOctreeEntry
+ if(mEntry.notNull())
{
- mCRC = crc;
- mHitCount = 0;
- mCRCChangeCount++;
+ new_entry->setOctreeEntry(mEntry);
+ mEntry = NULL;
+ }
- mDP.freeBuffer();
- mBuffer = new U8[dp.getBufferSize()];
- mDP.assignBuffer(mBuffer, dp.getBufferSize());
- mDP = dp;
+ //copy children
+ S32 num_children = getNumOfChildren();
+ for(S32 i = 0; i < num_children; i++)
+ {
+ new_entry->addChild(getChild(i));
}
+ mChildrenList.clear();
}
+void LLVOCacheEntry::setState(U32 state)
+{
+ mState = state;
+
+ if(getState() == ACTIVE)
+ {
+ const S32 MIN_REAVTIVE_INTERVAL = 32;
+ U32 last_visible = getVisible();
+
+ setVisible();
+
+ if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mMinFrameRange)
+ {
+ mMinFrameRange = llmin(mMinFrameRange * 2, getInvisibleObjectsLiveTime() * 32);
+ }
+ else
+ {
+ mMinFrameRange = getInvisibleObjectsLiveTime(); //reset
+ }
+ }
+}
+
+//virtual
+U32 LLVOCacheEntry::getMinFrameRange()const
+{
+ return mMinFrameRange;
+}
+
+void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
+{
+ llassert(entry != NULL);
+
+ mChildrenList.push_back(entry);
+}
+
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)
{
if ( (mCRC != crc)
@@ -170,9 +260,20 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)
return &mDP;
}
+LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP()
+{
+ if (mDP.getBufferSize() == 0)
+ {
+ //llinfos << "Not getting cache entry, invalid!" << llendl;
+ return NULL;
+ }
+
+ return &mDP;
+}
void LLVOCacheEntry::recordHit()
{
+ setTouched();
mHitCount++;
}
@@ -189,6 +290,11 @@ void LLVOCacheEntry::dump() const
BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
{
+ if(!mEntry)
+ {
+ return FALSE;
+ }
+
BOOL success;
success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
if(success)
@@ -221,49 +327,187 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
return success ;
}
+void LLVOCacheEntry::calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update)
+{
+ if(!needs_update && getVisible() >= last_update)
+ {
+ return; //no need to update
+ }
+
+ const LLVector4a& center = getPositionGroup();
+
+ LLVector4a origin;
+ origin.load3(camera_origin.mV);
+
+ LLVector4a lookAt;
+ lookAt.setSub(center, origin);
+ F32 squared_dist = lookAt.dot3(lookAt).getF32();
+
+ F32 rad = getBinRadius();
+ mSceneContrib = rad * rad / squared_dist;
+
+ setVisible();
+}
+
+void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale)
+{
+ LLVector4a center, newMin, newMax;
+ center.load3(pos.mV);
+ LLVector4a size;
+ size.load3(scale.mV);
+ newMin.setSub(center, size);
+ newMax.setAdd(center, size);
+
+ setPositionGroup(center);
+ setSpatialExtents(newMin, newMax);
+ setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f));
+}
+
//-------------------------------------------------------------------
-//LLVOCache
+//LLVOCachePartition
//-------------------------------------------------------------------
-// Format string used to construct filename for the object cache
-static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
+{
+ mLODPeriod = 16;
+ mRegionp = regionp;
+ mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
+
+ new LLOcclusionCullingGroup(mOctree, this);
+}
-const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
-const U32 MIN_ENTRIES_TO_PURGE = 16 ;
-const U32 INVALID_TIME = 0 ;
-const char* object_cache_dirname = "objectcache";
-const char* header_filename = "object.cache";
+void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
+{
+ llassert(entry->hasVOCacheEntry());
+
+ mOctree->insert(entry);
+}
+
+void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
+{
+ entry->getVOCacheEntry()->setGroup(NULL);
-LLVOCache* LLVOCache::sInstance = NULL;
+ llassert(!entry->getGroup());
+}
+
+class LLVOCacheOctreeCull : public LLViewerOctreeCull
+{
+public:
+ LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion)
+ : LLViewerOctreeCull(camera),
+ mRegionp(regionp)
+ {
+ mLocalShift = shift;
+ mUseObjectCacheOcclusion = (use_object_cache_occlusion && LLPipeline::sUseOcclusion);
+ }
-//static
-LLVOCache* LLVOCache::getInstance()
-{
- if(!sInstance)
+ virtual bool earlyFail(LLviewerOctreeGroup* base_group)
{
- sInstance = new LLVOCache() ;
+ if( mUseObjectCacheOcclusion &&
+ base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+ if(group->needsUpdate())
+ {
+ return false; //needs to issue new occlusion culling check.
+ }
+
+ group->checkOcclusion();
+
+ if (group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
- return sInstance ;
-}
-//static
-BOOL LLVOCache::hasInstance()
-{
- return sInstance != NULL ;
-}
+ virtual S32 frustumCheck(const LLviewerOctreeGroup* group)
+ {
+#if 0
+ S32 res = AABBInRegionFrustumGroupBounds(group);
+#else
+ S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group);
+#endif
+ if (res != 0)
+ {
+ res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift));
+ }
+ return res;
+ }
-//static
-void LLVOCache::destroyClass()
+ virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)
+ {
+#if 0
+ S32 res = AABBInRegionFrustumObjectBounds(group);
+#else
+ S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group);
+#endif
+ if (res != 0)
+ {
+ res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift));
+ }
+ return res;
+ }
+
+ virtual void processGroup(LLviewerOctreeGroup* base_group)
+ {
+ if(mUseObjectCacheOcclusion && base_group->getOctreeNode()->getParent())
+ {
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+ if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1)
+ {
+ ((LLOcclusionCullingGroup*)group)->doOcclusion(mCamera);
+ group->setVisible();
+ return; //wait for occlusion culling results
+ }
+ }
+ mRegionp->addVisibleGroup(base_group);
+ }
+
+private:
+ LLViewerRegion* mRegionp;
+ LLVector3 mLocalShift; //shift vector from agent space to local region space.
+ bool mUseObjectCacheOcclusion;
+};
+
+S32 LLVOCachePartition::cull(LLCamera &camera)
{
- if(sInstance)
+ static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
+
+ if(!LLViewerRegion::sVOCacheCullingEnabled)
{
- delete sInstance ;
- sInstance = NULL ;
+ return 0;
}
+
+ ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound();
+
+ //localize the camera
+ LLVector3 region_agent = mRegionp->getOriginAgent();
+ camera.calcRegionFrustumPlanes(region_agent);
+
+ LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion);
+ culler.traverse(mOctree);
+
+ return 0;
}
+//-------------------------------------------------------------------
+//LLVOCache
+//-------------------------------------------------------------------
+// Format string used to construct filename for the object cache
+static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+
+const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
+const U32 MIN_ENTRIES_TO_PURGE = 16 ;
+const U32 INVALID_TIME = 0 ;
+const char* object_cache_dirname = "objectcache";
+const char* header_filename = "object.cache";
+
+
LLVOCache::LLVOCache():
- mInitialized(FALSE),
- mReadOnly(TRUE),
+ mInitialized(false),
+ mReadOnly(true),
mNumEntries(0),
mCacheSize(1)
{
@@ -300,7 +544,7 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
llwarns << "Cache already initialized." << llendl;
return ;
}
- mInitialized = TRUE ;
+ mInitialized = true;
setDirNames(location);
if (!mReadOnly)
@@ -325,13 +569,19 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
}
}
-void LLVOCache::removeCache(ELLPath location)
+void LLVOCache::removeCache(ELLPath location, bool started)
{
+ if(started)
+ {
+ removeCache();
+ return;
+ }
+
if(mReadOnly)
{
llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl;
return ;
- }
+ }
llinfos << "about to remove the object cache due to settings." << llendl ;
@@ -342,22 +592,25 @@ void LLVOCache::removeCache(ELLPath location)
LLFile::rmdir(cache_dir);
clearCacheInMemory();
- mInitialized = FALSE ;
+ mInitialized = false;
}
void LLVOCache::removeCache()
{
- llassert_always(mInitialized) ;
+ if(!mInitialized)
+ {
+ //OK to remove cache even it is not initialized.
+ llwarns << "Object cache is not initialized yet." << llendl;
+ }
+
if(mReadOnly)
{
llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl;
return ;
}
- llinfos << "about to remove the object cache due to some error." << llendl ;
-
std::string mask = "*";
- llinfos << "Removing cache at " << mObjectCacheDirName << llendl;
+ llinfos << "Removing object cache at " << mObjectCacheDirName << llendl;
gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);
clearCacheInMemory() ;
@@ -366,23 +619,23 @@ void LLVOCache::removeCache()
void LLVOCache::removeEntry(HeaderEntryInfo* entry)
{
- llassert_always(mInitialized) ;
+ llassert_always(mInitialized);
if(mReadOnly)
{
- return ;
+ return;
}
if(!entry)
{
- return ;
+ return;
}
- header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ;
+ header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry);
if(iter != mHeaderEntryQueue.end())
{
- mHandleEntryMap.erase(entry->mHandle) ;
- mHeaderEntryQueue.erase(iter) ;
- removeFromCache(entry) ;
- delete entry ;
+ mHandleEntryMap.erase(entry->mHandle);
+ mHeaderEntryQueue.erase(iter);
+ removeFromCache(entry);
+ delete entry;
mNumEntries = mHandleEntryMap.size() ;
}
@@ -625,11 +878,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
{
for (S32 i = 0; i < num_entries; i++)
{
- LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file);
+ LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file);
if (!entry->getLocalID())
{
llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
- delete entry ;
success = false ;
break ;
}
@@ -665,7 +917,7 @@ void LLVOCache::purgeEntries(U32 size)
mNumEntries = mHandleEntryMap.size() ;
}
-void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache)
+void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled)
{
if(!mEnabled)
{
@@ -738,7 +990,10 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
{
- success = iter->second->writeToFile(&apr_file) ;
+ if(!removal_enabled || iter->second->isTouched())
+ {
+ success = iter->second->writeToFile(&apr_file) ;
+ }
}
}
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 14e3b4c793..b8a7ccac99 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -29,51 +29,141 @@
#include "lluuid.h"
#include "lldatapacker.h"
-#include "lldlinked.h"
#include "lldir.h"
-
+#include "llvieweroctree.h"
+#include "llapr.h"
//---------------------------------------------------------------------------
// Cache entries
class LLVOCacheEntry;
+class LLCamera;
-class LLVOCacheEntry
+class LLVOCacheEntry : public LLViewerOctreeEntryData
{
public:
+ enum //low 16-bit state
+ {
+ INACTIVE = 0x00000000, //not visible
+ IN_QUEUE = 0x00000001, //in visible queue, object to be created
+ WAITING = 0x00000002, //object creation request sent
+ ACTIVE = 0x00000004 //object created, and in rendering pipeline.
+ };
+
+ struct CompareVOCacheEntry
+ {
+ bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs)
+ {
+ F32 lpa = lhs->getSceneContribution();
+ F32 rpa = rhs->getSceneContribution();
+
+ //larger pixel area first
+ if(lpa > rpa)
+ {
+ return true;
+ }
+ else if(lpa < rpa)
+ {
+ return false;
+ }
+ else
+ {
+ return lhs < rhs;
+ }
+ }
+ };
+protected:
+ ~LLVOCacheEntry();
+public:
LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
LLVOCacheEntry(LLAPRFile* apr_file);
- LLVOCacheEntry();
- ~LLVOCacheEntry();
+ LLVOCacheEntry();
+ void setState(U32 state);
+ //void clearState(U32 state) {mState &= ~state;}
+ bool isState(U32 state) {return mState == state;}
+ bool hasState(U32 state) {return mState & state;}
+ U32 getState() const {return mState;}
+
U32 getLocalID() const { return mLocalID; }
U32 getCRC() const { return mCRC; }
S32 getHitCount() const { return mHitCount; }
S32 getCRCChangeCount() const { return mCRCChangeCount; }
+ U32 getMinFrameRange()const;
+
+ void calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update);
+ void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;}
+ F32 getSceneContribution() const { return mSceneContrib;}
void dump() const;
BOOL writeToFile(LLAPRFile* apr_file) const;
- void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
LLDataPackerBinaryBuffer *getDP(U32 crc);
+ LLDataPackerBinaryBuffer *getDP();
void recordHit();
void recordDupe() { mDupeCount++; }
+
+ void moveTo(LLVOCacheEntry* new_entry); //copy variables
+ /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry);
+
+ void setParentID(U32 id) {mParentID = id;}
+ U32 getParentID() const {return mParentID;}
+
+ void addChild(LLVOCacheEntry* entry);
+ LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];}
+ S32 getNumOfChildren() {return mChildrenList.size();}
+ void clearChildrenList() {mChildrenList.clear();}
+
+ //called from processing object update message
+ void setBoundingInfo(const LLVector3& pos, const LLVector3& scale);
+
+ void setTouched(BOOL touched = TRUE) {mTouched = touched;}
+ BOOL isTouched() const {return mTouched;}
+
+ void setUpdateFlags(U32 flags) {mUpdateFlags = flags;}
+ U32 getUpdateFlags() const {return mUpdateFlags;}
+
+private:
+ static U32 getInvisibleObjectsLiveTime();
public:
- typedef std::map<U32, LLVOCacheEntry*> vocache_entry_map_t;
+ typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
+ typedef std::set<LLVOCacheEntry*> vocache_entry_set_t;
+ typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
protected:
U32 mLocalID;
+ U32 mParentID;
U32 mCRC;
+ U32 mUpdateFlags; //receive from sim
S32 mHitCount;
S32 mDupeCount;
S32 mCRCChangeCount;
LLDataPackerBinaryBuffer mDP;
U8 *mBuffer;
+
+ F32 mSceneContrib; //projected scene contributuion of this object.
+ U32 mMinFrameRange;
+ U32 mState; //high 16 bits reserved for special use.
+ std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set.
+
+ BOOL mTouched; //if set, this entry is valid, otherwise it is invalid.
+};
+
+class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTrackable<LLVOCachePartition>
+{
+public:
+ LLVOCachePartition(LLViewerRegion* regionp);
+
+ void addEntry(LLViewerOctreeEntry* entry);
+ void removeEntry(LLViewerOctreeEntry* entry);
+ /*virtual*/ S32 cull(LLCamera &camera);
+
+ static LLTrace::MemStatHandle sMemStat;
};
//
//Note: LLVOCache is not thread-safe
//
-class LLVOCache
+class LLVOCache : public LLSingleton<LLVOCache>
{
private:
struct HeaderEntryInfo
@@ -106,19 +196,20 @@ private:
typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
private:
+ friend class LLSingleton<LLVOCache>;
LLVOCache() ;
public:
~LLVOCache() ;
void initCache(ELLPath location, U32 size, U32 cache_version) ;
- void removeCache(ELLPath location) ;
+ void removeCache(ELLPath location, bool started = false) ;
void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
- void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ;
+ void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled);
void removeEntry(U64 handle) ;
- void setReadOnly(BOOL read_only) {mReadOnly = read_only;}
+ void setReadOnly(bool read_only) {mReadOnly = read_only;}
private:
void setDirNames(ELLPath location);
@@ -134,9 +225,9 @@ private:
BOOL updateEntry(const HeaderEntryInfo* entry);
private:
- BOOL mEnabled;
- BOOL mInitialized ;
- BOOL mReadOnly ;
+ bool mEnabled;
+ bool mInitialized ;
+ bool mReadOnly ;
HeaderMetaInfo mMetaInfo;
U32 mCacheSize;
U32 mNumEntries;
@@ -145,12 +236,6 @@ private:
LLVolatileAPRPool* mLocalAPRFilePoolp ;
header_entry_queue_t mHeaderEntryQueue;
handle_entry_map_t mHandleEntryMap;
-
- static LLVOCache* sInstance ;
-public:
- static LLVOCache* getInstance() ;
- static BOOL hasInstance() ;
- static void destroyClass() ;
};
#endif
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index cab5c4bc1d..88ce6df916 100755
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -603,8 +603,8 @@ U32 LLVOGrass::getPartitionType() const
return LLViewerRegion::PARTITION_GRASS;
}
-LLGrassPartition::LLGrassPartition()
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
+LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -624,9 +624,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
LLViewerCamera* camera = LLViewerCamera::getInstance();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawablep = *i;
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
- if (drawablep->isDead())
+ if (!drawablep || drawablep->isDead())
{
continue;
}
@@ -738,8 +738,10 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
buffer, fullbright);
- info->mExtents[0] = group->mObjectExtents[0];
- info->mExtents[1] = group->mObjectExtents[1];
+
+ const LLVector4a* exts = group->getObjectExtents();
+ info->mExtents[0] = exts[0];
+ info->mExtents[1] = exts[1];
info->mVSize = vsize;
draw_vec.push_back(info);
//for alpha sorting
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index ac2a34ba1e..312842a70f 100755
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -28,12 +28,14 @@
#include "llagent.h"
#include "llfloaterreg.h"
+#include "llhttpclient.h"
#include "llimview.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpanel.h"
#include "llrecentpeople.h"
#include "llviewercontrol.h"
+#include "llviewerregion.h"
#include "llvoicechannel.h"
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 714dd6a9f2..bd9ea029a9 100755
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -34,7 +34,6 @@ class LLVOAvatar;
#include "lliosocket.h"
#include "v3math.h"
#include "llframetimer.h"
-#include "llviewerregion.h"
#include "llcallingcard.h" // for LLFriendObserver
#include "llsecapi.h"
#include "llcontrol.h"
diff --git a/indra/newview/llvoinventorylistener.h b/indra/newview/llvoinventorylistener.h
index bf14d19b01..c50c475478 100755
--- a/indra/newview/llvoinventorylistener.h
+++ b/indra/newview/llvoinventorylistener.h
@@ -30,7 +30,9 @@
#ifndef LL_LLVOINVENTORYLISTENER_H
#define LL_LLVOINVENTORYLISTENER_H
-#include "llviewerobject.h"
+#include "llinventory.h"
+
+class LLViewerObject;
class LLVOInventoryListener
{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 43a5ddba42..87f6f5c4a4 100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -492,8 +492,8 @@ U32 LLVOPartGroup::getPartitionType() const
return LLViewerRegion::PARTITION_PARTICLE;
}
-LLParticlePartition::LLParticlePartition()
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
+LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
{
mRenderPass = LLRenderPass::PASS_ALPHA;
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
@@ -502,8 +502,8 @@ LLParticlePartition::LLParticlePartition()
mLODPeriod = 1;
}
-LLHUDParticlePartition::LLHUDParticlePartition() :
- LLParticlePartition()
+LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
+ LLParticlePartition(regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES;
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
@@ -513,7 +513,7 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
{
- if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
return;
}
@@ -561,9 +561,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
LLViewerCamera* camera = LLViewerCamera::getInstance();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawablep = *i;
+ LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
- if (drawablep->isDead())
+ if (!drawablep || drawablep->isDead())
{
continue;
}
@@ -702,8 +702,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
buffer, fullbright);
- info->mExtents[0] = group->mObjectExtents[0];
- info->mExtents[1] = group->mObjectExtents[1];
+
+ const LLVector4a* exts = group->getObjectExtents();
+ info->mExtents[0] = exts[0];
+ info->mExtents[1] = exts[1];
info->mVSize = vsize;
draw_vec.push_back(info);
//for alpha sorting
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 36793017ed..0a119e853a 100755
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -2146,7 +2146,7 @@ void LLVOSky::updateFog(const F32 distance)
// get the water param manager variables
float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity();
- LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV;
+ LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV);
// adjust the color based on depth. We're doing linear approximations
float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 9a5c5831ca..4633b62bfb 100755
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -1056,8 +1056,8 @@ U32 LLVOSurfacePatch::getPartitionType() const
return LLViewerRegion::PARTITION_TERRAIN;
}
-LLTerrainPartition::LLTerrainPartition()
-: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB)
+LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
+: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
{
mOcclusionEnabled = FALSE;
mInfiniteFarClip = TRUE;
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 7b53219be8..3383b16dd9 100755
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -33,6 +33,8 @@
class LLSurfacePatch;
class LLDrawPool;
class LLVector2;
+class LLFacePool;
+class LLFace;
class LLVOSurfacePatch : public LLStaticViewerObject
{
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index cd12cd9552..dc20d348c0 100755
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -1167,8 +1167,8 @@ U32 LLVOTree::getPartitionType() const
return LLViewerRegion::PARTITION_TREE;
}
-LLTreePartition::LLTreePartition()
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
+LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
mPartitionType = LLViewerRegion::PARTITION_TREE;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 007c2b9003..eeb6c48b04 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -408,7 +408,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
dp->dumpBufferToLog();
llwarns << "Flushing cache files" << llendl;
- if(LLVOCache::hasInstance() && getRegion())
+ if(LLVOCache::instanceExists() && getRegion())
{
LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;
}
@@ -556,9 +556,9 @@ void LLVOVolume::animateTextures()
tex_mat.setIdentity();
LLVector3 trans ;
- trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
- tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
-
+ trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
+ tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
+
LLVector3 scale(scale_s, scale_t, 1.f);
LLQuaternion quat;
quat.setQuat(rot, 0, 0, -1.f);
@@ -3649,7 +3649,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
LLVector4a local_start = start;
LLVector4a local_end = end;
-
+
if (transform)
{
LLVector3 v_start(start.getF32ptr());
@@ -3661,7 +3661,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
local_start.load3(v_start.mV);
local_end.load3(v_end.mV);
}
-
+
LLVector4a p;
LLVector4a n;
LLVector2 tc;
@@ -3999,8 +3999,8 @@ U32 LLVOVolume::getPartitionType() const
return LLViewerRegion::PARTITION_VOLUME;
}
-LLVolumePartition::LLVolumePartition()
-: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
+LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
+: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp)
{
mLODPeriod = 32;
mDepthMask = FALSE;
@@ -4010,8 +4010,8 @@ LLVolumePartition::LLVolumePartition()
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
-LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
-: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK)
+LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
+: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp)
{
mDepthMask = FALSE;
mLODPeriod = 32;
@@ -4057,7 +4057,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{
LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
}
-
+
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
@@ -4107,11 +4107,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
U8 shiny = facep->getTextureEntry()->getShiny();
-
+
LLViewerTexture* tex = facep->getTexture();
U8 index = facep->getTextureIndex();
-
+
LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
@@ -4167,7 +4167,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mMaterial == mat &&
draw_vec[idx]->mMaterialID == mat_id &&
draw_vec[idx]->mFullbright == fullbright &&
- draw_vec[idx]->mBump == bump &&
+ draw_vec[idx]->mBump == bump &&
(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat &&
@@ -4193,7 +4193,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ facep->getVertexBuffer(), fullbright, bump);
draw_info->mGroup = group;
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
@@ -4321,9 +4321,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mLastUpdateViewAngle = group->mViewAngle;
- if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
+ if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
{
- if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
+ if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
{
rebuildMesh(group);
}
@@ -4336,7 +4336,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOAvatar* pAvatarVO = NULL;
- LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (bridge)
{
if (bridge->mAvatar.isNull())
@@ -4361,7 +4361,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mSurfaceArea = 0;
//cache object box size since it might be used for determining visibility
- group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32();
+ const LLVector4a* bounds = group->getObjectBounds();
+ group->mObjectBoxSize = bounds[1].getLength3().getF32();
group->clearDrawMap();
@@ -4375,10 +4376,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
std::vector<LLFace*> simple_faces;
std::vector<LLFace*> alpha_faces;
- U32 useage = group->mSpatialPartition->mBufferUsage;
+ U32 useage = group->getSpatialPartition()->mBufferUsage;
- U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
- U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
+ U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
U32 cur_total = 0;
@@ -4391,9 +4392,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//get all the faces into a list
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
{
continue;
}
@@ -4598,67 +4599,67 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
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 (type == LLDrawPool::POOL_ALPHA)
+ {
+ if (te->getColor().mV[3] > 0.f)
{
if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
}
else
{
- if (LLPipeline::sRenderDeferred)
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
- }
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
}
}
+ }
+ else if (te->getShiny())
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
+ }
else
{
- if (te->getFullbright())
+ if (LLPipeline::sRenderDeferred)
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ 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 (LLPipeline::sRenderDeferred)
+ {
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
{
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ if (te->getBumpmap())
{
- if (te->getBumpmap())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
- }
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
}
}
}
}
+ }
continue;
}
@@ -4869,7 +4870,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
alpha_mask = alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2;
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
-
+
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, batch_textures, FALSE);
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, batch_textures);
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, batch_textures);
@@ -4883,10 +4884,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//drawables have been rebuilt, clear rebuild status
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+ if(drawablep)
+ {
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
}
+ }
group->mLastUpdateTime = gFrameTimeSeconds;
group->mBuilt = 1.f;
@@ -4910,7 +4914,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
- if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))
{
LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
@@ -4923,9 +4927,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
@@ -4991,7 +4995,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
+ if(!drawablep)
+ {
+ continue;
+ }
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
LLFace* face = drawablep->getFace(i);
@@ -5071,7 +5079,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
#endif
//calculate maximum number of vertices to store in a single buffer
- U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
+ U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
{
@@ -5319,7 +5327,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
index_offset += facep->getGeomCount();
indices_index += facep->getIndicesCount();
-
+
//append face to appropriate render batch
BOOL force_simple = facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA;
@@ -5538,7 +5546,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
@@ -5560,10 +5568,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
}
+ }
if (!gPipeline.canUseVertexShaders() &&
@@ -5608,7 +5616,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
{
//initialize to default usage for this partition
- U32 usage = group->mSpatialPartition->mBufferUsage;
+ U32 usage = group->getSpatialPartition()->mBufferUsage;
//clear off any old faces
mFaceList.clear();
@@ -5617,9 +5625,9 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
+ LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep->isDead())
+ if (!drawablep || drawablep->isDead())
{
continue;
}
@@ -5657,7 +5665,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
group->mBufferUsage = usage;
}
-LLHUDPartition::LLHUDPartition()
+LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp)
{
mPartitionType = LLViewerRegion::PARTITION_HUD;
mDrawableType = LLPipeline::RENDER_TYPE_HUD;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index e8a1c3d1d6..50e7ed7bb5 100755
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -298,15 +298,15 @@ U32 LLVOVoidWater::getPartitionType() const
return LLViewerRegion::PARTITION_VOIDWATER;
}
-LLWaterPartition::LLWaterPartition()
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
+LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
{
mInfiniteFarClip = TRUE;
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
mPartitionType = LLViewerRegion::PARTITION_WATER;
}
-LLVoidWaterPartition::LLVoidWaterPartition()
+LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp) : LLWaterPartition(regionp)
{
mOcclusionEnabled = FALSE;
mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 4e26587184..0f2f49a975 100755
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -394,7 +394,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
segment->flush();
}
- llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl;
+ llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << llendl;
}
#else
mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 4f582fc2db..c852f1869b 100755
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llwatchdog.h"
+#include "llthread.h"
const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000;
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index ef1a953f59..79c2778253 100755
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -148,7 +148,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
{
LLFile::remove(std::string(filename));
}
- LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;
switch( status )
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index 3837825d31..6f274c6f16 100755
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
@@ -28,6 +28,7 @@
#define LL_LLWINDEBUG_H
#include "stdtypes.h"
+#include "llwin32headerslean.h"
#include <dbghelp.h>
class LLWinDebug:
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 7996f8a640..b49152508c 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -55,7 +55,7 @@
#include "message.h"
#include "pipeline.h"
#include "llappviewer.h" // for do_disconnect()
-
+#include "llscenemonitor.h"
#include <deque>
#include <queue>
#include <map>
@@ -110,6 +110,7 @@ LLWorld::LLWorld() :
gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled") && gSavedSettings.getBOOL("ObjectCacheEnabled");
}
@@ -122,10 +123,7 @@ void LLWorld::destroyClass()
LLViewerRegion* region_to_delete = *region_it++;
removeRegion(region_to_delete->getHost());
}
- if(LLVOCache::hasInstance())
- {
- LLVOCache::getInstance()->destroyClass() ;
- }
+
LLViewerPartSim::getInstance()->destroyClass();
mDefaultWaterTexturep = NULL ;
@@ -133,6 +131,11 @@ void LLWorld::destroyClass()
{
mEdgeWaterObjects[i] = NULL;
}
+
+ //make all visible drawbles invisible.
+ LLDrawable::incrementVisible();
+
+ LLSceneMonitor::deleteSingleton();
}
@@ -274,7 +277,7 @@ void LLWorld::removeRegion(const LLHost &host)
mActiveRegionList.remove(regionp);
mCulledRegionList.remove(regionp);
mVisibleRegionList.remove(regionp);
-
+
mRegionRemovedSignal(regionp);
delete regionp;
@@ -614,7 +617,8 @@ void LLWorld::updateVisibilities()
if (part)
{
LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
- if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
+ const LLVector4a* bounds = group->getBounds();
+ if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
{
mCulledRegionList.erase(curiter);
mVisibleRegionList.push_back(regionp);
@@ -637,7 +641,8 @@ void LLWorld::updateVisibilities()
if (part)
{
LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
- if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
+ const LLVector4a* bounds = group->getBounds();
+ if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))
{
regionp->calculateCameraDistance();
regionp->getLand().updatePatchVisibilities(gAgent);
@@ -675,6 +680,13 @@ void LLWorld::updateRegions(F32 max_update_time)
did_one = TRUE;
}
}
+
+ mNumOfActiveCachedObjects = 0;
+ for (region_list_t::iterator iter = mRegionList.begin();
+ iter != mRegionList.end(); ++iter)
+ {
+ mNumOfActiveCachedObjects += (*iter)->getNumOfActiveCachedObjects();
+ }
}
void LLWorld::updateParticles()
@@ -707,8 +719,10 @@ void LLWorld::updateNetStats()
{
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
- bits += regionp->mBitStat.getCurrent();
- packets += llfloor( regionp->mPacketsStat.getCurrent() );
+ bits += regionp->mBitsReceived;
+ packets += llfloor( regionp->mPacketsReceived );
+ regionp->mBitsReceived = 0.f;
+ regionp->mPacketsReceived = 0.f;
}
S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn;
@@ -717,19 +731,17 @@ void LLWorld::updateNetStats()
S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
- LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
- LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
- LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
- LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
- LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
- LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
+
+ add(LLStatViewer::ACTUAL_IN_KBIT, LLTrace::Bits(actual_in_bits));
+ add(LLStatViewer::ACTUAL_OUT_KBIT, LLTrace::Bits(actual_out_bits));
+ add(LLStatViewer::KBIT, LLTrace::Bits(bits));
+ add(LLStatViewer::PACKETS_IN, packets_in);
+ add(LLStatViewer::PACKETS_OUT, packets_out);
+ add(LLStatViewer::PACKETS_LOST, packets_lost);
if (packets_in)
{
- LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
- }
- else
- {
- LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
+ F32 packet_loss = 100.f * ((F32)packets_lost/(F32)packets_in);
+ sample(LLStatViewer::PACKETS_LOST_PERCENT, packet_loss);
}
mLastPacketsIn = gMessageSystem->mPacketsIn;
@@ -1142,6 +1154,7 @@ void send_agent_pause()
}
gObjectList.mWasPaused = TRUE;
+ LLViewerStats::instance().getRecording().stop();
}
@@ -1171,8 +1184,8 @@ void send_agent_resume()
gMessageSystem->sendReliable(regionp->getHost());
}
- // Reset the FPS counter to avoid an invalid fps
- LLViewerStats::getInstance()->mFPSStat.start();
+ // Resume data collection to ignore invalid rates
+ LLViewerStats::instance().getRecording().resume();
LLAppViewer::instance()->resumeMainloopTimeout();
}
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index d0b001ba44..d94c27c428 100755
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -145,6 +145,7 @@ public:
U64 getSpaceTimeUSec() const;
void getInfo(LLSD& info);
+ U32 getNumOfActiveCachedObjects() const {return mNumOfActiveCachedObjects;}
public:
typedef std::list<LLViewerRegion*> region_list_t;
@@ -187,7 +188,7 @@ private:
S32 mLastPacketsIn;
S32 mLastPacketsOut;
S32 mLastPacketsLost;
-
+ U32 mNumOfActiveCachedObjects;
U64 mSpaceTimeUSec;
BOOL mClassicCloudsEnabled;
diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h
index 12b6ef4792..ac1ea1607c 100755
--- a/indra/newview/llworldmapmessage.h
+++ b/indra/newview/llworldmapmessage.h
@@ -27,6 +27,8 @@
#ifndef LL_LLWORLDMAPMESSAGE_H
#define LL_LLWORLDMAPMESSAGE_H
+#include "boost/function.hpp"
+
// Handling of messages (send and process) as well as SLURL callback if necessary
class LLMessageSystem;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 1940cf541e..6759328b84 100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -302,8 +302,8 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
// animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(0.1f));
+ sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
+ sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 0da70d398b..583196fb7a 100755
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -25,6 +25,8 @@
*/
#include "llviewerprecompiledheaders.h"
+// include this to get winsock2 because openssl attempts to include winsock1
+#include "llwin32headerslean.h"
#include <openssl/x509_vfy.h>
#include <openssl/ssl.h>
#include "llsecapi.h"
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ebf6be4e36..c2f5b9b861 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -87,6 +87,7 @@
#include "llviewerregion.h" // for audio debugging.
#include "llviewerwindow.h" // For getSpinAxis
#include "llvoavatarself.h"
+#include "llvocache.h"
#include "llvoground.h"
#include "llvosky.h"
#include "llvotree.h"
@@ -112,6 +113,7 @@
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindingcharacters.h"
#include "llpathfindingpathtool.h"
+#include "llscenemonitor.h"
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -197,6 +199,7 @@ BOOL LLPipeline::CameraOffset;
F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
+LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
@@ -410,17 +413,9 @@ bool addDeferredAttachments(LLRenderTarget& target)
LLPipeline::LLPipeline() :
mBackfaceCull(FALSE),
- mBatchCount(0),
mMatrixOpCount(0),
mTextureMatrixOps(0),
- mMaxBatchSize(0),
- mMinBatchSize(0),
- mMeanBatchSize(0),
- mTrianglesDrawn(0),
mNumVisibleNodes(0),
- mVerticesRelit(0),
- mLightingChanges(0),
- mGeometryChanges(0),
mNumVisibleFaces(0),
mInitialized(FALSE),
@@ -504,7 +499,6 @@ void LLPipeline::init()
getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
- LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
resetFrameStats();
if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
@@ -933,7 +927,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
-
+
GLuint screenFormat = GL_RGBA16;
if (gGLManager.mIsATI)
{
@@ -1046,7 +1040,7 @@ void LLPipeline::updateRenderDeferred()
{
BOOL deferred = ((RenderDeferred &&
LLRenderTarget::sUseFBO &&
- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
LLPipeline::sRenderBump &&
VertexShaderEnable &&
RenderAvatarVP &&
@@ -1244,7 +1238,7 @@ void LLPipeline::createGLBuffers()
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);
+ mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
}
allocateScreenBuffer(resX,resY);
@@ -1516,18 +1510,18 @@ S32 LLPipeline::setLightingDetail(S32 level)
return mLightingDetail;
}
-class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
+class LLOctreeDirtyTexture : public OctreeTraveler
{
public:
const std::set<LLViewerFetchedTexture*>& mTextures;
LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
- virtual void visit(const LLOctreeNode<LLDrawable>* node)
+ virtual void visit(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
+ if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
{
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
@@ -1704,7 +1698,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
-
+
if (alpha && mat)
{
switch (mat->getDiffuseAlphaMode())
@@ -1750,11 +1744,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)
void LLPipeline::allocDrawable(LLViewerObject *vobj)
{
- LLDrawable *drawable = new LLDrawable();
+ LLDrawable *drawable = new LLDrawable(vobj);
vobj->mDrawable = drawable;
- drawable->mVObjp = vobj;
-
//encompass completely sheared objects by taking
//the most extreme point possible (<1,1,0.5>)
drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
@@ -1794,7 +1786,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
if (drawablep->getSpatialGroup())
{
LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
- if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
+ if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))
{
#ifdef LL_RELEASE_FOR_DOWNLOAD
llwarns << "Couldn't remove object from spatial group!" << llendl;
@@ -1940,17 +1932,7 @@ void LLPipeline::resetFrameStats()
{
assertInitialized();
- LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
-
- if (mBatchCount > 0)
- {
- mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount;
- }
- mTrianglesDrawn = 0;
sCompiles = 0;
- mVerticesRelit = 0;
- mLightingChanges = 0;
- mGeometryChanges = 0;
mNumVisibleFaces = 0;
if (mOldRenderDebugMask != mRenderDebugMask)
@@ -1958,7 +1940,6 @@ void LLPipeline::resetFrameStats()
gObjectList.clearDebugText();
mOldRenderDebugMask = mRenderDebugMask;
}
-
}
//external functions for asynchronous updating
@@ -2059,6 +2040,8 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree");
static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move");
+static LLFastTimer::DeclareTimer FTM_RETEXTURE("Retexture");
+static LLFastTimer::DeclareTimer FTM_MOVED_LIST("Moved List");
void LLPipeline::updateMove()
{
@@ -2072,8 +2055,7 @@ void LLPipeline::updateMove()
assertInitialized();
{
- static LLFastTimer::DeclareTimer ftm("Retexture");
- LLFastTimer t(ftm);
+ LLFastTimer t(FTM_RETEXTURE);
for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
iter != mRetexturedList.end(); ++iter)
@@ -2088,8 +2070,7 @@ void LLPipeline::updateMove()
}
{
- static LLFastTimer::DeclareTimer ftm("Moved List");
- LLFastTimer t(ftm);
+ LLFastTimer t(FTM_MOVED_LIST);
updateMovedList(mMovedList);
}
@@ -2178,7 +2159,7 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- if (drawable == *i)
+ if (drawable == (LLDrawable*)(*i)->getDrawable())
{
llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;
}
@@ -2200,10 +2181,13 @@ void check_references(LLSpatialGroup* group, LLFace* face)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(drawable)
+ {
check_references(drawable, face);
}
}
+}
void LLPipeline::checkReferences(LLFace* face)
{
@@ -2380,7 +2364,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
min = LLVector3(X,X,X);
max = LLVector3(-X,-X,-X);
- U32 saved_camera_id = LLViewerCamera::sCurCameraID;
+ LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
BOOL res = TRUE;
@@ -2525,6 +2509,13 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
}
}
}
+
+ //scan the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->cull(camera);
+ }
}
if (bound_shader)
@@ -2592,15 +2583,16 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
return;
}
+ const LLVector4a* bounds = group->getBounds();
if (sMinRenderSize > 0.f &&
- llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize)
+ llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize)
{
return;
}
assertInitialized();
- if (!group->mSpatialPartition->mRenderByGroup)
+ if (!group->getSpatialPartition()->mRenderByGroup)
{ //render by drawable
sCull->pushDrawableGroup(group);
}
@@ -2705,7 +2697,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
if (update_complete && assertInitialized())
{
drawablep->setState(LLDrawable::BUILT);
- mGeometryChanges++;
}
return update_complete;
}
@@ -2849,7 +2840,7 @@ void LLPipeline::rebuildGroups()
{
group->rebuildGeom();
- if (group->mSpatialPartition->mRenderByGroup)
+ if (group->getSpatialPartition()->mRenderByGroup)
{
count++;
}
@@ -2918,7 +2909,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
S32 count = 0;
- max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime);
+ max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit<F32, LLUnits::Seconds>(max_dtime));
LLSpatialGroup* last_group = NULL;
LLSpatialBridge* last_bridge = NULL;
@@ -3172,23 +3163,23 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group)
void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
{
- if (group && !group->isDead() && group->mSpatialPartition)
+ if (group && !group->isDead() && group->getSpatialPartition())
{
- if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD)
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD)
{
priority = TRUE;
}
if (priority)
{
- if (!group->isState(LLSpatialGroup::IN_BUILD_Q1))
+ if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
{
llassert_always(!mGroupQ1Locked);
mGroupQ1.push_back(group);
group->setState(LLSpatialGroup::IN_BUILD_Q1);
- if (group->isState(LLSpatialGroup::IN_BUILD_Q2))
+ if (group->hasState(LLSpatialGroup::IN_BUILD_Q2))
{
LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);
if (iter != mGroupQ2.end())
@@ -3199,7 +3190,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
}
}
}
- else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
+ else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
{
llassert_always(!mGroupQ2Locked);
mGroupQ2.push_back(group);
@@ -3274,7 +3265,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
group->setVisible();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- markVisible(*i, camera);
+ markVisible((LLDrawable*)(*i)->getDrawable(), camera);
}
if (!sDelayVBUpdate)
@@ -3361,8 +3352,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawablep = *i;
- stateSort(drawablep, camera);
+ stateSort((LLDrawable*)(*i)->getDrawable(), camera);
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3463,7 +3453,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
-
mNumVisibleFaces += drawablep->getNumFaces();
}
@@ -3476,7 +3465,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
{
for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
{
- func(*j);
+ if((*j)->hasDrawable())
+ {
+ func((LLDrawable*)(*j)->getDrawable());
+ }
}
}
}
@@ -3704,7 +3696,7 @@ void LLPipeline::postSort(LLCamera& camera)
continue;
}
- if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
{ //no way this group is going to be drawable without a rebuild
group->rebuildGeom();
}
@@ -3742,7 +3734,7 @@ void LLPipeline::postSort(LLCamera& camera)
if (alpha != group->mDrawMap.end())
{ //store alpha groups for sorting
- LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
if (bridge)
@@ -3863,7 +3855,7 @@ void LLPipeline::postSort(LLCamera& camera)
if (!sShadowRender)
{
mSelectedFaces.clear();
-
+
LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
// Draw face highlights for selected faces.
@@ -3888,33 +3880,6 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
- /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence");
- static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work");
- if (use_transform_feedback)
- { //using transform feedback, wait for transform feedback to complete
- LLFastTimer t(FTM_TRANSFORM_WAIT);
-
- S32 done = 0;
- //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count);
-
- glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
-
- while (!done)
- {
- {
- LLFastTimer t(FTM_TRANSFORM_DO_WORK);
- F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
- //do some useful work while we wait
- LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
- }
- glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
- }
-
- mTransformFeedbackPrimitives = 0;
- }*/
-
//LLSpatialGroup::sNoDelete = FALSE;
llpushcallstacks ;
}
@@ -4089,9 +4054,9 @@ void LLPipeline::renderHighlights()
}
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
{
@@ -4111,7 +4076,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
}
-
+
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
{
// Paint 'em red!
@@ -4720,10 +4685,8 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
count = index_count/3;
}
- mTrianglesDrawn += count;
- mBatchCount++;
- mMaxBatchSize = llmax(mMaxBatchSize, count);
- mMinBatchSize = llmin(mMinBatchSize, count);
+ record(sStatBatchSize, count);
+ add(LLStatViewer::TRIANGLES_DRAWN, count);
if (LLPipeline::sRenderFrameTest)
{
@@ -5152,7 +5115,7 @@ void LLPipeline::renderDebug()
{
DebugBlip& blip = *iter;
- blip.mAge += gFrameIntervalSeconds;
+ blip.mAge += gFrameIntervalSeconds.value();
if (blip.mAge > 2.f)
{
mDebugBlips.erase(iter++);
@@ -5162,7 +5125,7 @@ void LLPipeline::renderDebug()
iter++;
}
- blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f;
+ blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f;
gGL.color4fv(blip.mColor.mV);
gGL.vertex3fv(blip.mPosition.mV);
@@ -5404,7 +5367,7 @@ void LLPipeline::renderDebug()
continue;
}
- LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead()))
{
@@ -5752,7 +5715,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
case LLDrawPool::POOL_MATERIALS:
llassert(poolp == mMaterialsPool);
mMaterialsPool = NULL;
@@ -5828,7 +5791,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
}
mHWLightColors[1] = diffuse;
-
+
light->setDiffuse(diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -6033,7 +5996,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
if (farthest_light->fade >= 0.f)
{
- farthest_light->fade = -gFrameIntervalSeconds;
+ farthest_light->fade = -(gFrameIntervalSeconds.value());
}
}
else
@@ -6137,12 +6100,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (fade >= 0.f)
{
fade = fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds;
+ ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value();
}
else
{
fade = 1.f + fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds;
+ ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value();
}
fade = llclamp(fade,0.f,1.f);
light_color *= fade;
@@ -7311,10 +7274,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.loadIdentity();
LLGLDisable test(GL_ALPHA_TEST);
-
+
gGL.setColorMask(true, true);
glClearColor(0,0,0,0);
-
+
{
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
@@ -7521,7 +7484,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
else if (transition_time < 1.f)
{ //currently in a transition, continue interpolating
- transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds;
+ transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();
transition_time = llmin(transition_time, 1.f);
F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
@@ -7657,7 +7620,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
-
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{
shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
@@ -7705,7 +7668,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
mScreen.bindTexture(0, channel);
}
-
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{
shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
@@ -8591,7 +8554,7 @@ void LLPipeline::renderDeferredLighting()
fullscreen_lights.pop_front();
col[count] = light_colors.front();
light_colors.pop_front();
-
+
col[count].mV[0] = powf(col[count].mV[0], 2.2f);
col[count].mV[1] = powf(col[count].mV[1], 2.2f);
col[count].mV[2] = powf(col[count].mV[2], 2.2f);
@@ -9635,7 +9598,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
if (!mHighlightSet.empty())
{
- F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime;
+ F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;
LLGLDisable test(GL_ALPHA_TEST);
LLGLDepthTest depth(GL_FALSE);
@@ -9909,7 +9872,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowFrustPoints[j].clear();
}
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
//restore render matrices
glh_set_current_modelview(saved_view);
@@ -10285,12 +10248,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (gen_shadow)
{
- F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
//update shadow targets
for (U32 i = 0; i < 2; i++)
{ //for each current shadow
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
if (mShadowSpotLight[i].notNull() &&
(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
@@ -10409,7 +10374,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
@@ -10459,7 +10424,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
LLSpatialGroup* group = *i;
if (!group->isDead() &&
(!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
- gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
+ gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
group->mDrawMap.find(type) != group->mDrawMap.end())
{
pass->renderGroup(group,type,mask,texture);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 2c023a6f70..ef05205844 100755
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -29,8 +29,6 @@
#include "llcamera.h"
#include "llerror.h"
-#include "lldarrayptr.h"
-#include "lldqueueptr.h"
#include "lldrawpool.h"
#include "llspatialpartition.h"
#include "m4math.h"
@@ -43,27 +41,15 @@
#include <stack>
-#include <stack>
-
-#include <stack>
-
class LLViewerTexture;
-class LLEdge;
class LLFace;
class LLViewerObject;
-class LLAgent;
-class LLDisplayPrimitive;
class LLTextureEntry;
-class LLRenderFunc;
-class LLCubeMap;
class LLCullResult;
class LLVOAvatar;
class LLGLSLShader;
-class LLCurlRequest;
class LLDrawPoolAlpha;
-class LLMeshResponder;
-
typedef enum e_avatar_skinning_method
{
SKIN_METHOD_SOFTWARE,
@@ -542,23 +528,14 @@ public:
LLQuaternion mFlyCamRotation;
BOOL mBackfaceCull;
- S32 mBatchCount;
S32 mMatrixOpCount;
S32 mTextureMatrixOps;
- S32 mMaxBatchSize;
- S32 mMinBatchSize;
- S32 mMeanBatchSize;
- S32 mTrianglesDrawn;
S32 mNumVisibleNodes;
- S32 mVerticesRelit;
S32 mDebugTextureUploadCost;
S32 mDebugSculptUploadCost;
S32 mDebugMeshUploadCost;
- S32 mLightingChanges;
- S32 mGeometryChanges;
-
S32 mNumVisibleFaces;
static S32 sCompiles;
@@ -590,9 +567,11 @@ public:
static BOOL sRenderDeferred;
static BOOL sMemAllocationThrottled;
static S32 sVisibleLightCount;
- static F32 sMinRenderSize;
+ static F32 sMinRenderSize;
static BOOL sRenderingHUDs;
+ static LLTrace::EventStatHandle<S64> sStatBatchSize;
+
//screen texture
U32 mScreenWidth;
U32 mScreenHeight;
diff --git a/indra/newview/skins/default/xui/da/floater_lagmeter.xml b/indra/newview/skins/default/xui/da/floater_lagmeter.xml
deleted file mode 100755
index 149d174c34..0000000000
--- a/indra/newview/skins/default/xui/da/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="LAG METER">
- <floater.string name="max_title_msg">
- Lag måler
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Klient
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, vindue i baggrund
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Klients billeder/sek under [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Klients billeder/sek mellem [CLIENT_FRAME_RATE_CRITICAL] og [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Mulig årsag: &apos;Vis afstand&apos; sat for højt i grafik indstillinger
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Mulig årsag: Billeder hentes
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Mulig årsag: For mange billeder i hukommelse
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Mulig årsag: For mange komplekse objekter i scenariet
- </floater.string>
- <floater.string name="network_text_msg">
- Netværk
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Forbindelsen mister over [NETWORK_PACKET_LOSS_CRITICAL]% pakker
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Forbindelsen mister [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% pakker
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Forbindelsens ping tider er over [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Forbindelsens ping tider er [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Muligvis dårlig forbindelse eller &apos;båndbredde&apos; sat for højt i netværksopsætning.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Muligvis dårlig forbindelse eller fil delings program.
- </floater.string>
- <floater.string name="server_text_msg">
- Server
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Simulator framerate er under [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Simulator framerate er mellem [SERVER_FRAME_RATE_CRITICAL] og [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Mulig årsag: For mange fysiske objekter
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Mulig årsag: For mange objekter med script
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Mulig årsag: For meget netværks trafik
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Mulig årsag: For mange avatarer i bevægelse i regionen
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Mulig årsag: For mange billed udregninger
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Mulig årsag: Simulator belastning for stor
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button label="" label_selected="" name="client_lagmeter" tool_tip="Status for klient lag"/>
- <text name="client">
- Klient
- </text>
- <text name="client_text">
- Normal
- </text>
- <button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/>
- <text name="network">
- Netværk
- </text>
- <text name="network_text">
- Normal
- </text>
- <button label="" label_selected="" name="server_lagmeter" tool_tip="Status for server lag"/>
- <text name="server">
- Server
- </text>
- <text name="server_text">
- Normal
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="Ændre størrelse"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_lagmeter.xml b/indra/newview/skins/default/xui/de/floater_lagmeter.xml
deleted file mode 100755
index 45ff37c147..0000000000
--- a/indra/newview/skins/default/xui/de/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="LAG METER">
- <floater.string name="max_title_msg">
- Lag-Anzeige
- </floater.string>
- <floater.string name="max_width_px">
- 350
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Client
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, Fenster im Hintergrund
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Client-Frame-Rate unter [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Client-Frame-Rate zwischen [CLIENT_FRAME_RATE_CRITICAL] und [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Mögliche Ursache: Sichtweite zu groß
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Mögliche Ursache: Bilder werden geladen
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Mögliche Ursache: Zu viele Bilder im Speicher
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Mögliche Ursache: Zu viele komplexe Objekte in der Szene
- </floater.string>
- <floater.string name="network_text_msg">
- Netzwerk
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Paketverlust der Verbindung übersteigt [NETWORK_PACKET_LOSS_CRITICAL]%
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Paketverlust der Verbindung liegt bei [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]%
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Ping-Zeit der Verbindung übersteigt [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Ping-Zeit der Verbindung liegt bei [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Möglicherweise schlechte Verbindung oder zu hoher Wert für „Bandbreite“.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Möglicherweise schlechte Verbindung oder File-Sharing-Anwendung.
- </floater.string>
- <floater.string name="server_text_msg">
- Server
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Simulator-Frame-Rate liegt unter [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Simulator-Frame-Rate liegt zwischen [SERVER_FRAME_RATE_CRITICAL] und [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Mögliche Ursache: Zu viele physische Objekte
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Mögliche Ursache: Zu viele geskriptete Objekte
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Mögliche Ursache: Zu viel Netzwerktraffic
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Mögliche Ursache: Zu viele Personen in Bewegung in der Region
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Mögliche Ursache: Zu viele Bildberechnungen
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Mögliche Ursache: Zu hohe Simulator-Last
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="Client-Lag-Status"/>
- <text name="client">
- Client
- </text>
- <text name="client_text">
- Normal
- </text>
- <button name="network_lagmeter" tool_tip="Netzwerk-Lag-Status"/>
- <text name="network">
- Netzwerk
- </text>
- <text name="network_text">
- Normal
- </text>
- <button name="server_lagmeter" tool_tip="Server-Lag-Status"/>
- <text name="server">
- Server
- </text>
- <text name="server_text">
- Normal
- </text>
- <button label="&gt;&gt; " name="minimize" tool_tip="Fenstergröße ändern"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index 77adb5524e..671f116df3 100755
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -16,6 +16,27 @@
width="700">
<string name="pause" >Pause</string>
<string name="run">Run</string>
+ <combo_box name="time_scale_combo"
+ follows="left|top"
+ left="10"
+ top="5"
+ width="150"
+ height="20">
+ <item label="2x Average"/>
+ <item label="Max"/>
+ <item label="Recent Max"/>
+ <item label="100ms"/>
+ </combo_box>
+ <combo_box name="metric_combo"
+ follows="left|top"
+ left_pad="10"
+ top="5"
+ width="150"
+ height="20">
+ <item label="Time"/>
+ <item label="Number of Calls"/>
+ <item label="Hz"/>
+ </combo_box>
<button follows="top|right"
name="pause_btn"
left="-200"
@@ -24,4 +45,52 @@
height="40"
label="Pause"
font="SansSerifHuge"/>
+ <layout_stack name="legend_stack"
+ orientation="horizontal"
+ left="0"
+ top="50"
+ right="695"
+ bottom="500"
+ follows="all">
+ <layout_panel name="legend_panel"
+ auto_resize="false"
+ user_resize="true"
+ width="220"
+ height="450"
+ min_width="100">
+ <panel top="0"
+ left="0"
+ width="220"
+ height="440"
+ name="legend"
+ follows="all"/>
+ </layout_panel>
+ <layout_panel name="timers_panel"
+ auto_resize="true"
+ user_resize="true"
+ height="450"
+ width="475"
+ min_width="100">
+ <layout_stack name="timer_bars_stack"
+ orientation="vertical"
+ left="0"
+ top="0"
+ width="475"
+ height="445"
+ follows="all">
+ <layout_panel name="bars_panel"
+ auto_resize="true"
+ user_resize="true"
+ top="0"
+ width="475"
+ height="210"/>
+ <layout_panel name="lines_panel"
+ auto_resize="false"
+ user_resize="true"
+ width="475"
+ min_height="50"
+ height="240"/>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml
deleted file mode 100755
index b24c745bdd..0000000000
--- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml
+++ /dev/null
@@ -1,336 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="170"
- layout="topleft"
- name="floater_lagmeter"
- help_topic="floater_lagmeter"
- save_rect="true"
- title="LAG METER"
- width="350">
- <floater.string
- name="max_title_msg">
- Lag Meter
- </floater.string>
- <floater.string
- name="max_width_px">
- 360
- </floater.string>
- <floater.string
- name="min_title_msg">
- Lag
- </floater.string>
- <floater.string
- name="min_width_px">
- 90
- </floater.string>
- <floater.string
- name="client_text_msg">
- Client
- </floater.string>
- <floater.string
- name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string
- name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string
- name="client_frame_time_window_bg_msg">
- Normal, window in background
- </floater.string>
- <floater.string
- name="client_frame_time_critical_msg">
- Client frame rate below [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string
- name="client_frame_time_warning_msg">
- Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string
- name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string
- name="client_draw_distance_cause_msg">
- Possible cause: Draw distance set too high
- </floater.string>
- <floater.string
- name="client_texture_loading_cause_msg">
- Possible cause: Images loading
- </floater.string>
- <floater.string
- name="client_texture_memory_cause_msg">
- Possible cause: Too many images in memory
- </floater.string>
- <floater.string
- name="client_complex_objects_cause_msg">
- Possible cause: Too many complex objects in scene
- </floater.string>
- <floater.string
- name="network_text_msg">
- Network
- </floater.string>
- <floater.string
- name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string
- name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string
- name="network_packet_loss_critical_msg">
- Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets
- </floater.string>
- <floater.string
- name="network_packet_loss_warning_msg">
- Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets
- </floater.string>
- <floater.string
- name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string
- name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string
- name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string
- name="network_ping_critical_msg">
- Connection ping time is over [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string
- name="network_ping_warning_msg">
- Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string
- name="network_packet_loss_cause_msg">
- Possible bad connection or &apos;Bandwidth&apos; pref too high.
- </floater.string>
- <floater.string
- name="network_ping_cause_msg">
- Possible bad connection or file-sharing app.
- </floater.string>
- <floater.string
- name="server_text_msg">
- Server
- </floater.string>
- <floater.string
- name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string
- name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string
- name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string
- name="server_frame_time_critical_msg">
- Simulator framerate below [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string
- name="server_frame_time_warning_msg">
- Simulator framerate between [SERVER_FRAME_RATE_CRITICAL] and [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string
- name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string
- name="server_physics_cause_msg">
- Possible Cause: Too many physical objects
- </floater.string>
- <floater.string
- name="server_scripts_cause_msg">
- Possible Cause: Too many scripted objects
- </floater.string>
- <floater.string
- name="server_net_cause_msg">
- Possible Cause: Too much network traffic
- </floater.string>
- <floater.string
- name="server_agent_cause_msg">
- Possible Cause: Too many moving people in region
- </floater.string>
- <floater.string
- name="server_images_cause_msg">
- Possible Cause: Too many image calculations
- </floater.string>
- <floater.string
- name="server_generic_cause_msg">
- Possible Cause: Simulator load too heavy
- </floater.string>
- <floater.string
- name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string
- name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button
- follows="top|left"
- height="16"
- image_selected="lag_status_good.tga"
- image_unselected="lag_status_good.tga"
- layout="topleft"
- left="8"
- name="client_lagmeter"
- tab_stop="false"
- tool_tip="Client lag status"
- top="24"
- width="16" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="3"
- name="client"
- top_delta="0"
- width="128">
- Client
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- type="string"
- length="1"
- bottom="40"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="110"
- name="client_text"
- right="-10">
- Normal
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- bottom="56"
- follows="left|top"
- height="16"
- layout="topleft"
- left="40"
- name="client_lag_cause"
- right="-32" />
- <button
- follows="top|left"
- height="16"
- image_selected="lag_status_good.tga"
- image_unselected="lag_status_good.tga"
- layout="topleft"
- left="8"
- name="network_lagmeter"
- tab_stop="false"
- tool_tip="Network lag status"
- top="64"
- width="16" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="3"
- name="network"
- top_delta="0"
- width="128">
- Network
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- type="string"
- length="1"
- bottom="80"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="110"
- name="network_text"
- right="-10">
- Normal
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- bottom="96"
- follows="left|top"
- height="16"
- layout="topleft"
- left="40"
- name="network_lag_cause"
- right="-32" />
- <button
- follows="top|left"
- height="16"
- image_selected="lag_status_good.tga"
- image_unselected="lag_status_good.tga"
- layout="topleft"
- left="8"
- name="server_lagmeter"
- tab_stop="false"
- tool_tip="Server lag status"
- top="104"
- width="16" />
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left_pad="3"
- name="server"
- top_delta="0"
- width="60">
- Server
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- type="string"
- length="1"
- bottom="120"
- follows="left|top"
- font="SansSerif"
- height="16"
- layout="topleft"
- left="110"
- name="server_text"
- right="-10">
- Normal
- </text>
- <text
- invisiblity_control="LagMeterShrunk"
- bottom="136"
- follows="left|top"
- height="16"
- layout="topleft"
- left="40"
- name="server_lag_cause"
- right="-32" />
- <button
- follows="left|top"
- height="20"
- label="&gt;&gt;"
- layout="topleft"
- left="10"
- name="minimize"
- tool_tip="Toggle floater size"
- top_delta="24"
- width="40">
- <button.commit_callback
- function="LagMeter.ClickShrink" />
- </button>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
new file mode 100644
index 0000000000..246e8bb256
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater legacy_header_height="18"
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="Scene Load Statistics"
+ save_rect="true"
+ save_visibility="true"
+ title="SCENE LOAD STATISTICS"
+ width="260">
+ <button follows="top|left"
+ top="20"
+ bottom="60"
+ left="10"
+ width="100"
+ label="Pause"
+ name="playpause"/>
+ <scroll_container follows="top|left|bottom|right"
+ bottom="400"
+ layout="topleft"
+ left="0"
+ name="statistics_scroll"
+ reserve_scroll_corner="true"
+ top="60"
+ width="260">
+ <container_view follows="top|left|bottom|right"
+ height="378"
+ layout="topleft"
+ left="2"
+ name="statistics_view"
+ top="20"
+ width="245" >
+<!--Basic Section-->
+ <stat_view name="basic"
+ label="Basic"
+ show_label="true"
+ setting="OpenDebugStatBasic">
+ <stat_bar name="frame difference"
+ label="Frame Pixel Difference"
+ orientation="horizontal"
+ unit_label="%"
+ stat="FramePixelDifference"
+ bar_max="100"
+ tick_spacing="10"
+ unit_scale="100"
+ precision="0"/>
+ <stat_bar name="bandwidth"
+ label="Bandwidth"
+ orientation="horizontal"
+ unit_label="kbps"
+ stat="kbitstat"
+ bar_max="5000"
+ tick_spacing="500"
+ precision="0"/>
+ <stat_bar name="packet_loss"
+ label="Packet Loss"
+ orientation="horizontal"
+ unit_label=" %"
+ stat="packetslostpercentstat"
+ bar_max="5"
+ tick_spacing="0.5"
+ precision="3"
+ show_bar="false"
+ show_mean="true"/>
+ </stat_view>
+<!--Advanced Section-->
+ <stat_view name="advanced"
+ label="Advanced"
+ show_label="true"
+ setting="OpenDebugStatAdvanced">
+ <stat_view name="render"
+ label="Render"
+ show_label="true"
+ setting="OpenDebugStatRender">
+ <stat_bar name="objs"
+ label="Total Objects"
+ orientation="horizontal"
+ unit_label=""
+ stat="numobjectsstat"
+ bar_max="50000"
+ tick_spacing="5000"
+ precision="0"
+ show_bar="false"/>
+ <stat_bar name="newobjs"
+ label="New Objects"
+ orientation="horizontal"
+ unit_label="/sec"
+ stat="numnewobjectsstat"
+ bar_max="2000"
+ tick_spacing="200"
+ show_bar="false"/>
+ <stat_bar name="object_cache_hits"
+ label="Object Cache Hit Rate"
+ orientation="horizontal"
+ stat="object_cache_hits"
+ bar_max="100"
+ unit_label="%"
+ tick_spacing="20"
+ show_history="true"
+ show_bar="false"/>
+ </stat_view>
+<!--Texture Stats-->
+ <stat_view name="texture"
+ label="Texture"
+ show_label="true">
+ <stat_bar name="texture_cache_hits"
+ label="Cache Hit Rate"
+ orientation="horizontal"
+ stat="texture_cache_hits"
+ bar_max="100.f"
+ unit_label="%"
+ tick_spacing="20"
+ show_history="true"
+ show_bar="false"/>
+ <stat_bar name="texture_cache_read_latency"
+ label="Cache Read Latency"
+ orientation="horizontal"
+ unit_label="msec"
+ stat="texture_cache_read_latency"
+ bar_max="1000.f"
+ tick_spacing="100"
+ show_history="true"
+ show_bar="false"/>
+ <stat_bar name="numimagesstat"
+ label="Count"
+ orientation="horizontal"
+ stat="numimagesstat"
+ bar_max="8000.f"
+ tick_spacing="2000.f"
+ show_bar="false"/>
+ <stat_bar name="numrawimagesstat"
+ label="Raw Count"
+ orientation="horizontal"
+ stat="numrawimagesstat"
+ bar_max="8000.f"
+ tick_spacing="2000.f"
+ show_bar="false"/>
+ </stat_view>
+<!--Network Stats-->
+ <stat_view name="network"
+ label="Network"
+ show_label="true"
+ setting="OpenDebugStatNet">
+ <stat_bar name="packetsinstat"
+ label="Packets In"
+ orientation="horizontal"
+ stat="packetsinstat"
+ unit_label="/sec"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="packetsoutstat"
+ label="Packets Out"
+ orientation="horizontal"
+ stat="packetsoutstat"
+ unit_label="/sec"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="objectkbitstat"
+ label="Objects"
+ orientation="horizontal"
+ stat="objectkbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="texturekbitstat"
+ label="Texture"
+ orientation="horizontal"
+ stat="texturekbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="assetkbitstat"
+ label="Asset"
+ orientation="horizontal"
+ stat="assetkbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="layerskbitstat"
+ label="Layers"
+ orientation="horizontal"
+ stat="layerskbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="actualinkbitstat"
+ label="Actual In"
+ orientation="horizontal"
+ stat="actualinkbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="actualoutkbitstat"
+ label="Actual Out"
+ orientation="horizontal"
+ stat="actualoutkbitstat"
+ unit_label="kbps"
+ bar_max="1024.f"
+ tick_spacing="128.f"
+ precision="1"
+ show_bar="false"/>
+ <stat_bar name="vfspendingoperations"
+ label="VFS Pending Operations"
+ orientation="horizontal"
+ stat="vfspendingoperations"
+ unit_label=" Ops."
+ show_bar="false"/>
+ </stat_view>
+ </stat_view>
+<!--Sim Stats-->
+ <stat_view name="sim"
+ label="Simulator"
+ show_label="true"
+ setting="OpenDebugStatSim">
+ <stat_bar name="simobjects"
+ label="Objects"
+ orientation="horizontal"
+ stat="simobjects"
+ precision="0"
+ bar_max="30000.f"
+ tick_spacing="5000.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simactiveobjects"
+ label="Active Objects"
+ orientation="horizontal"
+ stat="simactiveobjects"
+ precision="0"
+ bar_max="5000.f"
+ tick_spacing="750.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simactivescripts"
+ label="Active Scripts"
+ orientation="horizontal"
+ stat="simactivescripts"
+ precision="0"
+ bar_max="15000.f"
+ tick_spacing="1875.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="siminpps"
+ label="Packets In"
+ orientation="horizontal"
+ stat="siminpps"
+ unit_label="pps"
+ precision="0"
+ bar_max="2000.f"
+ tick_spacing="250.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simoutpps"
+ label="Packets Out"
+ orientation="horizontal"
+ stat="simoutpps"
+ unit_label="pps"
+ precision="0"
+ bar_max="2000.f"
+ tick_spacing="250.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simpendingdownloads"
+ label="Pending Downloads"
+ orientation="horizontal"
+ stat="simpendingdownloads"
+ precision="0"
+ bar_max="800.f"
+ tick_spacing="100.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simpendinguploads"
+ label="Pending Uploads"
+ orientation="horizontal"
+ stat="simpendinguploads"
+ precision="0"
+ bar_max="100.f"
+ tick_spacing="25.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simtotalunackedbytes"
+ label="Total Unacked Bytes"
+ orientation="horizontal"
+ stat="simtotalunackedbytes"
+ unit_label="kb"
+ precision="1"
+ bar_max="100000.f"
+ tick_spacing="25000.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_view name="simperf"
+ label="Time (ms)"
+ show_label="true">
+ <stat_bar name="simframemsec"
+ label="Total Frame Time"
+ orientation="horizontal"
+ stat="simframemsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simnetmsec"
+ label="Net Time"
+ orientation="horizontal"
+ stat="simnetmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsimphysicsmsec"
+ label="Physics Time"
+ orientation="horizontal"
+ stat="simsimphysicsmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsimothermsec"
+ label="Simulation Time"
+ orientation="horizontal"
+ stat="simsimothermsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simagentmsec"
+ label="Agent Time"
+ orientation="horizontal"
+ stat="simagentmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simimagesmsec"
+ label="Images Time"
+ orientation="horizontal"
+ stat="simimagesmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simscriptmsec"
+ label="Script Time"
+ orientation="horizontal"
+ stat="simscriptmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsparemsec"
+ label="Spare Time"
+ orientation="horizontal"
+ stat="simsparemsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+<!--2nd level time blocks under 'Details' second-->
+ <stat_view name="timedetails"
+ label="Time Details (ms)"
+ show_label="true">
+ <stat_bar name="simsimphysicsstepmsec"
+ label=" Physics Step"
+ orientation="horizontal"
+ stat="simsimphysicsstepmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsimphysicsshapeupdatemsec"
+ label=" Update Phys Shapes"
+ orientation="horizontal"
+ stat="simsimphysicsshapeupdatemsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsimphysicsothermsec"
+ label=" Physics Other"
+ orientation="horizontal"
+ stat="simsimphysicsothermsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simsleepmsec"
+ label=" Sleep Time"
+ orientation="horizontal"
+ stat="simsleepmsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ <stat_bar name="simpumpiomsec"
+ label=" Pump IO"
+ orientation="horizontal"
+ stat="simpumpiomsec"
+ unit_label="ms"
+ precision="3"
+ bar_max="40.f"
+ tick_spacing="10.f"
+ show_bar="false"
+ show_mean="false"/>
+ </stat_view>
+ </stat_view>
+ </stat_view>
+ </container_view>
+ </scroll_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index f9eb16d224..0493f487d4 100755
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -31,17 +31,17 @@
<stat_view
name="basic"
label="Basic"
+ follows="left|top|right"
show_label="true"
setting="OpenDebugStatBasic">
<stat_bar
name="fps"
label="FPS"
unit_label="fps"
- stat="fpsstat"
+ stat="framesrendered"
bar_min="0"
bar_max="60"
tick_spacing="6"
- label_spacing="12"
precision="1"
show_bar="true"
show_history="true">
@@ -54,7 +54,6 @@
bar_min="0"
bar_max="5000"
tick_spacing="500"
- label_spacing="1000"
precision="0"
show_bar="true"
show_history="false">
@@ -67,9 +66,7 @@
bar_min="0"
bar_max="5"
tick_spacing="0.5"
- label_spacing="1"
precision="3"
- show_per_sec="false"
show_bar="false"
show_mean="true">
</stat_bar>
@@ -81,10 +78,8 @@
bar_min="0"
bar_max="5000"
tick_spacing="500"
- label_spacing="1000"
precision="0"
show_bar="false"
- show_per_sec="false"
show_mean="false">
</stat_bar>
</stat_view>
@@ -92,11 +87,13 @@
<stat_view
name="advanced"
label="Advanced"
+ follows="left|top|right"
show_label="true"
setting="OpenDebugStatAdvanced">
<stat_view
name="render"
label="Render"
+ follows="left|top|right"
show_label="true"
setting="OpenDebugStatRender">
<stat_bar
@@ -104,10 +101,10 @@
label="KTris Drawn per Frame"
unit_label="/fr"
stat="trianglesdrawnstat"
+ unit_scale="0.001"
bar_min="0"
bar_max="10000"
tick_spacing="1000"
- label_spacing="2000"
precision="0"
show_per_sec="false"
show_bar="false">
@@ -116,11 +113,11 @@
name="ktrissec"
label="KTris Drawn per Sec"
unit_label="/sec"
+ unit_scale="0.001"
stat="trianglesdrawnstat"
bar_min="0"
bar_max="200000"
tick_spacing="25000"
- label_spacing="50000"
precision="0"
show_bar="false">
</stat_bar>
@@ -132,9 +129,7 @@
bar_min="0"
bar_max="50000"
tick_spacing="5000"
- label_spacing="10000"
precision="0"
- show_per_sec="false"
show_bar="false">
</stat_bar>
<stat_bar
@@ -145,8 +140,6 @@
bar_min="0"
bar_max="2000"
tick_spacing="200"
- label_spacing="400"
- show_per_sec="true"
show_bar="false">
</stat_bar>
<stat_bar
@@ -157,9 +150,7 @@
bar_max="100"
unit_label="%"
tick_spacing="20"
- label_spacing="20"
show_history="true"
- show_per_sec="false"
show_bar="false">
</stat_bar>
</stat_view>
@@ -167,6 +158,7 @@
<stat_view
name="texture"
label="Texture"
+ follows="left|top|right"
show_label="true">
<stat_bar
name="texture_cache_hits"
@@ -176,9 +168,7 @@
bar_max="100.f"
unit_label="%"
tick_spacing="20"
- label_spacing="20"
show_history="true"
- show_per_sec="false"
show_bar="false">
</stat_bar>
<stat_bar
@@ -189,9 +179,7 @@
bar_min="0.f"
bar_max="1000.f"
tick_spacing="100"
- label_spacing="200"
show_history="true"
- show_per_sec="false"
show_bar="false">
</stat_bar>
<stat_bar
@@ -201,8 +189,6 @@
bar_min="0.f"
bar_max="8000.f"
tick_spacing="2000.f"
- label_spacing="4000.f"
- show_per_sec="false"
show_bar="false">
</stat_bar>
@@ -213,8 +199,6 @@
bar_min="0.f"
bar_max="8000.f"
tick_spacing="2000.f"
- label_spacing="4000.f"
- show_per_sec="false"
show_bar="false">
</stat_bar>
@@ -222,12 +206,12 @@
name="gltexmemstat"
label="GL Mem"
stat="gltexmemstat"
+ unit_label="MB"
+ unit_scale="0.000001"
bar_min="0.f"
bar_max="400.f"
tick_spacing="100.f"
- label_spacing="200.f"
precision="1"
- show_per_sec="false"
show_bar="false">
</stat_bar>
@@ -235,25 +219,25 @@
name="formattedmemstat"
label="Formatted Mem"
stat="formattedmemstat"
+ unit_label="MB"
+ unit_scale="0.000001"
bar_min="0.f"
bar_max="400.f"
tick_spacing="100.f"
- label_spacing="200.f"
- precision="1"
- show_per_sec="false"
+ precision="3"
show_bar="false">
</stat_bar>
<stat_bar
name="rawmemstat"
label="Raw Mem"
+ unit_label="MB"
+ unit_scale="0.000001"
stat="rawmemstat"
bar_min="0.f"
bar_max="400.f"
tick_spacing="100.f"
- label_spacing="200.f"
- precision="1"
- show_per_sec="false"
+ precision="3"
show_bar="false">
</stat_bar>
@@ -261,12 +245,12 @@
name="glboundmemstat"
label="Bound Mem"
stat="glboundmemstat"
+ unit_label="MB"
+ unit_scale="0.000001"
bar_min="0.f"
bar_max="400.f"
tick_spacing="100.f"
- label_spacing="200.f"
- precision="1"
- show_per_sec="false"
+ precision="3"
show_bar="false">
</stat_bar>
</stat_view>
@@ -274,6 +258,7 @@
<stat_view
name="network"
label="Network"
+ follows="left|top|right"
show_label="true"
setting="OpenDebugStatNet">
<stat_bar
@@ -284,7 +269,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false">
</stat_bar>
@@ -297,7 +281,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false" >
</stat_bar>
@@ -310,7 +293,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false" >
</stat_bar>
@@ -323,7 +305,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false" >
</stat_bar>
@@ -336,7 +317,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false" >
</stat_bar>
@@ -349,7 +329,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false" >
</stat_bar>
@@ -362,7 +341,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false"
show_history="false" >
@@ -376,7 +354,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
precision="1"
show_bar="false"
show_history="false">
@@ -387,7 +364,6 @@
label="VFS Pending Operations"
stat="vfspendingoperations"
unit_label=" Ops."
- show_per_sec="false"
show_bar="false" >
</stat_bar>
</stat_view>
@@ -396,6 +372,7 @@
<stat_view
name="sim"
label="Simulator"
+ follows="left|top|right"
show_label="true"
setting="OpenDebugStatSim">
<stat_bar
@@ -406,8 +383,6 @@
bar_min="0.f"
bar_max="1.f"
tick_spacing="0.16666f"
- label_spacing="0.33333f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -420,8 +395,6 @@
bar_min="0.f"
bar_max="45.f"
tick_spacing="7.5f"
- label_spacing="15.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -434,8 +407,6 @@
bar_min="0.f"
bar_max="45.f"
tick_spacing="7.5.f"
- label_spacing="15.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -443,6 +414,7 @@
<stat_view
name="physicsdetail"
label="Physics Details"
+ follows="left|top|right"
show_label="true">
<stat_bar
name="physicspinnedtasks"
@@ -452,8 +424,6 @@
bar_min="0.f"
bar_max="500.f"
tick_spacing="50.f"
- label_spacing="100.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -466,8 +436,6 @@
bar_min="0.f"
bar_max="500.f"
tick_spacing="50.f"
- label_spacing="100.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -481,8 +449,6 @@
bar_min="0.f"
bar_max="1024.f"
tick_spacing="128.f"
- label_spacing="256.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -496,8 +462,6 @@
bar_min="0.f"
bar_max="100.f"
tick_spacing="25.f"
- label_spacing="50.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -510,8 +474,6 @@
bar_min="0.f"
bar_max="80.f"
tick_spacing="10.f"
- label_spacing="40.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -524,8 +486,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="5.f"
- label_spacing="10.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -538,8 +498,6 @@
bar_min="0.f"
bar_max="30000.f"
tick_spacing="5000.f"
- label_spacing="10000.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -552,8 +510,6 @@
bar_min="0.f"
bar_max="5000.f"
tick_spacing="750.f"
- label_spacing="1250.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -566,8 +522,6 @@
bar_min="0.f"
bar_max="15000.f"
tick_spacing="1875.f"
- label_spacing="3750.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -579,9 +533,7 @@
bar_min="0"
bar_max="100"
tick_spacing="10"
- label_spacing="20"
precision="3"
- show_per_sec="false"
show_bar="false"
show_mean="true">
</stat_bar>
@@ -595,8 +547,6 @@
bar_min="0.f"
bar_max="5000.f"
tick_spacing="750.f"
- label_spacing="1250.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -604,6 +554,7 @@
<stat_view
name="simpathfinding"
label="Pathfinding"
+ follows="left|top|right"
show_label="true">
<stat_bar
name="simsimaistepmsec"
@@ -614,8 +565,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -628,8 +577,6 @@
bar_min="0"
bar_max="45"
tick_spacing="4"
- label_spacing="8"
- show_per_sec="false"
show_bar="false">
</stat_bar>
<stat_bar
@@ -640,9 +587,7 @@
bar_min="0"
bar_max="100"
tick_spacing="10"
- label_spacing="20"
precision="1"
- show_per_sec="false"
show_bar="false"
show_mean="true">
</stat_bar>
@@ -657,8 +602,6 @@
bar_min="0.f"
bar_max="2000.f"
tick_spacing="250.f"
- label_spacing="1000.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -672,8 +615,6 @@
bar_min="0.f"
bar_max="2000.f"
tick_spacing="250.f"
- label_spacing="1000.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -686,8 +627,6 @@
bar_min="0.f"
bar_max="800.f"
tick_spacing="100.f"
- label_spacing="200.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -700,8 +639,6 @@
bar_min="0.f"
bar_max="100.f"
tick_spacing="25.f"
- label_spacing="50.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -715,8 +652,6 @@
bar_min="0.f"
bar_max="100000.f"
tick_spacing="25000.f"
- label_spacing="50000.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -724,6 +659,7 @@
<stat_view
name="simperf"
label="Time (ms)"
+ follows="left|top|right"
show_label="true">
<stat_bar
name="simframemsec"
@@ -734,8 +670,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -749,8 +683,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -764,8 +696,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -779,8 +709,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -794,8 +722,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -809,8 +735,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -824,8 +748,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -839,8 +761,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -848,6 +768,7 @@
<stat_view
name="timedetails"
label="Time Details (ms)"
+ follows="left|top|right"
show_label="true">
<stat_bar
name="simsimphysicsstepmsec"
@@ -858,8 +779,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -872,8 +791,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -886,8 +803,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -900,8 +815,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
@@ -914,8 +827,6 @@
bar_min="0.f"
bar_max="40.f"
tick_spacing="10.f"
- label_spacing="20.f"
- show_per_sec="false"
show_bar="false"
show_mean="false" >
</stat_bar>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b01c3067ff..f4a9e69bf9 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1475,6 +1475,14 @@
function="Floater.Toggle"
parameter="stats" />
</menu_item_check>
+ <menu_item_call
+ label="Scene Load Statistics"
+ name="Scene Load Statistics"
+ shortcut="control|shift|2">
+ <on_click
+ function="Floater.Show"
+ parameter="scene_load_stats" />
+ </menu_item_call>
<menu_item_check
label="Show Draw Weight for Avatars"
name="Avatar Rendering Cost">
@@ -2080,6 +2088,16 @@
function="Advanced.ToggleConsole"
parameter="scene view" />
</menu_item_check>
+ <menu_item_check
+ label="Scene Loading Monitor"
+ name="Scene Loading Monitor">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="scene monitor" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="scene monitor" />
+ </menu_item_check>
<menu_item_call
enabled="false"
visible="false"
@@ -2834,6 +2852,16 @@
function="ToggleControl"
parameter="RenderHoverGlowEnable" />
</menu_item_check>
+ <menu_item_separator />
+
+ <menu_item_call
+ enabled="true"
+ label="Clear Cache Immediately"
+ name="Cache Clear">
+ <menu_item_call.on_click
+ function="Develop.ClearCache" />
+ </menu_item_call>
+
</menu>
<menu
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 9e582cf0de..8667d0277a 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6923,9 +6923,9 @@ Do not allow access if you do not fully understand why it wants access to your a
[FOOTERTEXT]
</footer>
</notification>
-
- <notification
- icon="notify.tga"
+
+ <notification
+ icon="notify.tga"
name="UnknownScriptQuestion"
persist="false"
type="notify">
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f7b33b0a4a..29393bf749 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -418,7 +418,7 @@ Please try logging in again in a minute.</string>
<string name="OverrideYourAnimations">Replace your default animations</string>
<string name="ScriptReturnObjects">Return objects on your behalf</string>
<string name="UnknownScriptPermission">(unknown)!</string>
-
+
<!-- Sim Access labels -->
<string name="SIM_ACCESS_PG">General</string>
<string name="SIM_ACCESS_MATURE">Moderate</string>
diff --git a/indra/newview/skins/default/xui/es/floater_lagmeter.xml b/indra/newview/skins/default/xui/es/floater_lagmeter.xml
deleted file mode 100755
index 227689a194..0000000000
--- a/indra/newview/skins/default/xui/es/floater_lagmeter.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="MEDIDOR DEL LAG">
- <floater.string name="max_title_msg">
- Medidor del lag
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Cliente
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, ventana en segundo plano
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Frames del cliente valorados por debajo de [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Frames del cliente valorados entre [CLIENT_FRAME_RATE_CRITICAL] y [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Posible causa: distancia de dibujo fijada muy alta
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Posible causa: imágenes cargándose
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Posible causa: demasiadas imágenes en la memoria
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Posible causa: demasiados objetos complejos en la escena
- </floater.string>
- <floater.string name="network_text_msg">
- Red
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- La conexión deja caer más del [NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- La conexión deja caer [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- El tiempo de conexión -ping- supera los [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- El tiempo de conexión -ping- es de [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Quizá una mala conexión o un ancho de banda fijado demasiado alto.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Quizá una mala conexión o una aplicación de archivos compartidos.
- </floater.string>
- <floater.string name="server_text_msg">
- Servidor
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Frecuencia (framerate) por debajo de [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Frecuencia (framerate) entre [SERVER_FRAME_RATE_CRITICAL] y [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Posible causa: demasiados objetos físicos
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Posible causa: demasiados objetos con script
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Posible causa: demasiado tráfico en la red
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Posible causa: demasiada gente moviéndose en la región
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Posible causa: demasiados cálculos de imáganes
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Posible causa: carga del simulador muy pesada
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button label="" label_selected="" name="client_lagmeter" tool_tip="Estado del lag del cliente"/>
- <text name="client">
- Cliente
- </text>
- <text font="SansSerifSmall" name="client_text">
- Normal
- </text>
- <text left="30" name="client_lag_cause" right="-10"/>
- <button label="" label_selected="" name="network_lagmeter" tool_tip="Estado del lag de la red"/>
- <text name="network">
- Red
- </text>
- <text font="SansSerifSmall" name="network_text">
- Normal
- </text>
- <text left="30" name="network_lag_cause" right="-10"/>
- <button label="" label_selected="" name="server_lagmeter" tool_tip="Estado del lag del servidor"/>
- <text name="server">
- Servidor
- </text>
- <text font="SansSerifSmall" name="server_text">
- Normal
- </text>
- <text left="30" name="server_lag_cause" right="-32"/>
- <button label="&gt;&gt;" name="minimize" tool_tip="Cambia el tamaño de la ventana"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml b/indra/newview/skins/default/xui/fr/floater_lagmeter.xml
deleted file mode 100755
index 39a861d8bd..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="MESURE DU LAG">
- <floater.string name="max_title_msg">
- Mesure du lag
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Client
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, fenêtre en arrière-plan
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Taux de défilement [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Taux de défilement entre [CLIENT_FRAME_RATE_CRITICAL] et [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Cause possible : limite d&apos;affichage trop élevée
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Cause possible : images en cours de chargement
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Cause possible : trop d&apos;images en mémoire
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Cause possible : trop d&apos;objets complexes
- </floater.string>
- <floater.string name="network_text_msg">
- Réseau
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- La connexion perd plus de [NETWORK_PACKET_LOSS_CRITICAL] % de paquets
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- La connexion perd entre [NETWORK_PACKET_LOSS_WARNING] % et [NETWORK_PACKET_LOSS_CRITICAL] % de paquets
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Connexion ping > [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Connexion ping entre [NETWORK_PING_WARNING] et [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Mauvaise connexion possible ou réglage de la bande passante trop élevé.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Mauvaise connexion possible ou app. de partage des fichiers
- </floater.string>
- <floater.string name="server_text_msg">
- Serveur
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Défilement du simulateur &lt; [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Défilement simulateur entre [SERVER_FRAME_RATE_CRITICAL] et [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Cause possible : trop d&apos;objets physiques
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Cause possible : trop d&apos;objets scriptés
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Cause possible : trop de trafic réseau
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Cause possible : trop de personnes en mouvement
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Cause possible : trop de calculs d&apos;images
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Cause possible : charge simulateur trop lourde
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="Statut du lag client"/>
- <text name="client">
- Client
- </text>
- <text name="client_text">
- Normal
- </text>
- <button name="network_lagmeter" tool_tip="Statut du lag réseau"/>
- <text name="network">
- Réseau
- </text>
- <text name="network_text">
- Normal
- </text>
- <button name="server_lagmeter" tool_tip="Statut du lag serveur"/>
- <text name="server">
- Serveur
- </text>
- <text name="server_text">
- Normal
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="Activer/désactiver la taille du floater"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_lagmeter.xml b/indra/newview/skins/default/xui/it/floater_lagmeter.xml
deleted file mode 100755
index f7b2b1ab4a..0000000000
--- a/indra/newview/skins/default/xui/it/floater_lagmeter.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="MISURATORE LAG">
- <floater.string name="max_title_msg">
- Misuratore del lag
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Programma in locale
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normale, finestra sullo sfondo
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Velocità dei frame al di sotto di [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Velocità dei frame tra [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normale
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Possibile causa: Campo visivo impostato troppo alto
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Possibile causa: Caricamento immagini
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Possibile causa: Troppe immagini in memoria
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Possibile causa: Troppi oggetti complessi intorno
- </floater.string>
- <floater.string name="network_text_msg">
- Network
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- La connessione sta calando al di sotto del [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- La connessione sta calando tra il [NETWORK_PACKET_LOSS_WARNING]% e il [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normale
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Il tempo di ping della connessione è al di sopra di [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Il tempo di ping della connessione è tra [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Possibile cattiva connessione o la larghezza di banda impostata nelle preferenze troppo alta.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Possibile cattiva connessione o l&apos;apertura di un programma di scambio files.
- </floater.string>
- <floater.string name="server_text_msg">
- Server
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Velocità dei frame al di sotto di [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Velocità dei frame tra [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normale
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Possibile causa: troppi oggetti fisici
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Possibile causa: troppi oggetti scriptati
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Possibile causa: eccessivo traffico sulla rete
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Possibile causa: troppi residenti in movimento nella regione
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Possibile causa: troppe elaborazioni di immagini
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Possibile causa: carico eccessivo del simulatore
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button label="" label_selected="" name="client_lagmeter" tool_tip="Stato del lag del programma in locale"/>
- <text name="client">
- Client
- </text>
- <text font="SansSerifSmall" left="145" name="client_text">
- Normale
- </text>
- <text left="30" name="client_lag_cause" right="-10"/>
- <button label="" label_selected="" name="network_lagmeter" tool_tip="Stato del lag del network"/>
- <text name="network">
- Rete
- </text>
- <text font="SansSerifSmall" name="network_text">
- Normale
- </text>
- <text left="30" name="network_lag_cause" right="-10"/>
- <button label="" label_selected="" name="server_lagmeter" tool_tip="Stato del lag del server"/>
- <text name="server">
- Server
- </text>
- <text font="SansSerifSmall" name="server_text">
- Normale
- </text>
- <text left="30" name="server_lag_cause" right="-32"/>
- <button label="&gt;&gt;" name="minimize" tool_tip="Cambia dimensioni floater"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
deleted file mode 100755
index e3546cd837..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="ラグメーター">
- <floater.string name="max_title_msg">
- ラグ メーター
- </floater.string>
- <floater.string name="max_width_px">
- 350
- </floater.string>
- <floater.string name="min_title_msg">
- ラグ
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- クライアント
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- ノーマル、ウィンドウは背景に
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- クライアント フレームレート < [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- クライアント フレームレート: [CLIENT_FRAME_RATE_CRITICAL] ~ [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- ノーマル
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- 考えられる原因: 描画距離の設定が大きすぎる
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- 考えられる原因: 画像のロード中
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- 考えられる原因: メモリ内の画像数が多すぎる
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- 考えられる原因: 画面に含まれる複雑なオブジェクトが多すぎる
- </floater.string>
- <floater.string name="network_text_msg">
- ネットワーク
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- 接続でドロップされるパケットの割合: > [NETWORK_PACKET_LOSS_CRITICAL]
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- 接続でドロップされるパケットの割合:[NETWORK_PACKET_LOSS_WARNING] ~ [NETWORK_PACKET_LOSS_CRITICAL]
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- ノーマル
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- 接続の ping 時間: > [NETWORK_PING_CRITICAL] ミリ秒
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- 接続の ping 時間: [NETWORK_PING_WARNING] ~ [NETWORK_PING_CRITICAL] ミリ秒
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- 接続不良になっているか、帯域幅設定が高すぎます。
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- 接続不良になっているか、ファイル共有アプリケーションに問題があります。
- </floater.string>
- <floater.string name="server_text_msg">
- サーバー
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- シミュレーターのフレームレート: < [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- シミュレーターのフレームレート: [SERVER_FRAME_RATE_CRITICAL] ~ [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- ノーマル
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- 考えられる原因: 物理的オブジェクトが多すぎる
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- 考えられる原因: スクリプトを含むオブジェクトが多すぎる
- </floater.string>
- <floater.string name="server_net_cause_msg">
- 考えられる原因: ネットワーク トラフィック過大
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- 考えられる原因: 地域内にて動いているアバターが多すぎる
- </floater.string>
- <floater.string name="server_images_cause_msg">
- 考えられる原因: 画像計算が多すぎる
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- 考えられる原因: シミュレーターの過負荷
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="クライアント ラグ ステータス"/>
- <text name="client">
- クライアント
- </text>
- <text name="client_text">
- ノーマル
- </text>
- <button name="network_lagmeter" tool_tip="ネットワーク ラグ ステータス"/>
- <text name="network">
- ネットワーク
- </text>
- <text name="network_text">
- ノーマル
- </text>
- <button name="server_lagmeter" tool_tip="サーバー ラグ ステータス"/>
- <text name="server">
- サーバー
- </text>
- <text name="server_text">
- ノーマル
- </text>
- <button label="&gt;&gt; " name="minimize" tool_tip="フローターのサイズをトグル"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml
deleted file mode 100755
index 8038550bcb..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="POMIAR LAGÓW">
- <floater.string name="max_title_msg">
- Pomiar lagów
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Lag
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Klient
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- W normie, okno w tle
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Ilość klatek na sekundę klienta poniżej [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Ilość klatek na sekundę pomiędzy [CLIENT_FRAME_RATE_CRITICAL] i [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- W normie
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Przyczyna: dystans rysowania jest za wysoki
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Przyczyna: ładowanie obrazu
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Przyczyna: za dużo obrazów w pamięci
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Przyczyna: za dużo złożonych obiektów
- </floater.string>
- <floater.string name="network_text_msg">
- Sieć
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Utrata pakietów przekracza [NETWORK_PACKET_LOSS_CRITICAL]%
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Utrata pakietów przekracza [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]%
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- W normie
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Fatalny ping - [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Wolny ping - [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Złe połączenie lub przepustowość.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Złe połączenie lub aplikacja współdzieląca pliki.
- </floater.string>
- <floater.string name="server_text_msg">
- Serwer
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Ilość klatek na sekundę poniżej [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Ilość klatek na sekundę pomiędzy [SERVER_FRAME_RATE_CRITICAL] i [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- W normie
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Przyczyna: za dużo obiektów fizycznych
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Przyczyna: za dużo obieków skryptowanych
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Przyczyna: za duży ruch w sieci
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Przyczyna: za dużo poruszających się awatarów w regionie
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Przyczyna: za dużo kalkulacji obrazu
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Przyczyna: symulator ładuje się zbyt powoli
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button label="" label_selected="" name="client_lagmeter" tool_tip="Status lagów klienta"/>
- <text name="client">
- Klient
- </text>
- <text name="client_text">
- W normie
- </text>
- <button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/>
- <text name="network">
- Sieć
- </text>
- <text name="network_text">
- W normie
- </text>
- <button label="" label_selected="" name="server_lagmeter" tool_tip="Server lag status"/>
- <text name="server">
- Serwer
- </text>
- <text name="server_text">
- W normie
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="Złącz rozmiar pliku xml"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml b/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
deleted file mode 100755
index 9932318293..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
+++ /dev/null
@@ -1,154 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="LAG - Índice">
- <floater.string name="max_title_msg">
- Medidor de Atraso
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Atraso
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Cliente
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, janela por baixo
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Taxa de quadros do Cliente abaixo de [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Taxa de quadros do Cliente entre [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Causa possível: Distância de desenho ajustada muito alta
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Causa possível: Carregamento de Imagens
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Causa possível: Muitas imagens na memória
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Causa possível: Muitos objetos complexos na cena
- </floater.string>
- <floater.string name="network_text_msg">
- Rede
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Conexão está caindo para cerca de [NETWORK_PACKET_LOSS_CRITICAL]% de pacotes
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Conexão está caindo [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de pacotes
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Tempo de conexão de ping é cerca de [NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Tempo de conexão de ping é [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Possível conexão ruim ou &apos;Largura de Banda&apos; escolhida muito alta.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Possível conexão ruim ou aplicativos compartilhando arquivos.
- </floater.string>
- <floater.string name="server_text_msg">
- Servidor
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Taxa de quadros abaixo de [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Taxa de quadros entre [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Causa possível: Muitos objetos físicos
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Causa possível: Muitos objetos com scripts
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Causa possível: Muito tráfego na rede
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Causa possível: Muitas pessoas se movendo na região
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Causa possível: Muitos cálculos de imagem
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Causa possível: Carga no simulador muito pesada
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button label="" label_selected="" name="client_lagmeter" tool_tip="Status de atraso no Cliente"/>
- <text name="client">
- Cliente
- </text>
- <text font="SansSerifSmall" name="client_text">
- Normal
- </text>
- <text left="30" name="client_lag_cause" right="-10"/>
- <button label="" label_selected="" name="network_lagmeter" tool_tip="Status de atraso na rede"/>
- <text name="network">
- Rede
- </text>
- <text font="SansSerifSmall" name="network_text">
- Normal
- </text>
- <text left="30" name="network_lag_cause" right="-10"/>
- <button label="" label_selected="" name="server_lagmeter" tool_tip="Status de atraso no servidor"/>
- <text name="server">
- Servidor
- </text>
- <text font="SansSerifSmall" name="server_text">
- Normal
- </text>
- <text left="30" name="server_lag_cause" right="-32"/>
- <button label="&gt;&gt;" name="minimize" tool_tip="Alternar o tamanho da janela"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml b/indra/newview/skins/default/xui/ru/floater_lagmeter.xml
deleted file mode 100755
index c420006a03..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="УРОВЕНЬ ЛАГОВ">
- <floater.string name="max_title_msg">
- Уровень лагов
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Лаг
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- Клиент
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Нормально, окно в фоне
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- Частота кадров клиента ниже [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- Частота кадров клиента от [CLIENT_FRAME_RATE_CRITICAL] до [CLIENT_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Нормально
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Возможная причина: дальность отрисовки слишком велика
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Возможная причина: загрузка изображений
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Возможная причина: слишком много изображений в памяти
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Возможная причина: слишком много сложных объектов в сцене
- </floater.string>
- <floater.string name="network_text_msg">
- Сеть
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Сеть теряет более [NETWORK_PACKET_LOSS_CRITICAL]% пакетов
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Сеть теряет [NETWORK_PACKET_LOSS_WARNING]–[NETWORK_PACKET_LOSS_CRITICAL]% пакетов
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Нормально
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Пинг соединения более [NETWORK_PING_CRITICAL] мс
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Пинг соединения [NETWORK_PING_WARNING]–[NETWORK_PING_CRITICAL] мс
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Возможно, плохое соединение, или параметр «Ширина канала» слишком велик.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Возможно, плохое соединение или есть работающие файлообменные программы.
- </floater.string>
- <floater.string name="server_text_msg">
- Сервер
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Частота кадров сервера ниже [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Частота кадров сервера [SERVER_FRAME_RATE_CRITICAL]–[SERVER_FRAME_RATE_WARNING]
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Нормально
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Возможная причина: слишком много физических объектов
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Возможная причина: слишком много скриптовых объектов
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Возможная причина: слишком большой сетевой трафик
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Возможная причина: слишком много людей в регионе
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Возможная причина: слишком много изображений
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Возможная причина: сервер сильно загружен
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="Уровень лагов клиента"/>
- <text name="client">
- Клиент
- </text>
- <text name="client_text">
- Нормально
- </text>
- <button name="network_lagmeter" tool_tip="Уровень лагов сети"/>
- <text name="network">
- Сеть
- </text>
- <text name="network_text">
- Нормально
- </text>
- <button name="server_lagmeter" tool_tip="Уровень лагов сервера"/>
- <text name="server">
- Сервер
- </text>
- <text name="server_text">
- Нормально
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="Переключение размера"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml b/indra/newview/skins/default/xui/tr/floater_lagmeter.xml
deleted file mode 100755
index 736c50be90..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="GECİKME ÖLÇER">
- <floater.string name="max_title_msg">
- Gecikme Ölçer
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- Gecikme
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- İstemci
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- Normal, pencere alt zeminde
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] altında
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] ile [CLIENT_FRAME_RATE_WARNING] arasınad
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- Muhtemel neden: Çizme mesafesi çok yüksek
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- Muhtemel neden: Görüntüler yükleniyor
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- Muhtemel neden: Bellekte çok fazla görüntü
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- Muhtemel neden: Sahnede çok fazla karmaşık nesne
- </floater.string>
- <floater.string name="network_text_msg">
- Ağ
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- Bağlantı paketlerin % [NETWORK_PACKET_LOSS_CRITICAL]&apos;sinden fazlasını bırakıyor
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- Bağlantı paketlerin % [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]&apos;sini bırakıyor
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- Normal
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- Bağlantı ping süresi [NETWORK_PING_CRITICAL] ms.den fazla
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- Bağlantı ping süresi [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- Muhtemel yetersiz bağlantı veya &apos;Bant Genişliği&apos; tercihi çok yüksek.
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- Muhtemel yetersiz bağlantı veya dosya paylaşım uygulaması.
- </floater.string>
- <floater.string name="server_text_msg">
- Sunucu
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] altında
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] ve [SERVER_FRAME_RATE_WARNING] arasında
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- Normal
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- Muhtemel Neden: Çok fazla fiziki nesne
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- Muhtemel Neden: Çok fazla komut dosyalı nesne
- </floater.string>
- <floater.string name="server_net_cause_msg">
- Muhtemel Neden: Çok fazla ağ trafiği
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- Muhtemel Neden: Bölgede hareket eden çok fazla insan var
- </floater.string>
- <floater.string name="server_images_cause_msg">
- Muhtemel Neden: Çok fazla görüntü hesabı
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- Muhtemel Neden: Simülatör yükü çok ağır
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="İstemci gecikme durumu"/>
- <text name="client">
- İstemci
- </text>
- <text name="client_text">
- Normal
- </text>
- <button name="network_lagmeter" tool_tip="Ağ gecikme durumu"/>
- <text name="network">
- Ağ
- </text>
- <text name="network_text">
- Normal
- </text>
- <button name="server_lagmeter" tool_tip="Sunucu gecikme durumu"/>
- <text name="server">
- Sunucu
- </text>
- <text name="server_text">
- Normal
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="Gezdirici büyüklüğünü değiştir"/>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
deleted file mode 100755
index e9a082288a..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_lagmeter" title="LAG 測量器">
- <floater.string name="max_title_msg">
- Lag 測量器
- </floater.string>
- <floater.string name="max_width_px">
- 360
- </floater.string>
- <floater.string name="min_title_msg">
- 延遲
- </floater.string>
- <floater.string name="min_width_px">
- 90
- </floater.string>
- <floater.string name="client_text_msg">
- 客戶端
- </floater.string>
- <floater.string name="client_frame_rate_critical_fps">
- 10
- </floater.string>
- <floater.string name="client_frame_rate_warning_fps">
- 15
- </floater.string>
- <floater.string name="client_frame_time_window_bg_msg">
- 正常,視窗位於背景
- </floater.string>
- <floater.string name="client_frame_time_critical_msg">
- 客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="client_frame_time_warning_msg">
- 客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] 和 [CLIENT_FRAME_RATE_WARNING] 之間
- </floater.string>
- <floater.string name="client_frame_time_normal_msg">
- 正常
- </floater.string>
- <floater.string name="client_draw_distance_cause_msg">
- 可能原因:可視距離設得太遠
- </floater.string>
- <floater.string name="client_texture_loading_cause_msg">
- 可能原因:正在載入圖像
- </floater.string>
- <floater.string name="client_texture_memory_cause_msg">
- 可能原因:記憶體裡圖像太多
- </floater.string>
- <floater.string name="client_complex_objects_cause_msg">
- 可能原因:場景內複雜物件太多
- </floater.string>
- <floater.string name="network_text_msg">
- 網路
- </floater.string>
- <floater.string name="network_packet_loss_critical_pct">
- 10
- </floater.string>
- <floater.string name="network_packet_loss_warning_pct">
- 5
- </floater.string>
- <floater.string name="network_packet_loss_critical_msg">
- 這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% 的封包
- </floater.string>
- <floater.string name="network_packet_loss_warning_msg">
- 這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% 的封包
- </floater.string>
- <floater.string name="network_performance_normal_msg">
- 正常
- </floater.string>
- <floater.string name="network_ping_critical_ms">
- 600
- </floater.string>
- <floater.string name="network_ping_warning_ms">
- 300
- </floater.string>
- <floater.string name="network_ping_critical_msg">
- 探測連通回應時間超過 [NETWORK_PING_CRITICAL] 毫秒
- </floater.string>
- <floater.string name="network_ping_warning_msg">
- 探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒
- </floater.string>
- <floater.string name="network_packet_loss_cause_msg">
- 可能連通不良,或所設的偏好連通頻寬過高。
- </floater.string>
- <floater.string name="network_ping_cause_msg">
- 可能連通不良,或使用檔案分享應用程式。
- </floater.string>
- <floater.string name="server_text_msg">
- 伺服器
- </floater.string>
- <floater.string name="server_frame_rate_critical_fps">
- 20
- </floater.string>
- <floater.string name="server_frame_rate_warning_fps">
- 30
- </floater.string>
- <floater.string name="server_single_process_max_time_ms">
- 20
- </floater.string>
- <floater.string name="server_frame_time_critical_msg">
- 模擬器 framerate 低於 [SERVER_FRAME_RATE_CRITICAL]
- </floater.string>
- <floater.string name="server_frame_time_warning_msg">
- 模擬器 framerate 介於 [SERVER_FRAME_RATE_CRITICAL] 與 [SERVER_FRAME_RATE_WARNING] 之間
- </floater.string>
- <floater.string name="server_frame_time_normal_msg">
- 正常
- </floater.string>
- <floater.string name="server_physics_cause_msg">
- 可能原因:太多物理物件
- </floater.string>
- <floater.string name="server_scripts_cause_msg">
- 可能原因:太多腳本物件
- </floater.string>
- <floater.string name="server_net_cause_msg">
- 可能原因:太多網路流量
- </floater.string>
- <floater.string name="server_agent_cause_msg">
- 可能原因:地區有太多移動的人
- </floater.string>
- <floater.string name="server_images_cause_msg">
- 可能原因:太多圖像計算
- </floater.string>
- <floater.string name="server_generic_cause_msg">
- 可能原因:模擬器負載過重
- </floater.string>
- <floater.string name="smaller_label">
- &gt;&gt;
- </floater.string>
- <floater.string name="bigger_label">
- &lt;&lt;
- </floater.string>
- <button name="client_lagmeter" tool_tip="客戶端 lag 狀態"/>
- <text name="client">
- 客戶端
- </text>
- <text name="client_text">
- 正常
- </text>
- <button name="network_lagmeter" tool_tip="網路 lag 狀態"/>
- <text name="network">
- 網路
- </text>
- <text name="network_text">
- 正常
- </text>
- <button name="server_lagmeter" tool_tip="伺服器 lag 狀態"/>
- <text name="server">
- 伺服器
- </text>
- <text name="server_text">
- 正常
- </text>
- <button label="&gt;&gt;" name="minimize" tool_tip="切換浮動視窗尺寸"/>
-</floater>
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index a331d9aa9e..b9712e5e9c 100755
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -37,6 +37,35 @@
#include "llregionhandle.h"
#include "../llvoavatar.h"
+namespace LLStatViewer
+{
+ LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample");
+}
+
+void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
+{
+ counts.resize(3);
+ counts[0] = 0;
+ counts[1] = 0;
+ counts[2] = 1;
+}
+
+// static
+std::string LLVOAvatar::rezStatusToString(S32 rez_status)
+{
+ if (rez_status==0) return "cloud";
+ if (rez_status==1) return "gray";
+ if (rez_status==2) return "textured";
+ return "unknown";
+}
+
+// static
+LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
+{
+ static LLViewerStats::StatsAccumulator junk;
+ return junk;
+}
+
static const char * all_keys[] =
{
"duration",
@@ -199,7 +228,18 @@ get_region(const LLSD & sd, U64 region_handle1)
namespace tut
{
struct tst_viewerassetstats_index
- {};
+ {
+ tst_viewerassetstats_index()
+ {
+ LLTrace::init();
+ }
+
+ ~tst_viewerassetstats_index()
+ {
+ LLTrace::cleanup();
+ }
+
+ };
typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t;
typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t;
tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test");
@@ -209,24 +249,24 @@ namespace tut
void tst_viewerassetstats_index_object_t::test<1>()
{
// Check that helpers aren't bothered by missing global stats
- ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
+ ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL);
+ LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL);
}
// Create a non-global instance and check the structure
template<> template<>
void tst_viewerassetstats_index_object_t::test<2>()
{
- ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
+ ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));
LLViewerAssetStats * it = new LLViewerAssetStats();
- ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain));
+ ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));
LLSD sd_full = it->asLLSD(false);
@@ -293,16 +333,17 @@ namespace tut
template<> template<>
void tst_viewerassetstats_index_object_t::test<4>()
{
- gViewerAssetStatsMain = new LLViewerAssetStats();
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ gViewerAssetStats = new LLViewerAssetStats();
+ LLViewerAssetStatsFF::set_region(region1_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
- LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->updateStats();
+ LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
sd = sd["regions"][0];
@@ -316,80 +357,39 @@ namespace tut
// Reset and check zeros...
// Reset leaves current region in place
- gViewerAssetStatsMain->reset();
- sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str];
+ gViewerAssetStats->reset();
+ sd = gViewerAssetStats->asLLSD(false)["regions"][region1_handle_str];
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = NULL;
+ delete gViewerAssetStats;
+ gViewerAssetStats = NULL;
ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
}
- // Create two global instances and verify no interactions
+ // Check multiple region collection
template<> template<>
void tst_viewerassetstats_index_object_t::test<5>()
{
- gViewerAssetStatsThread1 = new LLViewerAssetStats();
- gViewerAssetStatsMain = new LLViewerAssetStats();
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ gViewerAssetStats = new LLViewerAssetStats();
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::set_region(region1_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
- ensure("Other collector is empty", is_no_stats_map(sd));
- sd = gViewerAssetStatsMain->asLLSD(false);
- ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
- ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
- sd = sd["regions"][0];
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
- // Check a few points on the tree for content
- ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
- ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger()));
- ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger()));
- ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger()));
- ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
-
- // Reset and check zeros...
- // Reset leaves current region in place
- gViewerAssetStatsMain->reset();
- sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0];
-
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = NULL;
- delete gViewerAssetStatsThread1;
- gViewerAssetStatsThread1 = NULL;
-
- ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
- ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
- }
-
- // Check multiple region collection
- template<> template<>
- void tst_viewerassetstats_index_object_t::test<6>()
- {
- gViewerAssetStatsMain = new LLViewerAssetStats();
-
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ LLViewerAssetStatsFF::set_region(region2_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
-
- LLViewerAssetStatsFF::set_region_main(region2_handle);
-
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
-
- LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->updateStats();
+ LLSD sd = gViewerAssetStats->asLLSD(false);
// std::cout << sd << std::endl;
@@ -414,14 +414,14 @@ namespace tut
// Reset and check zeros...
// Reset leaves current region in place
- gViewerAssetStatsMain->reset();
- sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->reset();
+ sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
sd2 = sd["regions"][0];
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = NULL;
+ delete gViewerAssetStats;
+ gViewerAssetStats = NULL;
ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
@@ -429,41 +429,42 @@ namespace tut
// Check multiple region collection jumping back-and-forth between regions
template<> template<>
- void tst_viewerassetstats_index_object_t::test<7>()
+ void tst_viewerassetstats_index_object_t::test<6>()
{
- gViewerAssetStatsMain = new LLViewerAssetStats();
+ gViewerAssetStats = new LLViewerAssetStats();
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ LLViewerAssetStatsFF::set_region(region1_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::set_region_main(region2_handle);
+ LLViewerAssetStatsFF::set_region(region2_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ LLViewerAssetStatsFF::set_region(region1_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, true, true);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, true, true);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::set_region_main(region2_handle);
+ LLViewerAssetStatsFF::set_region(region2_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false);
- LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->updateStats();
+ LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
@@ -486,15 +487,15 @@ namespace tut
// Reset and check zeros...
// Reset leaves current region in place
- gViewerAssetStatsMain->reset();
- sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->reset();
+ sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
sd2 = get_region(sd, region2_handle);
ensure("Region2 is present in results", sd2.isMap());
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = NULL;
+ delete gViewerAssetStats;
+ gViewerAssetStats = NULL;
ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0);
@@ -502,38 +503,36 @@ namespace tut
// Non-texture assets ignore transport and persistence flags
template<> template<>
- void tst_viewerassetstats_index_object_t::test<8>()
+ void tst_viewerassetstats_index_object_t::test<7>()
{
- gViewerAssetStatsThread1 = new LLViewerAssetStats();
- gViewerAssetStatsMain = new LLViewerAssetStats();
- LLViewerAssetStatsFF::set_region_main(region1_handle);
+ gViewerAssetStats = new LLViewerAssetStats();
+ LLViewerAssetStatsFF::set_region(region1_handle);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, true);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, true);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, false);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true);
- LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, true);
+ LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, true);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, true);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, false);
- LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+ LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
- ensure("Other collector is empty", is_no_stats_map(sd));
- sd = gViewerAssetStatsMain->asLLSD(false);
+ gViewerAssetStats->updateStats();
+ LLSD sd = gViewerAssetStats->asLLSD(false);
ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
sd = get_region(sd, region1_handle);
@@ -551,445 +550,14 @@ namespace tut
// Reset and check zeros...
// Reset leaves current region in place
- gViewerAssetStatsMain->reset();
- sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle);
+ gViewerAssetStats->reset();
+ sd = get_region(gViewerAssetStats->asLLSD(false), region1_handle);
ensure("Region1 is present in results", sd.isMap());
- delete gViewerAssetStatsMain;
- gViewerAssetStatsMain = NULL;
- delete gViewerAssetStatsThread1;
- gViewerAssetStatsThread1 = NULL;
+ delete gViewerAssetStats;
+ gViewerAssetStats = NULL;
ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0);
}
-
-
- // LLViewerAssetStats::merge() basic functions work
- template<> template<>
- void tst_viewerassetstats_index_object_t::test<9>()
- {
- LLViewerAssetStats s1;
- LLViewerAssetStats s2;
-
- s1.setRegion(region1_handle);
- s2.setRegion(region1_handle);
-
- s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000);
- s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000);
- s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000);
- s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000);
- s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000);
-
- s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000);
- s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000);
- s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000);
-
- s2.merge(s1);
-
- LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle);
- ensure("Region1 is present in results", s2_llsd.isMap());
-
- ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8);
- ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22);
- ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22);
- ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22);
- }
-
- // LLViewerAssetStats::merge() basic functions work without corrupting source data
- template<> template<>
- void tst_viewerassetstats_index_object_t::test<10>()
- {
- LLViewerAssetStats s1;
- LLViewerAssetStats s2;
-
- s1.setRegion(region1_handle);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900);
-
-
- s2.setRegion(region2_handle);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000);
- s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000);
-
- {
- s2.merge(s1);
-
- LLSD src = s1.asLLSD(false);
- LLSD dst = s2.asLLSD(false);
-
- ensure_equals("merge src has single region", src["regions"].size(), 1);
- ensure_equals("merge dst has dual regions", dst["regions"].size(), 2);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
- dst["regions"][1].erase("duration");
-
- LLSD s1_llsd = get_region(src, region1_handle);
- ensure("Region1 is present in src", s1_llsd.isMap());
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd));
- }
-
- s1.setRegion(region1_handle);
- s2.setRegion(region1_handle);
- s1.reset();
- s2.reset();
-
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900);
-
-
- s2.setRegion(region1_handle);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000);
- s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000);
-
- {
- s2.merge(s1);
-
- LLSD src = s1.asLLSD(false);
- LLSD dst = s2.asLLSD(false);
-
- ensure_equals("merge src has single region (p2)", src["regions"].size(), 1);
- ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
-
- LLSD s1_llsd = get_region(src, region1_handle);
- ensure("Region1 is present in src", s1_llsd.isMap());
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4);
- ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4);
- ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2);
- ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20);
- ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20);
-
- ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12);
- ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11);
- ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4);
- ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20);
- ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20);
- }
- }
-
-
- // Maximum merges are interesting when one side contributes nothing
- template<> template<>
- void tst_viewerassetstats_index_object_t::test<11>()
- {
- LLViewerAssetStats s1;
- LLViewerAssetStats s2;
-
- s1.setRegion(region1_handle);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- // Want to test negative numbers here but have to work in U64
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
-
- s2.setRegion(region1_handle);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- {
- s2.merge(s1);
-
- LLSD src = s1.asLLSD(false);
- LLSD dst = s2.asLLSD(false);
-
- ensure_equals("merge src has single region", src["regions"].size(), 1);
- ensure_equals("merge dst has single region", dst["regions"].size(), 1);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
-
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
-
- ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum",
- s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20);
- }
-
- // Other way around
- s1.setRegion(region1_handle);
- s2.setRegion(region1_handle);
- s1.reset();
- s2.reset();
-
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- // Want to test negative numbers here but have to work in U64
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
-
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- {
- s1.merge(s2);
-
- LLSD src = s2.asLLSD(false);
- LLSD dst = s1.asLLSD(false);
-
- ensure_equals("merge src has single region", src["regions"].size(), 1);
- ensure_equals("merge dst has single region", dst["regions"].size(), 1);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
-
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
-
- ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)",
- s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20);
- }
- }
-
- // Minimum merges are interesting when one side contributes nothing
- template<> template<>
- void tst_viewerassetstats_index_object_t::test<12>()
- {
- LLViewerAssetStats s1;
- LLViewerAssetStats s2;
-
- s1.setRegion(region1_handle);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000);
-
- s2.setRegion(region1_handle);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- {
- s2.merge(s1);
-
- LLSD src = s1.asLLSD(false);
- LLSD dst = s2.asLLSD(false);
-
- ensure_equals("merge src has single region", src["regions"].size(), 1);
- ensure_equals("merge dst has single region", dst["regions"].size(), 1);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
-
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
-
- ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum",
- s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20);
- }
-
- // Other way around
- s1.setRegion(region1_handle);
- s2.setRegion(region1_handle);
- s1.reset();
- s2.reset();
-
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000);
- s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000);
-
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
- s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
-
- {
- s1.merge(s2);
-
- LLSD src = s2.asLLSD(false);
- LLSD dst = s1.asLLSD(false);
-
- ensure_equals("merge src has single region", src["regions"].size(), 1);
- ensure_equals("merge dst has single region", dst["regions"].size(), 1);
-
- // Remove time stamps, they're a problem
- src.erase("duration");
- src["regions"][0].erase("duration");
- dst.erase("duration");
- dst["regions"][0].erase("duration");
-
- LLSD s2_llsd = get_region(dst, region1_handle);
- ensure("Region1 is present in dst", s2_llsd.isMap());
-
- ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
-
- ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)",
- s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20);
- }
- }
-
}
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 31e1d89c68..62b1d9db62 100755
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -56,7 +56,6 @@ set(test_SOURCE_FILES
llstreamtools_tut.cpp
lltemplatemessagebuilder_tut.cpp
lltut.cpp
- lluuidhashmap_tut.cpp
message_tut.cpp
test.cpp
)
diff --git a/indra/test/io.cpp b/indra/test/io.cpp
index e776a2a3be..261422e9fc 100755
--- a/indra/test/io.cpp
+++ b/indra/test/io.cpp
@@ -44,6 +44,7 @@
#include "llsdrpcclient.h"
#include "llsdrpcserver.h"
#include "llsdserialize.h"
+#include "llcommon.h"
#include "lluuid.h"
#include "llinstantmessage.h"
@@ -1187,7 +1188,9 @@ namespace tut
mResponsePtr(response)
{
}
- ~LLSimpleRPCResponse() {}
+ ~LLSimpleRPCResponse()
+ {
+ }
virtual bool response(LLPumpIO* pump)
{
*mResponsePtr = mReturnValue;
diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp
index 46684bb9dc..ecf734ee90 100755
--- a/indra/test/llhttpdate_tut.cpp
+++ b/indra/test/llhttpdate_tut.cpp
@@ -29,6 +29,7 @@
#include "lltut.h"
#include "lldate.h"
+#include "llcommon.h"
#include "llframetimer.h"
#include <time.h>
@@ -38,6 +39,12 @@ namespace tut
{
struct httpdate_data
{
+ httpdate_data()
+ {
+ }
+ ~httpdate_data()
+ {
+ }
LLDate some_date;
};
typedef test_group<httpdate_data> httpdate_test;
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp
index 2fdc455f45..3fa5c8dd42 100755
--- a/indra/test/lliohttpserver_tut.cpp
+++ b/indra/test/lliohttpserver_tut.cpp
@@ -31,6 +31,7 @@
#include "lliohttpserver.h"
#include "llsdhttpserver.h"
#include "llsdserialize.h"
+#include "llcommon.h"
#include "llpipeutil.h"
@@ -81,6 +82,10 @@ namespace tut
mRoot.addNode("/delayed/echo", new DelayedEcho(this));
mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>);
}
+
+ ~HTTPServiceTestData()
+ {
+ }
LLHTTPNode mRoot;
LLHTTPNode::ResponsePtr mResponse;
diff --git a/indra/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp
deleted file mode 100755
index 9712a613f4..0000000000
--- a/indra/test/lluuidhashmap_tut.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/**
- * @file lluuidhashmap_tut.cpp
- * @author Adroit
- * @date 2007-02
- * @brief Test cases for LLUUIDHashMap
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include <tut/tut.hpp>
-#include "linden_common.h"
-#include "lluuidhashmap.h"
-#include "llsdserialize.h"
-#include "lldir.h"
-#include "stringize.h"
-#include <iostream>
-#include <fstream>
-
-namespace tut
-{
- class UUIDTableEntry
- {
- public:
- UUIDTableEntry()
- {
- mID.setNull();
- mValue = 0;
- }
-
- UUIDTableEntry(const LLUUID& id, U32 value)
- {
- mID = id;
- mValue = value;
- }
-
- ~UUIDTableEntry(){};
-
- static BOOL uuidEq(const LLUUID &uuid, const UUIDTableEntry &id_pair)
- {
- if (uuid == id_pair.mID)
- {
- return TRUE;
- }
- return FALSE;
- }
-
- const LLUUID& getID() { return mID; }
- const U32& getValue() { return mValue; }
-
- protected:
- LLUUID mID;
- U32 mValue;
- };
-
- struct hashmap_test
- {
- };
-
- typedef test_group<hashmap_test> hash_index_t;
- typedef hash_index_t::object hash_index_object_t;
- tut::hash_index_t tut_hash_index("hashmap_test");
-
- // stress test
- template<> template<>
- void hash_index_object_t::test<1>()
- {
- set_test_name("stress test");
- // As of 2012-10-10, I (nat) have observed sporadic failures of this
- // test: "set/get did not work." The trouble is that since test data
- // are randomly generated with every run, it is impossible to debug a
- // test failure. One is left with the uneasy suspicion that
- // LLUUID::generate() can sometimes produce duplicates even within the
- // moderately small number requested here. Since rerunning the test
- // generally allows it to pass, it's too easy to shrug and forget it.
- // The following code is intended to support reproducing such test
- // failures. The idea is that, on test failure, we save the generated
- // data to a canonical filename in a temp directory. Then on every
- // subsequent run, we check for that filename. If it exists, we reload
- // that specific data rather than generating fresh data -- which
- // should presumably reproduce the same test failure. But we inform
- // the user that to resume normal (random) test runs, s/he need only
- // delete that file. And since it's in a temp directory, sooner or
- // later the system will clean it up anyway.
- const char* tempvar = "TEMP";
- const char* tempdir = getenv(tempvar); // Windows convention
- if (! tempdir)
- {
- tempvar = "TMPDIR";
- tempdir = getenv(tempvar); // Mac convention
- }
- if (! tempdir)
- {
- // reset tempvar to the first var we check; it's just a
- // recommendation
- tempvar = "TEMP";
- tempdir = "/tmp"; // Posix in general
- }
- std::string savefile(gDirUtilp->add(tempdir, "lluuidhashmap_tut.save.txt"));
- const int numElementsToCheck = 32*256*32;
- std::vector<LLUUID> idList;
- if ((! getenv("TEAMCITY_PROJECT_NAME")) && gDirUtilp->fileExists(savefile))
- {
- // This is not a TeamCity build, and we have saved data from a
- // previous failed run. Reload that data.
- std::ifstream inf(savefile.c_str());
- if (! inf.is_open())
- {
- fail(STRINGIZE("Although save file '" << savefile << "' exists, it cannot be opened"));
- }
- std::string item;
- while (std::getline(inf, item))
- {
- idList.push_back(LLUUID(item));
- }
- std::cout << "Reloaded " << idList.size() << " items from '" << savefile << "'";
- if (idList.size() != numElementsToCheck)
- {
- std::cout << " (expected " << numElementsToCheck << ")";
- }
- std::cout << " -- delete this file to generate new data" << std::endl;
- }
- else
- {
- // This is a TeamCity build, or (normal case) savefile does not
- // exist: regenerate idList from scratch.
- for (int i = 0; i < numElementsToCheck; ++i)
- {
- LLUUID id;
- id.generate();
- idList.push_back(id);
- }
- }
-
- LLUUIDHashMap<UUIDTableEntry, 32> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- int i;
-
- for (i = 0; i < idList.size(); ++i)
- {
- UUIDTableEntry entry(idList[i], i);
- hashTable.set(idList[i], entry);
- }
-
- try
- {
- for (i = 0; i < idList.size(); i++)
- {
- LLUUID idToCheck = idList[i];
- UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
- ensure_equals(STRINGIZE("set/get ID (entry " << i << ")").c_str(),
- entryToCheck.getID(), idToCheck);
- ensure_equals(STRINGIZE("set/get value (ID " << idToCheck << ")").c_str(),
- entryToCheck.getValue(), (size_t)i);
- }
-
- for (i = 0; i < idList.size(); i++)
- {
- LLUUID idToCheck = idList[i];
- if (i % 2 != 0)
- {
- hashTable.remove(idToCheck);
- }
- }
-
- for (i = 0; i < idList.size(); i++)
- {
- LLUUID idToCheck = idList[i];
- ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
- }
- }
- catch (const failure&)
- {
- // One of the above tests failed. Try to save idList to repro with
- // a later run.
- std::ofstream outf(savefile.c_str());
- if (! outf.is_open())
- {
- // Sigh, don't use fail() here because we want to preserve
- // the original test failure.
- std::cout << "Cannot open file '" << savefile
- << "' to save data -- check and fix " << tempvar << std::endl;
- }
- else
- {
- // outf.is_open()
- for (int i = 0; i < idList.size(); ++i)
- {
- outf << idList[i] << std::endl;
- }
- std::cout << "Saved " << idList.size() << " entries to '" << savefile
- << "' -- rerun test to debug with these" << std::endl;
- }
- // re-raise the same exception -- we WANT this test failure to
- // be reported! We just needed to save the data on the way out.
- throw;
- }
- }
-
- // test removing all but one element.
- template<> template<>
- void hash_index_object_t::test<2>()
- {
- LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- const int numElementsToCheck = 5;
- std::vector<LLUUID> idList(numElementsToCheck*10);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
- }
-
- ensure("getLength failed", hashTable.getLength() == numElementsToCheck);
-
- // remove all but the last element
- for (i = 0; i < numElementsToCheck-1; i++)
- {
- LLUUID idToCheck = idList[i];
- hashTable.remove(idToCheck);
- }
-
- // there should only be one element left now.
- ensure("getLength failed", hashTable.getLength() == 1);
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID idToCheck = idList[i];
- if (i != numElementsToCheck - 1)
- {
- ensure("remove did not work", hashTable.check(idToCheck) == FALSE);
- }
- else
- {
- UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
- ensure("remove did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
- }
- }
- }
-
- // test overriding of value already set.
- template<> template<>
- void hash_index_object_t::test<3>()
- {
- LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- const int numElementsToCheck = 10;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
- }
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id = idList[i];
- // set new entry with value = i+numElementsToCheck
- UUIDTableEntry entry(id, i+numElementsToCheck);
- hashTable.set(id, entry);
- }
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID idToCheck = idList[i];
- UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
- ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)(i+numElementsToCheck));
- }
- }
-
- // test removeAll()
- template<> template<>
- void hash_index_object_t::test<4>()
- {
- LLUUIDHashMap<UUIDTableEntry, 5> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- const int numElementsToCheck = 10;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
- }
-
- hashTable.removeAll();
- ensure("removeAll failed", hashTable.getLength() == 0);
- }
-
-
- // test sparse map - force it by creating 256 entries that fall into 256 different nodes
- template<> template<>
- void hash_index_object_t::test<5>()
- {
- LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- const int numElementsToCheck = 256;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- // LLUUIDHashMap uses mData[0] to pick the bucket
- // overwrite mData[0] so that it ranges from 0 to 255
- id.mData[0] = i;
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
- }
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID idToCheck = idList[i];
- UUIDTableEntry entryToCheck = hashTable.get(idToCheck);
- ensure("set/get did not work for sparse map", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i);
- }
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID idToCheck = idList[i];
- if (i % 2 != 0)
- {
- hashTable.remove(idToCheck);
- }
- }
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID idToCheck = idList[i];
- ensure("remove or check did not work for sparse map", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck)));
- }
- }
-
- // iterator
- template<> template<>
- void hash_index_object_t::test<6>()
- {
- LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
- const int numElementsToCheck = 256;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- // LLUUIDHashMap uses mData[0] to pick the bucket
- // overwrite mData[0] so that it ranges from 0 to 255
- // to create a sparse map
- id.mData[0] = i;
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
- }
-
- hashIter.first();
- int numElementsIterated = 0;
- while(!hashIter.done())
- {
- numElementsIterated++;
- UUIDTableEntry tableEntry = *hashIter;
- LLUUID id = tableEntry.getID();
- hashIter.next();
- ensure("Iteration failed for sparse map", tableEntry.getValue() < (size_t)numElementsToCheck && idList[tableEntry.getValue()] == tableEntry.getID());
- }
-
- ensure("iteration count failed", numElementsIterated == numElementsToCheck);
- }
-
- // remove after middle of iteration
- template<> template<>
- void hash_index_object_t::test<7>()
- {
- LLUUIDHashMap<UUIDTableEntry, 2> hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry());
- LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable);
- const int numElementsToCheck = 256;
- std::vector<LLUUID> idList(numElementsToCheck);
- int i;
-
- LLUUID uuidtoSearch;
- for (i = 0; i < numElementsToCheck; i++)
- {
- LLUUID id;
- id.generate();
- // LLUUIDHashMap uses mData[0] to pick the bucket
- // overwrite mData[0] so that it ranges from 0 to 255
- // to create a sparse map
- id.mData[0] = i;
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
-
- // pick uuid somewhere in the middle
- if (i == 5)
- {
- uuidtoSearch = id;
- }
- }
-
- hashIter.first();
- int numElementsIterated = 0;
- while(!hashIter.done())
- {
- numElementsIterated++;
- UUIDTableEntry tableEntry = *hashIter;
- LLUUID id = tableEntry.getID();
- if (uuidtoSearch == id)
- {
- break;
- }
- hashIter.next();
- }
-
- // current iterator implementation will not allow any remove operations
- // until ALL elements have been iterated over. this seems to be
- // an unnecessary restriction. Iterator should have a method to
- // reset() its state so that further operations (inckuding remove)
- // can be performed on the HashMap without having to iterate thru
- // all the remaining nodes.
-
-// hashIter.reset();
-// hashTable.remove(uuidtoSearch);
-// ensure("remove after iteration reset failed", hashTable.check(uuidtoSearch) == FALSE);
- }
-}
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index dc8580fe69..28de88201c 100755
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -40,6 +40,7 @@
#include "tests/wrapllerrs.h" // RecorderProxy
#include "stringize.h"
#include "namedtempfile.h"
+#include "lltrace.h"
#include "apr_pools.h"
#include "apr_getopt.h"
@@ -512,15 +513,11 @@ int main(int argc, char **argv)
ctype_workaround();
#endif
- apr_initialize();
- apr_pool_t* pool = NULL;
- if(APR_SUCCESS != apr_pool_create(&pool, NULL))
- {
- std::cerr << "Unable to initialize pool" << std::endl;
- return 1;
- }
+ ll_init_apr();
+
+ LLTrace::init();
apr_getopt_t* os = NULL;
- if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
+ if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv))
{
std::cerr << "apr_getopt_init() failed" << std::endl;
return 1;
@@ -602,7 +599,7 @@ int main(int argc, char **argv)
if (LOGFAIL)
{
LLError::ELevel level = LLError::decodeLevel(LOGFAIL);
- replayer.reset(new LLReplayLogReal(level, pool));
+ replayer.reset(new LLReplayLogReal(level, gAPRPoolp));
}
else
{
@@ -646,7 +643,7 @@ int main(int argc, char **argv)
s.close();
}
- apr_terminate();
+ ll_cleanup_apr();
int retval = (success ? 0 : 1);
return retval;
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 884b00f0cc..fa4f5abd28 100755
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -37,6 +37,12 @@
#include "llmediaplugintest.h"
+
+#if LL_WINDOWS
+#pragma warning(disable: 4263)
+#pragma warning(disable: 4264)
+#endif
+
#if __APPLE__
#include <GLUT/glut.h>
#include <CoreFoundation/CoreFoundation.h>
@@ -46,10 +52,6 @@
#define GLUI_FREEGLUT
#endif
-#if LL_WINDOWS
-#pragma warning(disable: 4263)
-#pragma warning(disable: 4264)
-#endif
#include "glui.h"