summaryrefslogtreecommitdiff
path: root/indra/newview/lltexturecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltexturecache.cpp')
-rw-r--r--indra/newview/lltexturecache.cpp72
1 files changed, 69 insertions, 3 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 2a0d961952..633e025478 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -615,7 +615,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
if(idx >= 0)
{
// write to the fast cache.
- if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
+ if(!mCache->writeToFastCache(mID, idx, mRawImage, mRawDiscardLevel))
{
LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
mDataSize = -1; // failed
@@ -1998,8 +1998,48 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
return raw;
}
+#if LL_WINDOWS
+
+static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+
+U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
+{
+ if (code == STATUS_MSC_EXCEPTION)
+ {
+ // C++ exception, go on
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ else
+ {
+ // handle it
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+}
+
+//due to unwinding
+void dupe(LLPointer<LLImageRaw> &raw)
+{
+ raw = raw->duplicate();
+}
+
+void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
+{
+ __try
+ {
+ dupe(raw);
+ }
+ __except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
+ {
+ // convert to C++ styled exception
+ char integer_string[32];
+ sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
+ throw std::exception(integer_string);
+ }
+}
+#endif
+
//return the fast cache location
-bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
+bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
//rescale image if needed
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
@@ -2027,13 +2067,39 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
if(w * h *c > 0) //valid
{
//make a duplicate to keep the original raw image untouched.
- raw = raw->scaled(w, h);
+
+ try
+ {
+#if LL_WINDOWS
+ // Temporary diagnostics for scale/duplicate crash
+ logExceptionDupplicate(raw);
+#else
+ raw = raw->duplicate();
+#endif
+ }
+ catch (...)
+ {
+ removeFromCache(image_id);
+ LL_ERRS() << "Failed to cache image: " << image_id
+ << " local id: " << id
+ << " Exception: " << boost::current_exception_diagnostic_information()
+ << " Image new width: " << w
+ << " Image new height: " << h
+ << " Image new components: " << c
+ << " Image discard difference: " << i
+ << LL_ENDL;
+
+ return false;
+ }
+
if (raw->isBufferInvalid())
{
LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL;
return false;
}
+ raw->scale(w, h);
+
discardlevel += i ;
}
}