diff options
Diffstat (limited to 'indra/llappearance/lltexlayer.cpp')
| -rw-r--r-- | indra/llappearance/lltexlayer.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index bcb00e6afd..7b5ff21bc4 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -435,6 +435,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const return mInfo->mBodyRegion; } +// virtual +void LLTexLayerSet::asLLSD(LLSD& sd) const +{ + sd["visible"] = LLSD::Boolean(isVisible()); + LLSD layer_list_sd; + layer_list_t::const_iterator layer_iter = mLayerList.begin(); + layer_list_t::const_iterator layer_end = mLayerList.end(); + for(; layer_iter != layer_end; ++layer_iter) + { + LLSD layer_sd; + LLTexLayerInterface* layer = (*layer_iter); + if (layer) + { + layer->asLLSD(layer_sd); + } + layer_list_sd.append(layer_sd); + } + LLSD mask_list_sd; + LLSD info_sd; + sd["layers"] = layer_list_sd; + sd["masks"] = mask_list_sd; + sd["info"] = info_sd; +} + + void LLTexLayerSet::destroyComposite() { if( mComposite ) @@ -1405,6 +1430,15 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // We should only be doing this when we believe something has changed with respect to the user's appearance. { LL_DEBUGS("Morph") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL; + + // Replace the cached mask without leaking its old allocation. + alpha_cache_t::iterator cached = mAlphaCache.find(cache_index); + if (cached != mAlphaCache.end()) + { + ll_aligned_free_32(cached->second); + mAlphaCache.erase(cached); + } + // clear out a slot if we have filled our cache S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1; while ((S32)mAlphaCache.size() >= max_cache_entries) @@ -1424,6 +1458,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC size_t mem_size = pixels * bytes_per_pixel; alpha_data = (U8*)ll_aligned_malloc_32(mem_size); + if (!alpha_data) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate memory for morph texture: " << (S32)(mem_size) << LL_ENDL; + return; + } bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels @@ -1433,6 +1473,13 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC { // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO // returning only the alpha portion without locking up downstream U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA + if (!temp) + { + ll_aligned_free_32(alpha_data); + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate temporary memory for morph texture readback: " << (S32)(mem_size << 2) << LL_ENDL; + return; + } if (bound_target) { @@ -1471,6 +1518,13 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // We just want GL_ALPHA, but that isn't supported in OGL core profile 4. static const size_t TEMP_BYTES_PER_PIXEL = 4; U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL); + if (!temp_data) + { + ll_aligned_free_32(alpha_data); + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Failed to allocate temporary memory for morph texture: " << (S32)(mem_size * TEMP_BYTES_PER_PIXEL) << LL_ENDL; + return; + } glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data); for (size_t pixel = 0; pixel < pixels; pixel++) { alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3]; |
