Skip to content

Commit b1497e7

Browse files
committed
#4296 Crash at renderMorphMasks
1 parent 88fdeef commit b1497e7

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

indra/llappearance/lltexlayer.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
12931293
{
12941294
if (!force_render && !hasMorph())
12951295
{
1296-
LL_DEBUGS() << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
1296+
LL_DEBUGS("Morph") << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
12971297
return;
12981298
}
12991299
LL_PROFILE_ZONE_SCOPED;
@@ -1325,7 +1325,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
13251325
success &= param->render( x, y, width, height );
13261326
if (!success && !force_render)
13271327
{
1328-
LL_DEBUGS() << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
1328+
LL_DEBUGS("Morph") << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
13291329
return;
13301330
}
13311331
}
@@ -1365,7 +1365,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
13651365
}
13661366
else
13671367
{
1368-
LL_WARNS() << "Skipping rendering of " << getInfo()->mStaticImageFileName
1368+
LL_WARNS("Morph") << "Skipping rendering of " << getInfo()->mStaticImageFileName
13691369
<< "; expected 1 or 4 components." << LL_ENDL;
13701370
}
13711371
}
@@ -1404,8 +1404,8 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
14041404
// We can get bad morph masks during login, on minimize, and occasional gl errors.
14051405
// We should only be doing this when we believe something has changed with respect to the user's appearance.
14061406
{
1407-
LL_DEBUGS("Avatar") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
1408-
// clear out a slot if we have filled our cache
1407+
LL_DEBUGS("Morph") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
1408+
// clear out a slot if we have filled our cache
14091409
S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
14101410
while ((S32)mAlphaCache.size() >= max_cache_entries)
14111411
{
@@ -1444,13 +1444,20 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
14441444
}
14451445

14461446
glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
1447-
1448-
U8* alpha_cursor = alpha_data;
1449-
U8* pixel = temp;
1450-
for (int i = 0; i < pixels; i++)
1447+
GLenum error = glGetError();
1448+
if (error != GL_NO_ERROR)
1449+
{
1450+
LL_INFOS("Morph") << "GL Error while reading back morph texture. Error code: " << error << LL_ENDL;
1451+
}
1452+
else
14511453
{
1452-
*alpha_cursor++ = pixel[3];
1453-
pixel += 4;
1454+
U8* alpha_cursor = alpha_data;
1455+
U8* pixel = temp;
1456+
for (int i = 0; i < pixels; i++)
1457+
{
1458+
*alpha_cursor++ = pixel[3];
1459+
pixel += 4;
1460+
}
14541461
}
14551462

14561463
gGL.getTexUnit(0)->disable();

indra/llrender/llimagegl.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,8 +1870,17 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
18701870
glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
18711871
if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
18721872
{
1873-
LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ;
1874-
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
1873+
constexpr S64 MAX_GL_BYTES = 2048 * 2048;
1874+
if (glbytes > 0 && glbytes <= MAX_GL_BYTES)
1875+
{
1876+
LLError::LLUserWarningMsg::showOutOfMemory();
1877+
LL_ERRS() << "Memory allocation failed for reading back texture. Data size: " << glbytes << LL_ENDL;
1878+
}
1879+
else
1880+
{
1881+
LL_WARNS() << "Memory allocation failed for reading back texture. Data size is: " << glbytes << LL_ENDL;
1882+
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL;
1883+
}
18751884
return false ;
18761885
}
18771886

@@ -1882,8 +1891,18 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
18821891
{
18831892
if(!imageraw->allocateDataSize(width, height, ncomponents))
18841893
{
1885-
LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ;
1886-
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
1894+
constexpr F32 MAX_IMAGE_SIZE = 2048 * 2048;
1895+
F32 size = (F32)width * (F32)height * (F32)ncomponents;
1896+
if (size > 0 && size <= MAX_IMAGE_SIZE)
1897+
{
1898+
LLError::LLUserWarningMsg::showOutOfMemory();
1899+
LL_ERRS() << "Memory allocation failed for reading back texture. Data size: " << size << LL_ENDL;
1900+
}
1901+
else
1902+
{
1903+
LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL;
1904+
LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL;
1905+
}
18871906
return false ;
18881907
}
18891908

indra/newview/llappviewer.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,24 +2245,29 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
22452245
// Callback for LLError::LLUserWarningMsg
22462246
void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)
22472247
{
2248-
if (!message_string.empty())
2249-
{
2250-
OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
2251-
}
2248+
// message is going to hang viewer, create marker first
22522249
switch (code)
22532250
{
22542251
case LLError::LLUserWarningMsg::ERROR_OTHER:
22552252
LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH);
22562253
break;
22572254
case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC:
22582255
LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC);
2256+
// When system run out of memory and errorHandler gets called from a thread,
2257+
// main thread might keep going while OSMessageBox freezes the caller.
2258+
// Todo: handle it better, but for now disconnect to avoid making things worse
2259+
gDisconnected = true;
22592260
break;
22602261
case LLError::LLUserWarningMsg::ERROR_MISSING_FILES:
22612262
LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
22622263
break;
22632264
default:
22642265
break;
22652266
}
2267+
if (!message_string.empty())
2268+
{
2269+
OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
2270+
}
22662271
}
22672272

22682273
void LLAppViewer::initLoggingAndGetLastDuration()

0 commit comments

Comments
 (0)