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
22 changes: 22 additions & 0 deletions indra/llcommon/tests/llprocess_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ void yield(int seconds=1)
LLEventPumps::instance().obtain("mainloop").post(LLSD());
}

constexpr int EOF_EVENT_RETRY_COUNT = 20;
constexpr auto EOF_EVENT_RETRY_DELAY = std::chrono::milliseconds(50);

void waitfor(LLProcess& proc, int timeout=60)
{
int i = 0;
Expand Down Expand Up @@ -1222,6 +1225,14 @@ namespace tut
LLProcess::ReadPipe& childout(py.mPy->getReadPipe(LLProcess::STDOUT));
EventListener listener(childout.getPump());
waitfor(*py.mPy);
// On Windows the pipe-close EOF notification can trail the process exit
// status by a short interval, so keep pumping for up to 1 second
// (20 * 50 ms) until it arrives.
for (int i = 0; i < EOF_EVENT_RETRY_COUNT && listener.mHistory.empty(); ++i)
{
std::this_thread::sleep_for(EOF_EVENT_RETRY_DELAY);
LLEventPumps::instance().obtain("mainloop").post(LLSD());
}
// We can't be positive there will only be a single event, if the OS
// (or any other intervening layer) does crazy buffering. What we want
// to ensure is that there was exactly ONE event with "eof" true, and
Expand Down Expand Up @@ -1697,6 +1708,17 @@ namespace tut
EventListener errListener(childerr.getPump());

waitfor(*py.mPy);
// On Windows the pipe-close EOF notification can trail the process exit
// status by a short interval, so keep pumping for up to 1 second
// (20 * 50 ms) until both pipes report it.
for (int i = 0;
i < EOF_EVENT_RETRY_COUNT &&
(outListener.mHistory.empty() || errListener.mHistory.empty());
++i)
{
std::this_thread::sleep_for(EOF_EVENT_RETRY_DELAY);
LLEventPumps::instance().obtain("mainloop").post(LLSD());
}

ensure_equals("stdout size", childout.size(), 0);
ensure_equals("stderr size", childerr.size(), 0);
Expand Down
22 changes: 14 additions & 8 deletions indra/llinventory/llinventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,12 +983,14 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const

if (mThumbnailUUID.notNull())
{
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
LLSD& thumbnail = sd[INV_THUMBNAIL_LABEL];
thumbnail[INV_ASSET_ID_LABEL] = mThumbnailUUID;
}

if (mFavorite)
{
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
LLSD& favorite = sd[INV_FAVORITE_LABEL];
favorite[INV_TOGGLED_LABEL] = mFavorite;
}

U32 mask = mPermissions.getMaskBase();
Expand All @@ -1005,7 +1007,7 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
cipher.encrypt(shadow_id.mData, UUID_BYTES);
sd[INV_SHADOW_ID_LABEL] = shadow_id;
}
sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
if(!inv_type_str.empty())
{
Expand Down Expand Up @@ -1298,12 +1300,14 @@ LLSD LLInventoryCategory::asLLSD() const

if (mThumbnailUUID.notNull())
{
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
LLSD& thumbnail = sd[INV_THUMBNAIL_LABEL];
thumbnail[INV_ASSET_ID_LABEL] = mThumbnailUUID;
}

if (mFavorite)
{
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
LLSD& favorite = sd[INV_FAVORITE_LABEL];
favorite[INV_TOGGLED_LABEL] = mFavorite;
}

return sd;
Expand Down Expand Up @@ -1563,17 +1567,19 @@ void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
{
cat_data[INV_FOLDER_ID_LABEL] = mUUID;
cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
cat_data[INV_NAME_LABEL] = mName;

if (mThumbnailUUID.notNull())
{
cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
LLSD& thumbnail = cat_data[INV_THUMBNAIL_LABEL];
thumbnail[INV_ASSET_ID_LABEL] = mThumbnailUUID;
}
if (mFavorite)
{
cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
LLSD& favorite = cat_data[INV_FAVORITE_LABEL];
favorite[INV_TOGGLED_LABEL] = mFavorite;
}
}

Expand Down
25 changes: 23 additions & 2 deletions indra/llrender/lluiimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,17 @@ S32 LLUIImage::getHeight() const

buffer_data_list_t* LLUIImage::findDisplayList(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, bool solid_color) const
{
LLImageGL* gl_image = mImage->getGLTexture();
if (!gl_image)
{
return nullptr;
}

LLVector3 ui_translation = gGL.getUITranslation();
LLVector3 ui_scale = gGL.getUIScale();
LLGLuint tex_name = gl_image->getTexName();

auto key = PackedKey::create(x, y, width, height, color, solid_color, ui_translation, ui_scale);
auto key = PackedKey::create(x, y, width, height, color, solid_color, ui_translation, ui_scale, tex_name);

auto it = mDisplayLists.find(key);
if (it != mDisplayLists.end())
Expand All @@ -94,9 +101,23 @@ buffer_data_list_t* LLUIImage::findDisplayList(S32 x, S32 y, S32 width, S32 heig
buffer_data_list_t* LLUIImage::genDisplayList(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, bool solid_color) const
{
LL_PROFILE_ZONE_SCOPED;

LLImageGL* gl_image = mImage->getGLTexture();
if (!gl_image)
{
// Don't cache when texture hasn't been created yet
// draw just aborts in this case, so don't draw either.
return nullptr;
}

LLVector3 ui_translation = gGL.getUITranslation();
LLVector3 ui_scale = gGL.getUIScale();
auto key = PackedKey::create(x, y, width, height, color, solid_color, ui_translation, ui_scale);

// Get the GL texture name - this uniquely identifies the current texture state
// including discard level changes, texture recreation, etc.
LLGLuint tex_name = gl_image->getTexName();

auto key = PackedKey::create(x, y, width, height, color, solid_color, ui_translation, ui_scale, tex_name);

CachedDisplayList cached;
cached.last_used = std::chrono::steady_clock::now();
Expand Down
25 changes: 16 additions & 9 deletions indra/llrender/lluiimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,34 +127,38 @@ class LLUIImage : public LLRefCount
// Packed key for identifying unique display list configurations
struct PackedKey
{
uint64_t position; // x and y coordinates
uint64_t color_flags; // RGBA color + solid_color flag
uint64_t dimensions; // width and height
uint64_t translate; // UI offset
uint64_t scale; // UI scale
uint64_t position; // x and y coordinates (32 bits each)
uint64_t color_flags; // RGBA color (8 bits each) + solid_color flag (1 bit)
uint64_t dimensions; // width and height (32 bits each)
uint64_t translate; // UI translation (32 bits each for X and Y)
uint64_t scale; // UI scale (32 bits each for X and Y)
uint64_t tex_name; // OpenGL texture name (32 bits) + padding

constexpr bool operator==(const PackedKey& other) const
{
return position == other.position &&
color_flags == other.color_flags &&
dimensions == other.dimensions &&
translate == other.translate &&
scale == other.scale;
scale == other.scale &&
tex_name == other.tex_name;
}

struct Hash
{
std::size_t operator()(const PackedKey& key) const
{
return static_cast<std::size_t>(key.position ^ key.color_flags ^
key.dimensions ^ key.translate ^ key.scale);
key.dimensions ^ key.translate ^
key.scale ^ key.tex_name);
}
};

// Static factory function to create PackedKey from parameters
static constexpr PackedKey create(S32 x, S32 y, S32 width, S32 height,
const LLColor4& color, bool solid_color,
const LLVector3& translate, const LLVector3& scale)
const LLVector3& translate, const LLVector3& scale,
LLGLuint texture_name)
{
auto float_to_u8 = [](F32 f) -> uint8_t {
return static_cast<uint8_t>(llclamp(f * 255.0f, 0.0f, 255.0f));
Expand Down Expand Up @@ -187,7 +191,10 @@ class LLUIImage : public LLRefCount
uint64_t scl = (static_cast<uint64_t>(float_to_bits(scale.mV[VX])) << 32) |
static_cast<uint64_t>(float_to_bits(scale.mV[VY]));

return PackedKey{ pos, col, dim, trns, scl };
// Store full 32-bit texture name in lower 32 bits (upper 32 bits unused/zero)
uint64_t tex = static_cast<uint64_t>(texture_name);

return PackedKey{ pos, col, dim, trns, scl, tex };
}
};

Expand Down
12 changes: 8 additions & 4 deletions indra/newview/llappviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1749,15 +1749,15 @@ bool LLAppViewer::cleanup()
// Give any remaining SLPlugin instances a chance to exit cleanly.
LLPluginProcessParent::shutdown();

disconnectViewer();

if (LLWatchdog::instanceExists())
{
// Signal a stop early, so that it will be out
// of sleep loop by the time we get to clean it.
// of 1s sleep loop by the time we get to clean it.
LLWatchdog::getInstance()->shutdown();
}

disconnectViewer();

LLViewerCamera::deleteSingleton();

LL_INFOS() << "Viewer disconnected" << LL_ENDL;
Expand Down Expand Up @@ -2058,7 +2058,7 @@ bool LLAppViewer::cleanup()
}

LLSplashScreen::show();
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
LLSplashScreen::update(LLTrans::getString("ShutdownCleanup"));

LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;

Expand Down Expand Up @@ -2160,6 +2160,10 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();

LLSplashScreen::update(LLTrans::getString("CompressingInventoryCache"));
LLInventoryModel::waitForPendingCacheWrites();
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));

ll_close_fail_log();

LLError::LLCallStacks::cleanup();
Expand Down
Loading
Loading