Merge branch 'FirestormViewer:master' into Fire-30873-NewPoser

master
Angeldark Raymaker 2024-10-07 20:32:33 +01:00 committed by GitHub
commit 76657a75aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 208 additions and 78 deletions

View File

@ -1,6 +1,8 @@
![Firestorm Viewer Logo](doc/firestorm_256.png)
<img align="left" width="100" height="100" src="doc/firestorm_256.png" alt="Logo of 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.
**[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)

View File

@ -88,7 +88,7 @@ void LLImageFilter::executeFilter(LLPointer<LLImageRaw> raw_image)
{
mImage = raw_image;
LLImageDataLock lock(mImage);
LLImageDataSharedLock lock(mImage); // <FS:Beq> FIRE-34564 Bugsplat SHARED vs EXCLUSIVE lock conflict
//std::cout << "Filter : size = " << mFilterData.size() << std::endl;
for (S32 i = 0; i < mFilterData.size(); ++i)

View File

@ -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=$<CONFIG>
"--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=$<CONFIG>
"--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=$<CONFIG>
--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}"

View File

@ -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

View File

@ -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
# <FS:Ansariel> 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

View File

@ -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 ..."

View File

@ -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<LLButton>("add_button");
LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
[&](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&)
{
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<LLAvatarName>&)
{
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);
}
}

View File

@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild()
mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation);
}
LLButton* button = getChild<LLButton>("add_button", recurse);
if ( button )
mImplementation->mAddButton = getChild<LLButton>("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<LLButton>("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<LLButton>("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<LLButton>("cancel_button", recurse);
if ( button )
{
button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
}
LLButton* button = getChild<LLButton>("cancel_button", recurse);
button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
mImplementation->mTooManySelected = getString("ban_selection_too_large");
mImplementation->mBanNotPermitted = getString("ban_not_permitted");

View File

@ -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;

View File

@ -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<S32> LLViewerPartSim::sParticleCount{0}; // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
std::atomic<S32> LLViewerPartSim::sParticleCount2{0}; // <FS:Beq/> 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 ); // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
}
LLViewerPart::~LLViewerPart()
@ -107,7 +107,7 @@ LLViewerPart::~LLViewerPart()
mPartSourcep = NULL;
--LLViewerPartSim::sParticleCount2 ;
LLViewerPartSim::decParticleCount2( 1 ); // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
}
void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerTexture *imagep, LLVPCallback cb)
@ -205,7 +205,7 @@ LLViewerPartGroup::~LLViewerPartGroup()
}
mParticles.clear();
LLViewerPartSim::decPartCount(count);
LLViewerPartSim::decParticleCount(count); // <FS:Beq/> 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); // <FS:Beq/> 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); // <FS:Beq/> 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)
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// if(LLViewerPartSim::sParticleCount2 != LLViewerPartSim::sParticleCount)
S32 count = LLViewerPartSim::getParticleCount();
S32 count2 = LLViewerPartSim::getParticleCount2();
if( count != count2 )
// <FS:Beq/>
{
LL_ERRS() << "sParticleCount: " << LLViewerPartSim::sParticleCount << " ; sParticleCount2: " << LLViewerPartSim::sParticleCount2 << LL_ENDL ;
LL_ERRS() << "sParticleCount: " << count << " ; sParticleCount2: " << count2 << LL_ENDL ; //<FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
}
if(size > (U32)LLViewerPartSim::sParticleCount2)
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// if(size > (U32)LLViewerPartSim::sParticleCount2)
if( size > static_cast<U32>(count2) )
// <FS:Beq/>
{
LL_ERRS() << "curren particle size: " << LLViewerPartSim::sParticleCount2 << " array size: " << size << LL_ENDL ;
LL_ERRS() << "current particle size: " << count2 << " array size: " << size << LL_ENDL ; // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
}
}
@ -531,14 +539,18 @@ void LLViewerPartSim::destroyClass()
//static
bool LLViewerPartSim::shouldAddPart()
{
if (sParticleCount >= MAX_PART_COUNT)
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// if (sParticleCount < MAX_PART_COUNT)
auto count = LLViewerPartSim::getParticleCount();
if ( count >= MAX_PART_COUNT)
// <FS:Beq/>
{
return false;
}
if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
if ( count > PART_THROTTLE_THRESHOLD*sMaxParticleCount) // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
{
F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
F32 frac = (F32)count/(F32)sMaxParticleCount; // <FS:Beq/> 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
// <FS:Beq> 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)
// <FS:Beq/>
{
sParticleAdaptiveRate *= PART_ADAPT_RATE_MULT;
}
else
{
if (sParticleCount < sMaxParticleCount * 0.5f
if ( count < sMaxParticleCount * 0.5f // <FS:Beq/> 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
// <FS:Beq> 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
// <FS:Beq/>
{
sParticleBurstRate = 0.0f ;
}
else if(sParticleCount > 0)
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// else if(sParticleCount > 0)
else if (count > 0)
// <FS:Beq/>
{
if(sParticleBurstRate > 0.0000001f)
{
F32 total_particles = sParticleCount / sParticleBurstRate ; //estimated
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// F32 total_particles = sParticleCount / sParticleBurstRate ; //estimated
F32 total_particles = count / sParticleBurstRate ; //estimated
// <FS:Beq/>
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) ;

View File

@ -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)
// <FS:Beq> 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;
}
// </FS:Beq>
return 0.f;
}
F32 getRefRate() { return sParticleAdaptiveRate; }
@ -177,12 +188,28 @@ public:
friend class LLViewerPartGroup;
bool aboveParticleLimit() const { return sParticleCount > sMaxParticleCount; }
// <FS:Beq> FIRE-34600 - bugsplat AVX2 particle count mismatch
// bool aboveParticleLimit() const { return sParticleCount > sMaxParticleCount; }
bool aboveParticleLimit() const { return getParticleCount() > sMaxParticleCount; }
// </FS:Beq>
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; }
// <FS:Beq> 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); }
// </FS:Beq>
U32 mID;
@ -195,7 +222,7 @@ protected:
LLFrameTimer mSimulationTimer;
static S32 sMaxParticleCount;
static S32 sParticleCount;
static std::atomic<S32> sParticleCount; // <FS:Beq/> 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<S32> sParticleCount2; // <FS:Beq/> FIRE-34600 - bugsplat AVX2 particle count mismatch
static void checkParticleCount(U32 size = 0) ;
};

View File

@ -56,6 +56,8 @@
</panel>
<panel name="zoom">
<joystick_rotate name="cam_rotate_stick" tool_tip="Kamera um Fokus kreisen"/>
<button name="roll_left" tool_tip="Kamera nach links rollen" />
<button name="roll_right" tool_tip="Kamera nach rechts rollen" />
<slider_bar name="zoom_slider" tool_tip="Hierdurch wird die Kamera hinein- und herausbewegt. HINWEIS: Es handelt sich hierbei nicht um einen Zoom wie im echten Leben, diese Einstellung hat keinen Effekt auf das Sichtfeld der Kamera. Für echtes Zoomen muss der Regler „Sichtwinkel“ verwendet werden!"/>
<joystick_track name="cam_track_stick" tool_tip="Kamera nach oben, unten, links und rechts bewegen"/>
</panel>

View File

@ -238,6 +238,36 @@
tool_tip="Orbit camera around focus"
top="5"
width="100"/>
<!-- <FS:Beq> FIRE-34509 Add Camera roll -->
<button
follows="bottom|left"
width="12"
height="12"
image_selected="VirtualTrackball_Rotate_Left_Active"
image_unselected="VirtualTrackball_Rotate_Left"
layout="topleft"
top_delta="85"
left_delta="5"
name="roll_left"
tool_tip="Roll camera Left">
<commit_callback function="Camera.roll_left" />
<mouse_held_callback function="Camera.roll_left" />
</button>
<button
follows="bottom|right"
width="12"
height="12"
image_selected="VirtualTrackball_Rotate_Right_Active"
image_unselected="VirtualTrackball_Rotate_Right"
layout="topleft"
top_delta="0"
left_delta="78"
name="roll_right"
tool_tip="Roll camera Right">
<commit_callback function="Camera.roll_right" />
<mouse_held_callback function="Camera.roll_right" />
</button>
<!-- </FS:Beq> -->
<button
follows="top|left"
height="18"

View File

@ -951,6 +951,7 @@ class Windows_x86_64_Manifest(ViewerManifest):
substitution_strings['installer_file'] = installer_file
substitution_strings['is64bit'] = (1 if (self.address_size == 64) else 0)
substitution_strings['isavx2'] = (1 if (self.fs_is_avx2) else 0)
substitution_strings['is_opensim'] = self.fs_is_opensim() # <FS:Ansariel> FIRE-30446: Register hop-protocol for OS version only
substitution_strings['friendly_app_name'] = self.friendly_app_name() # <FS:Ansariel> FIRE-30446: Set FriendlyAppName for protocol registrations
substitution_strings['icon_suffix'] = ("_os" if (self.fs_is_opensim()) else "") # <FS:Ansariel> FIRE-24335: Use different icon for OpenSim version
@ -975,6 +976,7 @@ class Windows_x86_64_Manifest(ViewerManifest):
!define SHORTCUT "%(app_name)s"
!define URLNAME "secondlife"
!define IS64BIT "%(is64bit)d"
!define ISAVX2 "%(isavx2)d"
!define ISOPENSIM "%(is_opensim)d"
!define APPNAME "%(friendly_app_name)s"
!define ICON_SUFFIX "%(icon_suffix)s"
@ -2454,6 +2456,7 @@ if __name__ == "__main__":
dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'),
dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'),
dict(name='tracy', description="""Indication tracy profiler is enabled""", default='OFF'),
dict(name='avx2', description="""Indication avx2 instruction set is enabled""", default='OFF'),
]
try:
main(extra=extra_arguments)