diff --git a/README.md b/README.md
index e78a22fd54..a60954a276 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
-
+
-**[Firestorm](https://www.firestormviewer.org/) is a free client for 3D virtual worlds such as Second Life and various OpenSim worlds where users can create, connect and chat with others from around the world.** This repository contains the official source code for the Firestorm viewer.
+**[Firestorm](https://www.firestormviewer.org) is a free client for 3D virtual worlds such as Second Life and various OpenSim worlds where users can create, connect and chat with others from around the world.**
+
+This repository contains the official source code for the Firestorm viewer.
## Open Source
@@ -12,7 +14,7 @@ Pre-built versions of the viewer releases for Windows, Mac and Linux can be down
## Build Instructions
-Build instructions for each operating system can be found using the links below and in the official [wiki](https://wiki.firestormviewer.org/).
+Build instructions for each operating system can be found using the links below and in the official [wiki](https://wiki.firestormviewer.org).
- [Windows](doc/building_windows.md)
- [Mac](doc/building_macos.md)
diff --git a/indra/llimage/llimagefilter.cpp b/indra/llimage/llimagefilter.cpp
index 1703e30dbe..da3519e3ab 100644
--- a/indra/llimage/llimagefilter.cpp
+++ b/indra/llimage/llimagefilter.cpp
@@ -88,7 +88,7 @@ void LLImageFilter::executeFilter(LLPointer raw_image)
{
mImage = raw_image;
- LLImageDataLock lock(mImage);
+ LLImageDataSharedLock lock(mImage); // FIRE-34564 Bugsplat SHARED vs EXCLUSIVE lock conflict
//std::cout << "Filter : size = " << mFilterData.size() << std::endl;
for (S32 i = 0; i < mFilterData.size(); ++i)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ca52fa1203..58619e6191 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2256,6 +2256,7 @@ if (WINDOWS)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=$
"--channel=${VIEWER_CHANNEL}"
@@ -2319,6 +2320,7 @@ if (WINDOWS)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=$
"--channel=${VIEWER_CHANNEL}"
@@ -2504,6 +2506,7 @@ if (LINUX)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -2531,6 +2534,7 @@ if (LINUX)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
@@ -2626,6 +2630,7 @@ if (DARWIN)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=$
--bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
@@ -2663,6 +2668,7 @@ if (DARWIN)
"--fmodstudio=${USE_FMODSTUDIO}"
"--openal=${USE_OPENAL}"
"--tracy=${USE_TRACY}"
+ "--avx2=${USE_AVX2_OPTIMIZATION}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
diff --git a/indra/newview/fs_viewer_manifest.py b/indra/newview/fs_viewer_manifest.py
index d6666d0fef..8093f9d3f6 100644
--- a/indra/newview/fs_viewer_manifest.py
+++ b/indra/newview/fs_viewer_manifest.py
@@ -4,18 +4,25 @@ import tarfile
class FSViewerManifest:
def fs_installer_basename(self):
+ if self.fs_is_avx2():
+ opt_string = "AVX2"
+ else:
+ opt_string = "LEGACY"
substitution_strings = {
'version' : '.'.join(self.args['version']),
'version_short' : '.'.join(self.args['version'][:-1]),
'version_dashes' : '-'.join(self.args['version']),
'app_name':self.app_name(),
+ 'optimized': opt_string,
'app_name_oneword':self.app_name_oneword()
}
- return "Phoenix-%(app_name)s-%(version_dashes)s" % substitution_strings
+ return "Phoenix-%(app_name)s_%(optimized)s-%(version_dashes)s" % substitution_strings
def fs_is_opensim(self):
return self.args['viewer_flavor'] == 'oss' #Havok would be hvk
+ def fs_is_avx2(self):
+ return self.args['avx2'] == 'ON'
def fs_splice_grid_substitution_strings( self, subst_strings ):
ret = subst_strings
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index bb62d35b1d..e0c515917b 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -32,7 +32,7 @@ SetCompressor /solid lzma # Compress whole installer as one block
SetDatablockOptimize off # Only saves us 0.1%, not worth it
XPStyle on # Add an XP manifest to the installer
RequestExecutionLevel admin # For when we write to Program Files
-Unicode true # Enable unicode support
+Unicode true # Enable unicode support
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Project flags
@@ -181,6 +181,42 @@ Function dirPre
FunctionEnd
+; Add the AVX2 check functions
+Function CheckCPUFlagsAVX2
+ Push $1
+ System::Call 'kernel32::IsProcessorFeaturePresent(i 40) i .r1' ; 40 is PF_AVX2_INSTRUCTIONS_AVAILABLE
+ IntCmp $1 1 OK_AVX2
+ ; AVX2 not supported
+ MessageBox MB_OK $(MissingAVX2)
+ Quit
+
+ OK_AVX2:
+ Pop $1
+ Return
+FunctionEnd
+
+Function CheckCPUFlagsAVX2_Prompt
+ Push $1
+ System::Call 'kernel32::IsProcessorFeaturePresent(i 40) i .r1' ; 40 is PF_AVX2_INSTRUCTIONS_AVAILABLE
+ IntCmp $1 1 OK_AVX2 Not_AVX2
+
+ OK_AVX2:
+ MessageBox MB_YESNO $(AVX2Available) IDYES DownloadAVX2 IDNO ContinueInstall
+ DownloadAVX2:
+ ExecShell open 'https://www.firestormviewer.org/early-access-beta-downloads/'
+ Quit
+ ContinueInstall:
+ Goto End
+
+ Not_AVX2:
+ ; CPU does not support AVX2, continue installation
+ Goto End
+
+ End:
+ Pop $1
+ Return
+FunctionEnd
+
# Optional start menu entry
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Post-directory page callback
@@ -224,6 +260,12 @@ ${If} $0 != ""
${EndIf}
Call CheckCPUFlags # Make sure we have SSE2 support
+${If} ${ISAVX2} == 1
+ Call CheckCPUFlagsAVX2
+${Else}
+ Call CheckCPUFlagsAVX2_Prompt
+${EndIf}
+
Call CheckWindowsVersion # Don't install On unsupported systems
Push $0
${GetParameters} $COMMANDLINE # Get our command line
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 164f165f50..a11e4d505a 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
@@ -57,6 +57,8 @@ LangString CheckAdministratorUnInstMB ${LANG_GERMAN} 'Sie besitzen ungenügende
; checkcpuflags
LangString MissingSSE2 ${LANG_GERMAN} "Dieser PC besitzt möglicherweise keinen Prozessor mit SSE2-Unterstützung, die für die Ausführung von Firestorm ${VERSION_LONG} benötigt wird. Trotzdem installieren?"
+LangString MissingAVX2 ${LANG_GERMAN} "Ihre CPU unterstützt keine AVX2-Anweisungen. Bitte laden Sie die Version für ältere CPUs von https://www.firestormviewer.org/early-access-beta-downloads-legacy-cpus/ herunter."
+LangString AVX2Available ${LANG_GERMAN} "Ihre CPU unterstützt AVX2-Anweisungen. Sie können die für AVX2 optimierte Version für eine bessere Leistung unter https://www.firestormviewer.org/early-access-beta-downloads/ herunterladen. Möchten Sie sie jetzt herunterladen?"
; closesecondlife function (install)
LangString CloseSecondLifeInstDP ${LANG_GERMAN} "Warten auf die Beendigung von Firestorm ..."
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index c301aa0e4e..69cde24d32 100644
Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index 37897d5981..cf36e45285 100755
Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index fc263d1eab..5312e31426 100755
Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 34e3bdcebd..d7447ed46b 100755
Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index 8322d86f81..b0d8958984 100755
Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 2a8ea7ef1d..3356eed567 100644
Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 3f75a5b580..c7bb70ad02 100755
Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ
diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp
index 433db74cda..8032e207cd 100644
--- a/indra/newview/llpanelgroupbulk.cpp
+++ b/indra/newview/llpanelgroupbulk.cpp
@@ -56,6 +56,7 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) :
mGroupID(group_id),
mBulkAgentList(NULL),
mOKButton(NULL),
+ mAddButton(nullptr),
mRemoveButton(NULL),
mGroupName(NULL),
mLoadingText(),
@@ -79,29 +80,18 @@ LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl()
}
}
-// static
-void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata)
+void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp)
{
- if (LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata)
- {
- // Right now this is hard coded with some knowledge that it is part
- // of a floater since the avatar picker needs to be added as a dependent
- // floater to the parent floater.
- // Soon the avatar picker will be embedded into this panel
- // instead of being it's own separate floater. But that is next week.
- // This will do for now. -jwolk May 10, 2006
- LLView* button = panelp->findChild("add_button");
- LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- [&](const uuid_vec_t& agent_ids, const std::vector&)
- {
- panelp->mImplementation->addUsers(agent_ids);
- }, true, false, false, root_floater->getName(), button);
- if (picker)
+ LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
+ [this](const uuid_vec_t& agent_ids, const std::vector&)
{
- root_floater->addDependentFloater(picker);
- LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID);
- }
+ addUsers(agent_ids);
+ }, true, false, false, root_floater->getName(), mAddButton);
+ if (picker)
+ {
+ root_floater->addDependentFloater(picker);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
}
diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp
index 3c764887a6..1d3edad0f3 100644
--- a/indra/newview/llpanelgroupbulkban.cpp
+++ b/indra/newview/llpanelgroupbulkban.cpp
@@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild()
mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation);
}
- LLButton* button = getChild("add_button", recurse);
- if ( button )
+ mImplementation->mAddButton = getChild("add_button", recurse);
+ // default to opening avatarpicker automatically
+ mImplementation->mAddButton->setClickedCallback(
+ [this](LLUICtrl* ctrl, const LLSD& param)
{
- // default to opening avatarpicker automatically
- // (*impl::callbackClickAdd)((void*)this);
- button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this);
- }
+ mImplementation->callbackClickAdd(this);
+ });
mImplementation->mRemoveButton =
getChild("remove_button", recurse);
- if ( mImplementation->mRemoveButton )
- {
- mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation);
- mImplementation->mRemoveButton->setEnabled(false);
- }
+ mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation);
+ mImplementation->mRemoveButton->setEnabled(false);
mImplementation->mOKButton =
getChild("ban_button", recurse);
- if ( mImplementation->mOKButton )
- {
- mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this);
- mImplementation->mOKButton->setEnabled(false);
- }
+ mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this);
+ mImplementation->mOKButton->setEnabled(false);
- button = getChild("cancel_button", recurse);
- if ( button )
- {
- button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
- }
+ LLButton* button = getChild("cancel_button", recurse);
+ button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
mImplementation->mTooManySelected = getString("ban_selection_too_large");
mImplementation->mBanNotPermitted = getString("ban_not_permitted");
diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h
index 5a479f8117..5515bd6d9a 100644
--- a/indra/newview/llpanelgroupbulkimpl.h
+++ b/indra/newview/llpanelgroupbulkimpl.h
@@ -44,7 +44,7 @@ public:
LLPanelGroupBulkImpl(const LLUUID& group_id);
~LLPanelGroupBulkImpl();
- static void callbackClickAdd(void* userdata);
+ void callbackClickAdd(LLPanelGroupBulk* panelp);
static void callbackClickRemove(void* userdata);
static void callbackClickCancel(void* userdata);
@@ -70,6 +70,7 @@ public:
LLNameListCtrl* mBulkAgentList;
LLButton* mOKButton;
+ LLButton* mAddButton;
LLButton* mRemoveButton;
LLTextBox* mGroupName;
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 028c82c1ce..eccbb5722c 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -47,8 +47,8 @@ const F32 PART_SIM_BOX_SIDE = 16.f;
//static
S32 LLViewerPartSim::sMaxParticleCount = 0;
-S32 LLViewerPartSim::sParticleCount = 0;
-S32 LLViewerPartSim::sParticleCount2 = 0;
+std::atomic LLViewerPartSim::sParticleCount{0}; // FIRE-34600 - bugsplat AVX2 particle count mismatch
+std::atomic LLViewerPartSim::sParticleCount2{0}; // FIRE-34600 - bugsplat AVX2 particle count mismatch
// This controls how greedy individual particle burst sources are allowed to be, and adapts according to how near the particle-count limit we are.
F32 LLViewerPartSim::sParticleAdaptiveRate = 0.0625f;
F32 LLViewerPartSim::sParticleBurstRate = 0.5f;
@@ -82,7 +82,7 @@ LLViewerPart::LLViewerPart() :
mPartSourcep = NULL;
mParent = NULL;
mChild = NULL;
- ++LLViewerPartSim::sParticleCount2 ;
+ LLViewerPartSim::incParticleCount2( 1 ); // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
LLViewerPart::~LLViewerPart()
@@ -107,7 +107,7 @@ LLViewerPart::~LLViewerPart()
mPartSourcep = NULL;
- --LLViewerPartSim::sParticleCount2 ;
+ LLViewerPartSim::decParticleCount2( 1 ); // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
void LLViewerPart::init(LLPointer sourcep, LLViewerTexture *imagep, LLVPCallback cb)
@@ -205,7 +205,7 @@ LLViewerPartGroup::~LLViewerPartGroup()
}
mParticles.clear();
- LLViewerPartSim::decPartCount(count);
+ LLViewerPartSim::decParticleCount(count); // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
void LLViewerPartGroup::cleanup()
@@ -268,7 +268,7 @@ bool LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
mParticles.push_back(part);
part->mSkipOffset=mSkippedTime;
- LLViewerPartSim::incPartCount(1);
+ LLViewerPartSim::incParticleCount(1); // FIRE-34600 - bugsplat AVX2 particle count mismatch
return true;
}
@@ -432,7 +432,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
{
gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL);
}
- LLViewerPartSim::decPartCount(removed);
+ LLViewerPartSim::decParticleCount(removed); // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
// Kill the viewer object if this particle group is empty
@@ -478,14 +478,22 @@ void LLViewerPartGroup::removeParticlesByID(const U32 source_id)
//static
void LLViewerPartSim::checkParticleCount(U32 size)
{
- if(LLViewerPartSim::sParticleCount2 != LLViewerPartSim::sParticleCount)
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if(LLViewerPartSim::sParticleCount2 != LLViewerPartSim::sParticleCount)
+ S32 count = LLViewerPartSim::getParticleCount();
+ S32 count2 = LLViewerPartSim::getParticleCount2();
+ if( count != count2 )
+ //
{
- LL_ERRS() << "sParticleCount: " << LLViewerPartSim::sParticleCount << " ; sParticleCount2: " << LLViewerPartSim::sParticleCount2 << LL_ENDL ;
+ LL_ERRS() << "sParticleCount: " << count << " ; sParticleCount2: " << count2 << LL_ENDL ; // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
- if(size > (U32)LLViewerPartSim::sParticleCount2)
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if(size > (U32)LLViewerPartSim::sParticleCount2)
+ if( size > static_cast(count2) )
+ //
{
- LL_ERRS() << "curren particle size: " << LLViewerPartSim::sParticleCount2 << " array size: " << size << LL_ENDL ;
+ LL_ERRS() << "current particle size: " << count2 << " array size: " << size << LL_ENDL ; // FIRE-34600 - bugsplat AVX2 particle count mismatch
}
}
@@ -531,14 +539,18 @@ void LLViewerPartSim::destroyClass()
//static
bool LLViewerPartSim::shouldAddPart()
{
- if (sParticleCount >= MAX_PART_COUNT)
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if (sParticleCount < MAX_PART_COUNT)
+ auto count = LLViewerPartSim::getParticleCount();
+ if ( count >= MAX_PART_COUNT)
+ //
{
return false;
}
- if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+ if ( count > PART_THROTTLE_THRESHOLD*sMaxParticleCount) // FIRE-34600 - bugsplat AVX2 particle count mismatch
{
- F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
+ F32 frac = (F32)count/(F32)sMaxParticleCount; // FIRE-34600 - bugsplat AVX2 particle count mismatch
frac -= PART_THROTTLE_THRESHOLD;
frac *= PART_THROTTLE_RESCALE;
if (ll_frand() < frac)
@@ -560,7 +572,7 @@ bool LLViewerPartSim::shouldAddPart()
void LLViewerPartSim::addPart(LLViewerPart* part)
{
- if (sParticleCount < MAX_PART_COUNT)
+ if (LLViewerPartSim::getParticleCount() < MAX_PART_COUNT)
{
put(part);
}
@@ -794,14 +806,19 @@ void LLViewerPartSim::updateSimulation()
}
if (LLDrawable::getCurrentFrame()%16==0)
{
- if (sParticleCount > sMaxParticleCount * 0.875f
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if (sParticleCount > sMaxParticleCount * 0.875f
+ // && sParticleAdaptiveRate < 2.0f)
+ auto count = LLViewerPartSim::getParticleCount();
+ if ( count > sMaxParticleCount * 0.875f
&& sParticleAdaptiveRate < 2.0f)
+ //
{
sParticleAdaptiveRate *= PART_ADAPT_RATE_MULT;
}
else
{
- if (sParticleCount < sMaxParticleCount * 0.5f
+ if ( count < sMaxParticleCount * 0.5f // FIRE-34600 - bugsplat AVX2 particle count mismatch
&& sParticleAdaptiveRate > 0.03125f)
{
sParticleAdaptiveRate *= PART_ADAPT_RATE_MULT_RECIP;
@@ -818,15 +835,25 @@ void LLViewerPartSim::updatePartBurstRate()
{
if (!(LLDrawable::getCurrentFrame() & 0xf))
{
- if (sParticleCount >= MAX_PART_COUNT) //set rate to zero
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if (sParticleCount >= MAX_PART_COUNT) //set rate to zero
+ auto count = LLViewerPartSim::getParticleCount();
+ if (count >= MAX_PART_COUNT) //set rate to zero
+ //
{
sParticleBurstRate = 0.0f ;
}
- else if(sParticleCount > 0)
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // else if(sParticleCount > 0)
+ else if (count > 0)
+ //
{
if(sParticleBurstRate > 0.0000001f)
{
- F32 total_particles = sParticleCount / sParticleBurstRate ; //estimated
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // F32 total_particles = sParticleCount / sParticleBurstRate ; //estimated
+ F32 total_particles = count / sParticleBurstRate ; //estimated
+ //
F32 new_rate = llclamp(0.9f * sMaxParticleCount / total_particles, 0.0f, 1.0f) ;
F32 delta_rate_threshold = llmin(0.1f * llmax(new_rate, sParticleBurstRate), 0.1f) ;
F32 delta_rate = llclamp(new_rate - sParticleBurstRate, -1.0f * delta_rate_threshold, delta_rate_threshold) ;
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index cf3843bd66..3e92a1988d 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -155,14 +155,25 @@ public:
static bool shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
F32 maxRate() // Return maximum particle generation rate
{
- if (sParticleCount >= MAX_PART_COUNT)
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // if (sParticleCount >= MAX_PART_COUNT)
+ // {
+ // return 1.f;
+ // }
+ // if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+ // {
+ // return (((F32)sParticleCount/(F32)sMaxParticleCount)-PART_THROTTLE_THRESHOLD)*PART_THROTTLE_RESCALE;
+ // }
+ const auto count = getParticleCount();
+ if ( count >= MAX_PART_COUNT)
{
return 1.f;
}
- if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+ if ( count > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
{
- return (((F32)sParticleCount/(F32)sMaxParticleCount)-PART_THROTTLE_THRESHOLD)*PART_THROTTLE_RESCALE;
+ return (((F32)count/(F32)sMaxParticleCount)-PART_THROTTLE_THRESHOLD)*PART_THROTTLE_RESCALE;
}
+ //
return 0.f;
}
F32 getRefRate() { return sParticleAdaptiveRate; }
@@ -177,12 +188,28 @@ public:
friend class LLViewerPartGroup;
- bool aboveParticleLimit() const { return sParticleCount > sMaxParticleCount; }
-
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // bool aboveParticleLimit() const { return sParticleCount > sMaxParticleCount; }
+ bool aboveParticleLimit() const { return getParticleCount() > sMaxParticleCount; }
+ //
static void setMaxPartCount(const S32 max_parts) { sMaxParticleCount = max_parts; }
static S32 getMaxPartCount() { return sMaxParticleCount; }
- static void incPartCount(const S32 count) { sParticleCount += count; }
- static void decPartCount(const S32 count) { sParticleCount -= count; }
+
+ // FIRE-34600 - bugsplat AVX2 particle count mismatch
+ // static void incPartCount(const S32 count) { sParticleCount += count; }
+ // static void decPartCount(const S32 count) { sParticleCount -= count; }
+ static void incParticleCount(const S32 count, std::memory_order order = std::memory_order_seq_cst )
+ { sParticleCount.fetch_add( count , std::memory_order_seq_cst ); }
+ static void decParticleCount(const S32 count, std::memory_order order = std::memory_order_seq_cst )
+ { sParticleCount.fetch_sub( count , std::memory_order_seq_cst ); }
+ static void incParticleCount2(const S32 count, std::memory_order order = std::memory_order_seq_cst )
+ { sParticleCount2.fetch_add( count , std::memory_order_seq_cst ); }
+ static void decParticleCount2(const S32 count, std::memory_order order = std::memory_order_seq_cst )
+ { sParticleCount2.fetch_sub( count , std::memory_order_seq_cst ); }
+ static inline S32 getParticleCount(std::memory_order order = std::memory_order_seq_cst) { return sParticleCount.load(order); }
+
+ static inline S32 getParticleCount2(std::memory_order order = std::memory_order_seq_cst) { return sParticleCount2.load(order); }
+ //
U32 mID;
@@ -195,7 +222,7 @@ protected:
LLFrameTimer mSimulationTimer;
static S32 sMaxParticleCount;
- static S32 sParticleCount;
+ static std::atomic sParticleCount; // FIRE-34600 - bugsplat AVX2 particle count mismatch
static F32 sParticleAdaptiveRate;
static F32 sParticleBurstRate;
@@ -207,7 +234,7 @@ protected:
//debug use only
public:
- static S32 sParticleCount2;
+ static std::atomic sParticleCount2; // FIRE-34600 - bugsplat AVX2 particle count mismatch
static void checkParticleCount(U32 size = 0) ;
};
diff --git a/indra/newview/skins/default/xui/de/floater_phototools_camera.xml b/indra/newview/skins/default/xui/de/floater_phototools_camera.xml
index 621fe231f4..25490cfcad 100644
--- a/indra/newview/skins/default/xui/de/floater_phototools_camera.xml
+++ b/indra/newview/skins/default/xui/de/floater_phototools_camera.xml
@@ -56,6 +56,8 @@
+
+
diff --git a/indra/newview/skins/default/xui/en/floater_phototools_camera.xml b/indra/newview/skins/default/xui/en/floater_phototools_camera.xml
index 43214c138e..b0340a53f6 100644
--- a/indra/newview/skins/default/xui/en/floater_phototools_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_phototools_camera.xml
@@ -238,6 +238,36 @@
tool_tip="Orbit camera around focus"
top="5"
width="100"/>
+
+
+
+