Merge branch 'marchcat/maint-b-cherrypicks' into marchcat/2025.03-maint-b

master
Andrey Lihatskiy 2025-03-11 05:10:11 +02:00
commit 4132a13972
36 changed files with 381 additions and 164 deletions

View File

@ -981,7 +981,7 @@ void LLPolyMesh::initializeForMorph()
LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));
memcpy((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices)); // allocated in LLPolyMeshSharedData::allocateVertexData
for (S32 i = 0; i < mSharedData->mNumVertices; ++i)
{

View File

@ -465,7 +465,7 @@ void LLProxy::applyProxySettings(CURL* handle)
/**
* @brief Send one TCP packet and receive one in return.
*
* This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking
* This operation is done synchronously with a 100ms timeout. Therefore, it should not be used when a blocking
* operation would impact the operation of the viewer.
*
* @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP.
@ -482,7 +482,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
apr_size_t expected_len = outlen;
handle->setBlocking(1000);
handle->setBlocking(100000); // 100ms, 100000us. Should be sufficient for localhost, nearby network
rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv)

View File

@ -108,12 +108,15 @@ LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LL
LLXmlTreeNode::~LLXmlTreeNode()
{
attribute_map_t::iterator iter;
for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++)
delete iter->second;
for(LLXmlTreeNode* node : mChildren)
for (auto& attr : mAttributes)
{
delete node;
delete attr.second;
}
mAttributes.clear();
for (auto& child : mChildren)
{
delete child;
}
mChildren.clear();
}

View File

@ -56,6 +56,7 @@
#include "llgroupmgr.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
#include "lllandmarkactions.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
@ -4320,8 +4321,17 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
{
LLViewerRegion *regionp = getRegion();
if(regionp && teleportCore())
bool is_local(false);
LLViewerRegion* regionp = getRegion();
if (LLLandmark* landmark = gLandmarkList.getAsset(landmark_asset_id, NULL))
{
LLVector3d pos_global;
landmark->getGlobalPos(pos_global);
is_local = (regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]));
}
if(regionp && teleportCore(is_local))
{
LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
<< " region id " << regionp->getRegionID()

View File

@ -1385,8 +1385,6 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
&& curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN
&& version > curr_cat->getVersion())
{
// Potentially should new_cat->setVersion(unknown) here,
// but might be waiting for a callback that would increment
LL_DEBUGS("Inventory") << "Category " << category_id
<< " is stale. Known version: " << curr_cat->getVersion()
<< " server version: " << version << LL_ENDL;

View File

@ -2350,6 +2350,14 @@ void LLAppViewer::initLoggingAndGetLastDuration()
{
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
}
std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");
if (gDirUtilp->fileExists(user_data_path_cef_log))
{
std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old");
LLFile::remove(user_data_path_cef_old, ENOENT);
LLFile::rename(user_data_path_cef_log, user_data_path_cef_old);
}
}
}
@ -2977,9 +2985,10 @@ void LLAppViewer::initStrings()
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
{
std::string crash_reason;
if (strings_path_full.empty())
{
LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
crash_reason = "The file '" + strings_file + "' is not found";
}
else
{
@ -2987,24 +2996,23 @@ void LLAppViewer::initStrings()
int rc = LLFile::stat(strings_path_full, &st);
if (rc != 0)
{
LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc);
}
else if (S_ISDIR(st.st_mode))
{
LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
crash_reason = "The filename '" + strings_path_full + "' is a directory name";
}
else
{
LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
crash_reason = "The filename '" + strings_path_full + "' doesn't seem to be a regular file name";
}
}
// initial check to make sure files are there failed
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Viewer failed to find localization and UI files."
<< " Please reinstall viewer from https://secondlife.com/support/downloads"
<< " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
LL_ERRS() << "Viewer failed to open some of localization and UI files."
<< " " << crash_reason << "." << LL_ENDL;
}
LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");

View File

@ -670,6 +670,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
break;
case FFLOAD_HDRI:
allowedv->push_back("exr");
case FFLOAD_MODEL:
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;

View File

@ -31,6 +31,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "llcombobox.h"
#include "llfloaterreg.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
@ -296,7 +297,7 @@ void LLFloaterCreateLandmark::onCreateFolderClicked()
void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
{
populateFoldersList(folder_id);
populateFoldersList(folder_id);
}
void LLFloaterCreateLandmark::onSaveClicked()
@ -389,6 +390,7 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
mItem = item;
mAssetID = mItem->getAssetUUID();
mParentID = mItem->getParentUUID();
setVisibleAndFrontmost(true);
break;
}
@ -418,8 +420,7 @@ void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
closeFloater();
}
LLUUID folder_id = mFolderCombo->getValue().asUUID();
if (folder_id != mItem->getParentUUID())
if (mParentID != mItem->getParentUUID())
{
// user moved landmark in inventory,
// assume that we are done all other changes should already be commited

View File

@ -69,6 +69,7 @@ private:
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
LLUUID mAssetID;
LLUUID mParentID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;

View File

@ -57,8 +57,7 @@ static const S32 USED_EMOJIS_IMAGE_INDEX = 0x23F2;
// https://www.compart.com/en/unicode/U+1F6D1
static const S32 EMPTY_LIST_IMAGE_INDEX = 0x1F6D1;
// The following categories should follow the required alphabetic order
static const std::string RECENTLY_USED_CATEGORY = "1 recently used";
static const std::string FREQUENTLY_USED_CATEGORY = "2 frequently used";
static const std::string FREQUENTLY_USED_CATEGORY = "frequently used";
// Floater state related variables
static std::list<llwchar> sRecentlyUsed;
@ -445,11 +444,10 @@ void LLFloaterEmojiPicker::fillGroups()
params.name = "all_categories";
createGroupButton(params, rect, ALL_EMOJIS_IMAGE_INDEX);
// Create group and button for "Recently used" and/or "Frequently used"
if (!sRecentlyUsed.empty() || !sFrequentlyUsed.empty())
// Create group and button for "Frequently used"
if (!sFrequentlyUsed.empty())
{
std::map<std::string, std::vector<LLEmojiSearchResult>> cats;
fillCategoryRecentlyUsed(cats);
fillCategoryFrequentlyUsed(cats);
if (!cats.empty())
@ -482,40 +480,6 @@ void LLFloaterEmojiPicker::fillGroups()
resizeGroupButtons();
}
void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats)
{
if (sRecentlyUsed.empty())
return;
std::vector<LLEmojiSearchResult> emojis;
// In case of empty mFilterPattern we'd use sRecentlyUsed directly
if (!mFilterPattern.empty())
{
// List all emojis in "Recently used"
const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
std::size_t begin, end;
for (llwchar emoji : sRecentlyUsed)
{
auto e2d = emoji2descr.find(emoji);
if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
{
for (const std::string& shortcode : e2d->second->ShortCodes)
{
if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
{
emojis.emplace_back(emoji, shortcode, begin, end);
}
}
}
}
if (emojis.empty())
return;
}
cats.emplace(std::make_pair(RECENTLY_USED_CATEGORY, emojis));
}
void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats)
{
if (sFrequentlyUsed.empty())
@ -756,7 +720,6 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes
{
// Place the category title
std::string title =
category == RECENTLY_USED_CATEGORY ? getString("title_for_recently_used") :
category == FREQUENTLY_USED_CATEGORY ? getString("title_for_frequently_used") :
isupper(category.front()) ? category : LLStringUtil::capitalize(category);
LLEmojiGridDivider* div = new LLEmojiGridDivider(row_panel_params, title);
@ -769,21 +732,7 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes
{
const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
LLEmojiSearchResult emoji { 0, "", 0, 0 };
if (category == RECENTLY_USED_CATEGORY)
{
for (llwchar code : sRecentlyUsed)
{
const LLEmojiDictionary::emoji2descr_map_t::const_iterator& e2d = emoji2descr.find(code);
if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
{
emoji.Character = code;
emoji.String = e2d->second->ShortCodes.front();
createEmojiIcon(emoji, category, row_panel_params, row_list_params, icon_params,
icon_rect, max_icons, bg, row, icon_index);
}
}
}
else if (category == FREQUENTLY_USED_CATEGORY)
if (category == FREQUENTLY_USED_CATEGORY)
{
for (const auto& code : sFrequentlyUsed)
{

View File

@ -60,7 +60,6 @@ public:
private:
void initialize();
void fillGroups();
void fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
void fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
void fillGroupEmojis(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats, U32 index);
void createGroupButton(LLButton::Params& params, const LLRect& rect, llwchar emoji);

View File

@ -115,12 +115,12 @@ bool LLFloaterPerformance::postBuild()
mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
mHUDList->setHoverIconName("StopReload_Off");
mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));
mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list");
mObjectList->setNameListType(LLNameListCtrl::SPECIAL);
mObjectList->setHoverIconName("StopReload_Off");
mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));
mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
@ -527,9 +527,13 @@ void LLFloaterPerformance::setFPSText()
mTextFPSLabel->setValue(fps_text);
}
void LLFloaterPerformance::detachItem(const LLUUID& item_id)
void LLFloaterPerformance::detachObject(const LLUUID& obj_id)
{
LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
LLViewerObject* obj = gObjectList.findObject(obj_id);
if (obj)
{
LLAppearanceMgr::instance().removeItemFromAvatar(obj->getAttachmentItemID());
}
}
void LLFloaterPerformance::onClickAdvanced()

View File

@ -48,7 +48,7 @@ public:
void hidePanels();
void showAutoadjustmentsPanel();
void detachItem(const LLUUID& item_id);
void detachObject(const LLUUID& obj_id);
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);

View File

@ -329,6 +329,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
@ -360,6 +361,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreference::updateIndirectMaxNonImpostors, this, _2));
mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
@ -543,6 +545,7 @@ LLFloaterPreference::~LLFloaterPreference()
{
LLConversationLog::instance().removeObserver(this);
mComplexityChangedSignal.disconnect();
mImpostorsChangedSignal.disconnect();
}
void LLFloaterPreference::draw()
@ -1287,6 +1290,9 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
void LLFloaterPreference::refresh()
{
LLPanel::refresh();
setMaxNonImpostorsText(
gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
LLAvatarComplexityControls::setText(
gSavedSettings.getU32("RenderAvatarMaxComplexity"),
getChild<LLTextBox>("IndirectMaxComplexityText", true));
@ -1561,6 +1567,44 @@ void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_bo
}
}
void LLFloaterPreference::updateMaxNonImpostors()
{
// Called when the IndirectMaxNonImpostors control changes
// Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors", true);
U32 value = ctrl->getValue().asInteger();
if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
{
value = 0;
}
gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreference::updateIndirectMaxNonImpostors(const LLSD& newvalue)
{
U32 value = newvalue.asInteger();
if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
{
gSavedSettings.setU32("IndirectMaxNonImpostors", value);
}
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreference::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
{
if (0 == value)
{
text_box->setText(LLTrans::getString("no_limit"));
}
else
{
text_box->setText(llformat("%d", value));
}
}
void LLFloaterPreference::updateMaxComplexity()
{
// Called when the IndirectMaxComplexity control changes

View File

@ -206,6 +206,9 @@ private:
void onDeleteTranscripts();
void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
void updateDeleteTranscriptsButton();
void updateMaxNonImpostors();
void updateIndirectMaxNonImpostors(const LLSD& newvalue);
void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
void updateMaxComplexity();
void updateComplexityText();
static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);
@ -234,6 +237,7 @@ private:
std::unique_ptr< ll::prefs::SearchData > mSearchData;
bool mSearchDataDirty;
boost::signals2::connection mImpostorsChangedSignal;
boost::signals2::connection mComplexityChangedSignal;
void onUpdateFilterTerm( bool force = false );

View File

@ -51,6 +51,8 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));
}
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
@ -58,7 +60,6 @@ LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
mComplexityChangedSignal.disconnect();
mComplexityModeChangedSignal.disconnect();
mLODFactorChangedSignal.disconnect();
mNumImpostorsChangedSignal.disconnect();
}
bool LLFloaterPreferenceGraphicsAdvanced::postBuild()
@ -254,8 +255,8 @@ void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LL
if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
{
gSavedSettings.setU32("IndirectMaxNonImpostors", value);
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)

View File

@ -61,6 +61,7 @@ protected:
void onBtnOK(const LLSD& userdata);
void onBtnCancel(const LLSD& userdata);
boost::signals2::connection mImpostorsChangedSignal;
boost::signals2::connection mComplexityChangedSignal;
boost::signals2::connection mComplexityModeChangedSignal;
boost::signals2::connection mLODFactorChangedSignal;

View File

@ -903,39 +903,6 @@ private:
};
F32 shader_timer_benchmark(std::vector<LLRenderTarget> & dest, TextureHolder & texHolder, U32 textures_count, LLVertexBuffer * buff, F32 &seconds)
{
// run GPU timer benchmark
//number of samples to take
const S32 samples = 64;
{
ShaderProfileHelper initProfile;
dest[0].bindTarget();
gBenchmarkProgram.bind();
for (S32 c = 0; c < samples; ++c)
{
for (U32 i = 0; i < textures_count; ++i)
{
texHolder.bind(i);
buff->setBuffer();
buff->drawArrays(LLRender::TRIANGLES, 0, 3);
}
}
gBenchmarkProgram.unbind();
dest[0].flush();
}
F32 ms = gBenchmarkProgram.mTimeElapsed / 1000000.f;
seconds = ms / 1000.f;
F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
F64 gpixels_drawn = samples_drawn / 1000000000.0;
F32 samples_sec = (F32)(gpixels_drawn / seconds);
return samples_sec * 4; // 4 bytes per sample
}
//-----------------------------------------------------------------------------
// gpu_benchmark()
// returns measured memory bandwidth of GPU in gigabytes per second
@ -977,6 +944,9 @@ F32 gpu_benchmark()
//number of textures
const U32 count = 32;
//number of samples to take
const S32 samples = 64;
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
@ -1066,15 +1036,33 @@ F32 gpu_benchmark()
LLGLSLShader::unbind();
// run GPU timer benchmark twice
F32 seconds = 0;
F32 gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
// run GPU timer benchmark
{
ShaderProfileHelper initProfile;
dest[0].bindTarget();
gBenchmarkProgram.bind();
for (S32 c = 0; c < samples; ++c)
{
for (U32 i = 0; i < count; ++i)
{
texHolder.bind(i);
buff->setBuffer();
buff->drawArrays(LLRender::TRIANGLES, 0, 3);
}
}
gBenchmarkProgram.unbind();
dest[0].flush();
}
LL_INFOS("Benchmark") << "Memory bandwidth, 1st run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
F64 gpixels_drawn = samples_drawn / 1000000000.0;
F32 samples_sec = (F32)(gpixels_drawn/seconds);
F32 gbps = samples_sec*4; // 4 bytes per sample
LL_INFOS("Benchmark") << "Memory bandwidth, final run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}

View File

@ -844,7 +844,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
if (isAgentInventory() && !single_folder_root)
if (isAgentInventory() && !single_folder_root && !isMarketplaceListingsFolder())
{
items.push_back(std::string("New folder from selected"));
items.push_back(std::string("Subfolder Separator"));
@ -5315,7 +5315,7 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
// but so is collecting and passing descendants' ids
inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1, cb);
inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);
gInventory.createNewCategory(dest_id,
LLFolderType::FT_OUTFIT,
inv_cat->getName(),
@ -5323,11 +5323,25 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
inv_cat->getThumbnailUUID());
}
void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb)
void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id,
LLUUID cat_dest_id,
LLPointer<LLInventoryCallback> cb,
LLHandle<LLInventoryPanel> inventory_panel)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
getInventoryModel()->getDirectDescendentsOf(cat_source_id, categories, items);
LLInventoryPanel* panel = inventory_panel.get();
if (!panel)
{
return;
}
LLInventoryModel* model = panel->getModel();
if (!model)
{
return;
}
model->getDirectDescendentsOf(cat_source_id, categories, items);
LLInventoryObject::const_object_list_t link_array;

View File

@ -378,7 +378,10 @@ public:
static void staticFolderOptionsMenu();
protected:
void outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb);
static void outfitFolderCreatedCallback(LLUUID cat_source_id,
LLUUID cat_dest_id,
LLPointer<LLInventoryCallback> cb,
LLHandle<LLInventoryPanel> inventory_panel);
void callback_pasteFromClipboard(const LLSD& notification, const LLSD& response);
void perform_pasteFromClipboard();
void gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level);

View File

@ -30,6 +30,7 @@
#include "llaisapi.h"
#include "llagent.h"
#include "llappviewer.h"
#include "llappearancemgr.h"
#include "llcallbacklist.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
@ -470,6 +471,22 @@ void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback)
callback();
LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT);
if (id.notNull())
{
// COF might have fetched base outfit folder through a link, but it hasn't
// fetched base outfit's content, which doesn't nessesary match COF,
// so make sure it's up to date
LLUUID baseoutfit_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
if (baseoutfit_id.notNull())
{
LLViewerInventoryCategory* cat = gInventory.getCategory(baseoutfit_id);
if (!cat || cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(baseoutfit_id, no_op);
}
}
}
});
// start idle loop to track completion

View File

@ -924,8 +924,8 @@ void LLOutfitListBase::onIdleRefreshList()
if (cat)
{
std::string name = cat->getName();
updateChangedCategoryName(cat, name);
}
updateChangedCategoryName(cat, name);
}
curent_time = LLTimer::getTotalSeconds();
if (curent_time >= end_time)

View File

@ -68,6 +68,9 @@ LLPanelEmojiComplete::LLPanelEmojiComplete(const LLPanelEmojiComplete::Params& p
{
LLScrollbar::Params sbparams;
sbparams.orientation(LLScrollbar::VERTICAL);
sbparams.doc_size(static_cast<S32>(mTotalEmojis));
sbparams.doc_pos(0);
sbparams.page_size(static_cast<S32>(mVisibleEmojis));
sbparams.change_callback([this](S32 index, LLScrollbar*) { onScrollbarChange(index); });
mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);
addChild(mScrollbar);

View File

@ -407,10 +407,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, bool damp_w
F32* vw = (F32*) vertex_weightsp.get();
F32* cw = (F32*) clothing_weightsp.get();
S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size);
S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size);
//S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF;
//LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size);
//S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF;
//LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size);
// Both allocated in LLPolyMeshSharedData::allocateVertexData(unsigned int)
memcpy(tc, mMesh->getTexCoords(), num_verts*2*sizeof(F32) );
memcpy(vw, mMesh->getWeights(), num_verts*sizeof(F32) );
LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));
}

View File

@ -1730,8 +1730,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
user_data_path_cache += gDirUtilp->getDirDelimiter();
std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
// See if the plugin executable exists
llstat s;
if(LLFile::stat(launcher_name, &s))
@ -1748,6 +1746,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");
media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log);
media_source->setLanguageCode(LLUI::getLanguage());
media_source->setZoomFactor(zoom_factor);

View File

@ -2917,6 +2917,17 @@ void LLViewerObject::fetchInventoryFromServer()
delete mInventory;
mInventory = NULL;
// This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
if (mRegionp && !mRegionp->getCapability("RequestTaskInventory").empty())
{
LLCoros::instance().launch("LLViewerObject::fetchInventoryFromCapCoro()",
boost::bind(&LLViewerObject::fetchInventoryFromCapCoro, mID));
}
else
{
LL_WARNS() << "Using old task inventory path!" << LL_ENDL;
// Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
@ -2926,15 +2937,13 @@ void LLViewerObject::fetchInventoryFromServer()
msg->nextBlockFast(_PREHASH_InventoryData);
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
// This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
}
}
}
void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
{
// unless already waiting, drop previous request and shedule an update
// unless already waiting, drop previous request and schedule an update
if (mInvRequestState != INVENTORY_REQUEST_WAIT)
{
if (mInvRequestXFerId != 0)
@ -2965,6 +2974,80 @@ void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64
}
}
//static
void LLViewerObject::fetchInventoryFromCapCoro(const LLUUID task_inv)
{
LLViewerObject *obj = gObjectList.findObject(task_inv);
if (obj)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TaskInventoryRequest", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
std::string url = obj->mRegionp->getCapability("RequestTaskInventory") + "?task_id=" + obj->mID.asString();
// If we already have a copy of the inventory then add it so the server won't re-send something we already have.
// We expect this case to crop up in the case of failed inventory mutations, but it might happen otherwise as well.
if (obj->mInventorySerialNum && obj->mInventory)
url += "&inventory_serial=" + std::to_string(obj->mInventorySerialNum);
obj->mInvRequestState = INVENTORY_XFER;
LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
// Object may have gone away while we were suspended, double-check that it still exists
obj = gObjectList.findObject(task_inv);
if (!obj)
{
LL_WARNS() << "Object " << task_inv << " went away while fetching inventory, dropping result" << LL_ENDL;
return;
}
bool potentially_stale = false;
if (status)
{
// Dealing with inventory serials is kind of funky. They're monotonically increasing and 16 bits,
// so we expect them to overflow, but we can use inv serial < expected serial as a signal that we may
// have mutated the task inventory since we kicked off the request, and those mutations may have not
// been taken into account yet. Of course, those mutations may have actually failed which would result
// in the inv serial never increasing.
//
// When we detect this case, set the expected inv serial to the inventory serial we actually received
// and kick off a re-request after a slight delay.
S16 serial = (S16)result["inventory_serial"].asInteger();
potentially_stale = serial < obj->mExpectedInventorySerialNum;
LL_INFOS() << "Inventory loaded for " << task_inv << LL_ENDL;
obj->mInventorySerialNum = serial;
obj->mExpectedInventorySerialNum = serial;
obj->loadTaskInvLLSD(result);
}
else if (status.getType() == 304)
{
LL_INFOS() << "Inventory wasn't changed on server!" << LL_ENDL;
obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
// Even though it wasn't necessary to send a response, we still may have mutated
// the inventory since we kicked off the request, check for that case.
potentially_stale = obj->mInventorySerialNum < obj->mExpectedInventorySerialNum;
// Set this to what we already have so that we don't re-request a second time.
obj->mExpectedInventorySerialNum = obj->mInventorySerialNum;
}
else
{
// Not sure that there's anything sensible we can do to recover here, retrying in a loop would be bad.
LL_WARNS() << "Error status while requesting task inventory: " << status.toString() << LL_ENDL;
obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
}
if (potentially_stale)
{
// Stale? I guess we can use what we got for now, but we'll have to re-request
LL_WARNS() << "Stale inv_serial? Re-requesting." << LL_ENDL;
obj->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
}
}
}
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@ -3140,6 +3223,20 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
S16 serial = 0;
msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial);
if (object->mRegionp && !object->mRegionp->getCapability("RequestTaskInventory").empty())
{
// It seems that simulator may ask us to re-download the task inventory if an update to the inventory
// happened out-of-band while we had the object selected (like if a script is saved.)
//
// If we're meant to use the HTTP capability, ignore the contents of the UDP message and fetch the
// inventory via the CAP so that we don't flow down the UDP inventory request path unconditionally here.
// We shouldn't need to wait, as any updates should already be ready to fetch by this point.
LL_INFOS() << "Handling unsolicited ReplyTaskInventory for " << task_id << LL_ENDL;
object->mExpectedInventorySerialNum = serial;
object->fetchInventoryFromServer();
return;
}
if (serial == object->mInventorySerialNum
&& serial < object->mExpectedInventorySerialNum)
{
@ -3347,6 +3444,47 @@ bool LLViewerObject::loadTaskInvFile(const std::string& filename)
return true;
}
void LLViewerObject::loadTaskInvLLSD(const LLSD& inv_result)
{
if (inv_result.has("contents"))
{
if(mInventory)
{
mInventory->clear(); // will deref and delete it
}
else
{
mInventory = new LLInventoryObject::object_list_t;
}
// Synthesize the "Contents" category, the viewer expects it, but it isn't sent.
LLPointer<LLInventoryObject> inv = new LLInventoryObject(mID, LLUUID::null, LLAssetType::AT_CATEGORY, "Contents");
mInventory->push_front(inv);
const LLSD& inventory = inv_result["contents"];
for (const auto& inv_entry : llsd::inArray(inventory))
{
if (inv_entry.has("item_id"))
{
LLPointer<LLViewerInventoryItem> inv = new LLViewerInventoryItem;
inv->unpackMessage(inv_entry);
mInventory->push_front(inv);
}
else
{
LL_WARNS_ONCE() << "Unknown inventory entry while reading from inventory file. Entry: '"
<< inv_entry << "'" << LL_ENDL;
}
}
}
else
{
LL_WARNS() << "unable to load task inventory: " << inv_result << LL_ENDL;
return;
}
doInventoryCallback();
}
void LLViewerObject::doInventoryCallback()
{
for (callback_list_t::iterator iter = mInventoryCallbacks.begin();

View File

@ -688,6 +688,7 @@ private:
// forms task inventory request after some time passed, marks request as pending
void fetchInventoryDelayed(const F64 &time_seconds);
static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
static void fetchInventoryFromCapCoro(const LLUUID task_inv);
public:
//
@ -826,6 +827,7 @@ protected:
static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
bool loadTaskInvFile(const std::string& filename);
void loadTaskInvLLSD(const LLSD &inv_result);
void doInventoryCallback();
bool isOnMap();

View File

@ -3239,6 +3239,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("FetchInventory2");
capabilityNames.append("FetchInventoryDescendents2");
capabilityNames.append("IncrementCOFVersion");
capabilityNames.append("RequestTaskInventory");
AISAPI::getCapNames(capabilityNames);
capabilityNames.append("InterestList");

View File

@ -1014,6 +1014,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old");
if (gDirUtilp->fileExists(new_log))
{
LLFile::remove(old_log, ENOENT);
LLFile::rename(new_log, old_log);
}

View File

@ -13,7 +13,6 @@
chrome="true"
height="350"
width="304">
<floater.string name="title_for_recently_used" value="Recently used"/>
<floater.string name="title_for_frequently_used" value="Frequently used"/>
<floater.string name="text_no_emoji_for_filter" value="No emoji found for '[FILTER]'"/>
<scroll_container

View File

@ -75,7 +75,7 @@
step_size="16"
doc_pos="0"
doc_size="3000"
page_size="0"
page_size="50"
/>
</layout_panel>
<layout_panel name="timers_panel"

View File

@ -257,7 +257,7 @@
height="16"
increment="1"
initial_value="12"
label="Max. # of non-impostors:"
label="Max. # animated avatars:"
label_width="185"
layout="topleft"
left="30"

View File

@ -37,7 +37,8 @@
top="16"
left="0"
right="-1"
bottom="-1">
bottom="-1"
orientation="horizontal">
<layout_panel
name="map_lp"
width="385"

View File

@ -4214,16 +4214,6 @@ function="World.EnvPreset"
<menu_item_separator/>
<menu_item_check
label="HTTP Textures"
name="HTTP Textures">
<menu_item_check.on_check
function="CheckControl"
parameter="ImagePipelineUseHTTP" />
<menu_item_check.on_click
function="ToggleControl"
parameter="ImagePipelineUseHTTP" />
</menu_item_check>
<menu_item_call
label="Compress Images"
name="Compress Images">

View File

@ -210,26 +210,60 @@
increment="8"
initial_value="160"
label="Draw distance:"
label_width="90"
label_width="187"
layout="topleft"
left="30"
min_val="64"
max_val="512"
name="DrawDistance"
top_delta="40"
width="330" />
width="427" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left_delta="330"
left_delta="427"
name="DrawDistanceMeterText2"
top_delta="0"
width="128">
m
</text>
<slider
control_name="IndirectMaxNonImpostors"
name="IndirectMaxNonImpostors"
decimal_digits="0"
increment="1"
initial_value="12"
show_text="false"
min_val="1"
max_val="66"
label="Maximum number of animated avatars:"
follows="left|top"
layout="topleft"
height="16"
label_width="240"
left="30"
top_delta="40"
width="393">
<slider.commit_callback
function="Pref.UpdateIndirectMaxNonImpostors"
parameter="IndirectNonImpostorsText" />
</slider>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
top_delta="0"
left_delta="397"
text_readonly_color="LabelDisabledColor"
name="IndirectMaxNonImpostorsText"
width="65">
0
</text>
<button
height="23"

View File

@ -264,8 +264,7 @@
top_pad="1"
halign="right"
name="txt_alt1">
Sky [INDEX]
[ALTITUDE]m
Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"
@ -310,8 +309,7 @@
top_pad="1"
halign="right"
name="txt_alt2">
Sky [INDEX]
[ALTITUDE]m
Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"
@ -356,8 +354,7 @@
top_pad="1"
halign="right"
name="txt_alt3">
Sky [INDEX]
[ALTITUDE]m
Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"