Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 202 additions & 26 deletions indra/newview/llfloaterobjectweights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@
#include "lltextbox.h"

#include "llagent.h"
#include "llcallbacklist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llmeshrepository.h"

static const std::string lod_strings[4] =
{
Expand Down Expand Up @@ -74,6 +76,14 @@ bool LLCrossParcelFunctor::apply(LLViewerObject* obj)

LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
: LLFloater(key),
mWeightsDirty(false),
mSelectionDirty(true),
mSelectionMeshDirty(true),
mSelectionLastLOD(-1),
mSelectionLastTris(0),
mSelectionLastArea(0),
mLastActiveLODRequests(0),
mSelectionRefreshTime(0.),
Comment thread
akleshchev marked this conversation as resolved.
mSelectedObjects(NULL),
mSelectedPrims(NULL),
mSelectedDownloadWeight(NULL),
Expand All @@ -88,6 +98,13 @@ LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
mTrianglesShown(nullptr),
mPixelArea(nullptr)
{
mSelectionConnection = LLSelectMgr::getInstance()->mUpdateSignal.connect(
[this]()
{
mSelectionDirty = true;
mSelectionMeshDirty = true; // assume that mesh data will arrive with a delay.
}
);
}

LLFloaterObjectWeights::~LLFloaterObjectWeights()
Expand All @@ -114,6 +131,11 @@ bool LLFloaterObjectWeights::postBuild()
mTrianglesShown = getChild<LLTextBox>("triangles_shown");
mPixelArea = getChild<LLTextBox>("pixel_area");

mHighLodTris = getChild<LLTextBox>("high_lod_tris");
mMediumLodTris = getChild<LLTextBox>("medium_lod_tris");
mLowLodTris = getChild<LLTextBox>("low_lod_tris");
mLowestLodTris = getChild<LLTextBox>("lowest_lod_tris");

return true;
}

Expand All @@ -122,6 +144,14 @@ void LLFloaterObjectWeights::onOpen(const LLSD& key)
{
refresh();
updateLandImpacts(LLViewerParcelMgr::getInstance()->getFloatingParcelSelection()->getParcel());

onIdleRefresh(this);
gIdleCallbacks.addFunction(onIdleRefresh, this);
}

void LLFloaterObjectWeights::onClose(bool app_quitting)
{
gIdleCallbacks.deleteFunction(onIdleRefresh, this);
}

// virtual
Expand All @@ -131,8 +161,9 @@ void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost
mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost));
mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost));

S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
mSelectedDisplayWeight->setText(llformat("%d", render_cost));
// onWeightsUpdate comes from a coroutine.
// Postpone LLSelectMgr operations as getSelectedObjectRenderCost is not coroutine-safe
mWeightsDirty = true;

toggleWeightsLoadingIndicators(false);
}
Expand All @@ -152,20 +183,13 @@ void LLFloaterObjectWeights::setErrorStatus(S32 status, const std::string& reaso

void LLFloaterObjectWeights::draw()
{
// Normally it's a bad idea to set text and visibility inside draw
// since it can cause rect updates go to different, already drawn elements,
// but floater is very simple and these elements are supposed to be isolated
// This logic might be a bit too expensive for draw(),
// but this floater needs to react fast, even if it's
// detrimental to performance. Having callbacks like
// 'tris changed' in every selected object might be
// more impactful on performance.
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
if (selection->isEmpty())
{
const std::string text = getString("nothing_selected");
mLodLevel->setText(text);
mTrianglesShown->setText(text);
mPixelArea->setText(text);

toggleRenderLoadingIndicators(false);
}
else
if (!selection->isEmpty() && !mSelectionDirty)
{
S32 object_lod = -1;
bool multiple_lods = false;
Expand All @@ -192,27 +216,71 @@ void LLFloaterObjectWeights::draw()
}
}

if (multiple_lods)
if (mSelectionLastTris != total_tris)
{
mLodLevel->setText(getString("multiple_lods"));
toggleRenderLoadingIndicators(false);
mSelectionDirty = true;
}
else if (object_lod < 0)
else if (mSelectionLastArea != pixel_area)
{
// nodes are waiting for data
toggleRenderLoadingIndicators(true);
mSelectionDirty = true;
}
else
else if (multiple_lods)
{
mLodLevel->setText(getString(lod_strings[object_lod]));
toggleRenderLoadingIndicators(false);
mSelectionDirty |= mSelectionLastLOD != -1;
}
else if (mSelectionLastLOD != object_lod)
{
mSelectionDirty = true;
}
mTrianglesShown->setText(llformat("%d", total_tris));
mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
}
LLFloater::draw();
}

void LLFloaterObjectWeights::onIdleRefresh(void* user_data)
{
LLFloaterObjectWeights* self = (LLFloaterObjectWeights*)user_data;

F64 current_time = LLTimer::getTotalSeconds();
S32 current_lod_requests = LLMeshRepoThread::sActiveLODRequests.load();
// Can't look for a specific mesh (no callback mechanics and we
// need multiple ones), so just update periodically if something loads
self->mSelectionMeshDirty |= (self->mLastActiveLODRequests > current_lod_requests);
bool throttle_elapsed = (current_time - self->mSelectionRefreshTime) >= 2.0;

if (self->mLastActiveLODRequests < current_lod_requests)
{
// we are interested in finished downloads,
// so don't refresh if more requests are getting added.
self->mLastActiveLODRequests = current_lod_requests;
}

if (self->mSelectionDirty)
{
// Always refresh on selection changes
self->refreshDataFromSelection();
self->mSelectionDirty = false;
self->mSelectionRefreshTime = current_time;
// refreshDataFromSelection could have indirectly initiated more requests
self->mLastActiveLODRequests = LLMeshRepoThread::sActiveLODRequests.load();
}
else if (self->mSelectionMeshDirty && throttle_elapsed)
{
// LOD requests count changed or mesh needs lod data reload
self->refreshDataFromSelection();
self->mSelectionRefreshTime = current_time;
self->mSelectionMeshDirty = false;
// refreshDataFromSelection could have indirectly initiated more requests
self->mLastActiveLODRequests = LLMeshRepoThread::sActiveLODRequests.load();
}
else if (self->mWeightsDirty) // also done in refreshDataFromSelection
{
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
S32 render_cost = selection->getSelectedObjectRenderCost();
self->mSelectedDisplayWeight->setText(llformat("%d", render_cost));
self->mWeightsDirty = false;
}
}

void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel)
{
if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty())
Expand Down Expand Up @@ -240,6 +308,101 @@ void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel)
}
}

void LLFloaterObjectWeights::refreshDataFromSelection()
{
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
if (selection->isEmpty())
{
const std::string text = getString("nothing_selected");
mLodLevel->setText(text);
mTrianglesShown->setText(text);
mPixelArea->setText(text);

mHighLodTris->setText(text);
mMediumLodTris->setText(text);
mLowLodTris->setText(text);
mLowestLodTris->setText(text);

toggleRenderLoadingIndicators(false);
toggleLODLoadingIndicators(false);
}
else
{
S32 object_lod = -1;
bool multiple_lods = false;
S32 total_tris = 0;
F32 pixel_area = 0;
S32 high_tris = 0;
S32 medium_tris = 0;
S32 low_tris = 0;
S32 lowest_tris = 0;
for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
iter != selection->valid_root_end(); ++iter)
{
LLViewerObject* object = (*iter)->getObject();
S32 lod = object->getLOD();
if (object_lod < 0)
{
object_lod = lod;
}
else if (object_lod != lod)
{
multiple_lods = true;
}

if (object->isRootEdit())
{
total_tris += object->recursiveGetTriangleCount();
pixel_area += object->getPixelArea();
object->recursiveGetLODTriangleCount(high_tris, medium_tris, low_tris, lowest_tris);
}
}

mSelectionLastTris = total_tris;
mSelectionLastArea = pixel_area;
if (multiple_lods)
{
mSelectionLastLOD = -1;
}
else
{
mSelectionLastLOD = object_lod;
}

if (multiple_lods)
{
mLodLevel->setText(getString("multiple_lods"));
toggleRenderLoadingIndicators(false);
toggleLODLoadingIndicators(false);
}
else if (object_lod < 0)
{
// nodes are waiting for data
toggleRenderLoadingIndicators(true);
toggleLODLoadingIndicators(true);
}
else
{
mLodLevel->setText(getString(lod_strings[object_lod]));
toggleRenderLoadingIndicators(false);
toggleLODLoadingIndicators(false);
}
mTrianglesShown->setText(llformat("%d", total_tris));
mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
mHighLodTris->setText(llformat("%d", high_tris));
mMediumLodTris->setText(llformat("%d", medium_tris));
mLowLodTris->setText(llformat("%d", low_tris));
mLowestLodTris->setText(llformat("%d", lowest_tris));
}

if (mWeightsDirty)
{
S32 render_cost = selection->getSelectedObjectRenderCost();
mSelectedDisplayWeight->setText(llformat("%d", render_cost));
mWeightsDirty = false;
}
}

void LLFloaterObjectWeights::refresh()
{
LLSelectMgr* sel_mgr = LLSelectMgr::getInstance();
Expand Down Expand Up @@ -341,6 +504,19 @@ void LLFloaterObjectWeights::toggleRenderLoadingIndicators(bool visible)
mPixelArea->setVisible(!visible);
}

void LLFloaterObjectWeights::toggleLODLoadingIndicators(bool visible)
{
childSetVisible("high_lod_tris_loading_indicator", visible);
childSetVisible("medium_lod_tris_loading_indicator", visible);
childSetVisible("low_lod_tris_loading_indicator", visible);
childSetVisible("lowest_lod_tris_loading_indicator", visible);

mHighLodTris->setVisible(!visible);
mMediumLodTris->setVisible(!visible);
mLowLodTris->setVisible(!visible);
mLowestLodTris->setVisible(!visible);
}

void LLFloaterObjectWeights::updateIfNothingSelected()
{
const std::string text = getString("nothing_selected");
Expand Down
21 changes: 21 additions & 0 deletions indra/newview/llfloaterobjectweights.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,17 @@ class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
bool postBuild() override;

void onOpen(const LLSD& key) override;
void onClose(bool app_quitting) override;

void onWeightsUpdate(const SelectionCost& selection_cost) override;
void setErrorStatus(S32 status, const std::string& reason) override;

void draw() override;

static void onIdleRefresh(void* user_data);

void updateLandImpacts(const LLParcel* parcel);
void refreshDataFromSelection();
void refresh() override;

private:
Expand All @@ -76,9 +80,19 @@ class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
void toggleWeightsLoadingIndicators(bool visible);
void toggleLandImpactsLoadingIndicators(bool visible);
void toggleRenderLoadingIndicators(bool visible);
void toggleLODLoadingIndicators(bool visible);

void updateIfNothingSelected();

bool mWeightsDirty;
bool mSelectionDirty;
bool mSelectionMeshDirty;
F64 mSelectionRefreshTime;
S32 mSelectionLastLOD;
S32 mSelectionLastTris;
F32 mSelectionLastArea;
S32 mLastActiveLODRequests;

LLTextBox *mSelectedObjects;
LLTextBox *mSelectedPrims;

Expand All @@ -95,6 +109,13 @@ class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
LLTextBox *mLodLevel;
LLTextBox *mTrianglesShown;
LLTextBox *mPixelArea;

LLTextBox *mHighLodTris;
LLTextBox *mMediumLodTris;
LLTextBox *mLowLodTris;
LLTextBox *mLowestLodTris;

boost::signals2::scoped_connection mSelectionConnection;
};

#endif //LL_LLFLOATEROBJECTWEIGHTS_H
1 change: 0 additions & 1 deletion indra/newview/llselectmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ LLSelectMgr::LLSelectMgr()
LLSelectMgr::~LLSelectMgr()
{
clearSelections();
mSlectionLodModChangedConnection.disconnect();
}

void LLSelectMgr::clearSelections()
Expand Down
1 change: 0 additions & 1 deletion indra/newview/llselectmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,6 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr>
bool mForceSelection;

std::vector<LLAnimPauseRequest> mPauseRequests;
boost::signals2::connection mSlectionLodModChangedConnection;
};

// *DEPRECATED: For callbacks or observers, use
Expand Down
Loading
Loading