summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp40
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp38
3 files changed, 64 insertions, 16 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 75f6cd405a..9b545bca0a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -645,7 +645,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
}
static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
-void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
+BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
bool is_compressed = false;
@@ -810,19 +810,33 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llassert(prev_mip_data);
llassert(cur_mip_size == bytes*4);
#endif
- U8* new_data = new U8[bytes];
+ U8* new_data = new(std::nothrow) U8[bytes];
+ if (!new_data)
+ {
+ stop_glerror();
+
+ if (prev_mip_data)
+ delete[] prev_mip_data;
+ if (cur_mip_data)
+ delete[] cur_mip_data;
+
+ mGLTextureCreated = false;
+ return FALSE;
+ }
+ else
+ {
#ifdef SHOW_ASSERT
- llassert(prev_mip_data);
- llassert(cur_mip_size == bytes*4);
- llassert_always(new_data);
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes * 4);
#endif
- LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
- cur_mip_data = new_data;
+ LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
+ cur_mip_data = new_data;
#ifdef SHOW_ASSERT
- cur_mip_size = bytes;
+ cur_mip_size = bytes;
#endif
+ }
}
llassert(w > 0 && h > 0 && cur_mip_data);
@@ -909,6 +923,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
stop_glerror();
mGLTextureCreated = true;
+ return TRUE;
}
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
@@ -1378,8 +1393,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
{
// This will only be true if the size has not changed
- setImage(data_in, data_hasmips);
- return TRUE;
+ return setImage(data_in, data_hasmips);
}
U32 old_name = mTexName;
@@ -1421,7 +1435,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
mCurrentDiscardLevel = discard_level;
- setImage(data_in, data_hasmips);
+ if (!setImage(data_in, data_hasmips))
+ {
+ stop_glerror();
+ return FALSE;
+ }
// Set texture options to our defaults.
gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index bb0284a166..4f3d7eed0a 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -108,7 +108,7 @@ public:
S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
- void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
+ BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 5048799854..f10301b42d 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1057,10 +1057,12 @@ LLVertexBuffer::~LLVertexBuffer()
if (mFence)
{
+ // Sanity check. We have weird crashes in this destructor (on delete). Yet mFence is disabled.
+ // TODO: mFence was added in scope of SH-2038, but was never enabled, consider removing mFence.
+ LL_ERRS() << "LLVertexBuffer destruction failed" << LL_ENDL;
delete mFence;
+ mFence = NULL;
}
-
- mFence = NULL;
sVertexCount -= mNumVerts;
sIndexCount -= mNumIndices;
@@ -1930,7 +1932,21 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
+ if (mSize >= length + offset)
+ {
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*)mMappedData + offset);
+ }
+ else
+ {
+ GLint size = 0;
+ glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
+ << "mapped size: " << mSize
+ << ", gl buffer size: " << size
+ << ", length: " << length
+ << ", offset: " << offset
+ << LL_ENDL;
+ }
stop_glerror();
}
@@ -1998,7 +2014,21 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
+ if (mIndicesSize >= length + offset)
+ {
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
+ }
+ else
+ {
+ GLint size = 0;
+ glGetBufferParameterivARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
+ << "mapped size: " << mIndicesSize
+ << ", gl buffer size: " << size
+ << ", length: " << length
+ << ", offset: " << offset
+ << LL_ENDL;
+ }
stop_glerror();
}