MAINT-6931 Fixed Flexi prims being FPS dependent
parent
4bcaac489e
commit
6bc2c5789c
|
|
@ -43,9 +43,9 @@
|
|||
#include "llworld.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
static const F32 SEC_PER_FLEXI_FRAME = 1.f / 60.f; // 60 flexi updates per second
|
||||
/*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
|
||||
std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList;
|
||||
std::vector<S32> LLVolumeImplFlexible::sUpdateDelay;
|
||||
|
||||
static LLTrace::BlockTimerStatHandle FTM_FLEXIBLE_REBUILD("Rebuild");
|
||||
static LLTrace::BlockTimerStatHandle FTM_DO_FLEXIBLE_UPDATE("Flexible Update");
|
||||
|
|
@ -56,7 +56,10 @@ static LLTrace::BlockTimerStatHandle FTM_DO_FLEXIBLE_UPDATE("Flexible Update");
|
|||
// constructor
|
||||
//-----------------------------------------------
|
||||
LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectData* attributes) :
|
||||
mVO(vo), mAttributes(attributes)
|
||||
mVO(vo),
|
||||
mAttributes(attributes),
|
||||
mLastFrameNum(0),
|
||||
mLastUpdatePeriod(0)
|
||||
{
|
||||
static U32 seed = 0;
|
||||
mID = seed++;
|
||||
|
|
@ -64,7 +67,6 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
|
|||
mUpdated = FALSE;
|
||||
mInitializedRes = -1;
|
||||
mSimulateRes = 0;
|
||||
mFrameNum = 0;
|
||||
mCollisionSphereRadius = 0.f;
|
||||
mRenderRes = -1;
|
||||
|
||||
|
|
@ -75,7 +77,6 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
|
|||
|
||||
mInstanceIndex = sInstanceList.size();
|
||||
sInstanceList.push_back(this);
|
||||
sUpdateDelay.push_back(0);
|
||||
}//-----------------------------------------------
|
||||
|
||||
LLVolumeImplFlexible::~LLVolumeImplFlexible()
|
||||
|
|
@ -86,28 +87,28 @@ LLVolumeImplFlexible::~LLVolumeImplFlexible()
|
|||
{
|
||||
sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
|
||||
sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
|
||||
sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx];
|
||||
}
|
||||
|
||||
sInstanceList.pop_back();
|
||||
sUpdateDelay.pop_back();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVolumeImplFlexible::updateClass()
|
||||
{
|
||||
std::vector<S32>::iterator delay_iter = sUpdateDelay.begin();
|
||||
LL_RECORD_BLOCK_TIME(FTM_DO_FLEXIBLE_UPDATE);
|
||||
|
||||
U64 virtual_frame_num = LLTimer::getElapsedSeconds() / SEC_PER_FLEXI_FRAME;
|
||||
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
|
||||
iter != sInstanceList.end();
|
||||
++iter)
|
||||
{
|
||||
--(*delay_iter);
|
||||
if (*delay_iter <= 0)
|
||||
// Note: by now update period might have changed
|
||||
if ((*iter)->mRenderRes == -1
|
||||
|| (*iter)->mLastFrameNum + (*iter)->mLastUpdatePeriod <= virtual_frame_num
|
||||
|| (*iter)->mLastFrameNum > virtual_frame_num) //time issues, overflow
|
||||
{
|
||||
(*iter)->doIdleUpdate();
|
||||
}
|
||||
++delay_iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,15 +335,12 @@ void LLVolumeImplFlexible::updateRenderRes()
|
|||
// updated every time step. In the future, perhaps there could be an
|
||||
// optimization similar to what Havok does for objects that are stationary.
|
||||
//---------------------------------------------------------------------------------
|
||||
static LLTrace::BlockTimerStatHandle FTM_FLEXIBLE_UPDATE("Update Flexies");
|
||||
void LLVolumeImplFlexible::doIdleUpdate()
|
||||
{
|
||||
LLDrawable* drawablep = mVO->mDrawable;
|
||||
|
||||
if (drawablep)
|
||||
{
|
||||
//LL_RECORD_BLOCK_TIME(FTM_FLEXIBLE_UPDATE);
|
||||
|
||||
//ensure drawable is active
|
||||
drawablep->makeActive();
|
||||
|
||||
|
|
@ -354,15 +352,20 @@ void LLVolumeImplFlexible::doIdleUpdate()
|
|||
{
|
||||
updateRenderRes();
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
sUpdateDelay[mInstanceIndex] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 pixel_area = mVO->getPixelArea();
|
||||
|
||||
// Note: Flexies afar will be rarely updated, closer ones will be updated more frequently.
|
||||
// But frequency differences are extremely noticeable, so consider modifying update factor,
|
||||
// or at least clamping value a bit more from both sides.
|
||||
U32 update_period = (U32) (llmax((S32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f))),0)+1);
|
||||
// MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames
|
||||
update_period = llclamp(update_period, 0U, 32U);
|
||||
update_period = llclamp(update_period, 1U, 32U);
|
||||
|
||||
// We control how fast flexies update, buy splitting updates among frames
|
||||
U64 virtual_frame_num = LLTimer::getElapsedSeconds() / SEC_PER_FLEXI_FRAME;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
|
|
@ -370,42 +373,44 @@ void LLVolumeImplFlexible::doIdleUpdate()
|
|||
pixel_area > 256.f)
|
||||
{
|
||||
U32 id;
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
{
|
||||
id = mID;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
LLVOVolume* parent = (LLVOVolume*)mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
}
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
{
|
||||
id = mID;
|
||||
|
||||
// Throttle flexies and spread load by preventing flexies from updating in same frame
|
||||
// Shows how many frames we need to wait before next update
|
||||
U64 throttling_delay = (virtual_frame_num + id) % update_period;
|
||||
|
||||
if ((throttling_delay == 0 && mLastFrameNum < virtual_frame_num) //one or more virtual frames per frame
|
||||
|| (mLastFrameNum + update_period < virtual_frame_num)) // missed virtual frame
|
||||
{
|
||||
// We need mLastFrameNum to compensate for 'unreliable time' and to filter 'duplicate' frames
|
||||
// If happened too late, subtract throttling_delay (it is zero otherwise)
|
||||
mLastFrameNum = virtual_frame_num - throttling_delay;
|
||||
|
||||
// Store update period for updateClass()
|
||||
// Note: Consider substituting update_period with mLastUpdatePeriod everywhere.
|
||||
mLastUpdatePeriod = update_period;
|
||||
|
||||
updateRenderRes();
|
||||
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
}
|
||||
|
||||
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
|
||||
{
|
||||
sUpdateDelay[mInstanceIndex] = (S32) update_period-1;
|
||||
|
||||
updateRenderRes();
|
||||
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
mLastFrameNum = virtual_frame_num;
|
||||
mLastUpdatePeriod = update_period;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sUpdateDelay[mInstanceIndex] = (S32) update_period;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ class LLVolumeImplFlexible : public LLVolumeInterface
|
|||
{
|
||||
private:
|
||||
static std::vector<LLVolumeImplFlexible*> sInstanceList;
|
||||
static std::vector<S32> sUpdateDelay;
|
||||
S32 mInstanceIndex;
|
||||
|
||||
public:
|
||||
|
|
@ -133,7 +132,8 @@ private:
|
|||
S32 mInitializedRes;
|
||||
S32 mSimulateRes;
|
||||
S32 mRenderRes;
|
||||
U32 mFrameNum;
|
||||
U64 mLastFrameNum;
|
||||
U32 mLastUpdatePeriod;
|
||||
LLVector3 mCollisionSpherePosition;
|
||||
F32 mCollisionSphereRadius;
|
||||
U32 mID;
|
||||
|
|
|
|||
Loading…
Reference in New Issue