diff options
author | Brad Linden <46733234+brad-linden@users.noreply.github.com> | 2024-05-06 15:44:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-06 15:44:19 -0700 |
commit | 84827a7cb8d4b7a58309f98c7d4df4cfeb173935 (patch) | |
tree | b91494298eab93bbd8dd9b00722b7a30714a1b9c /indra/llimage/llimage.cpp | |
parent | 76101843c0d390c25a783f212eb1ea75e508ada4 (diff) | |
parent | 8b747cee182cd8e95063fa152d9b5d7383cb1c74 (diff) |
Merge pull request #1413 from secondlife/gltf-dev-maint-a-merge
Merge Maint A to development
Diffstat (limited to 'indra/llimage/llimage.cpp')
-rw-r--r-- | indra/llimage/llimage.cpp | 134 |
1 files changed, 108 insertions, 26 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index ed8f36286f..625dcf7410 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -615,7 +615,6 @@ const std::string& LLImage::getLastError() //static void LLImage::setLastError(const std::string& message) { - LLMutexLock m(sMutex); sLastErrorMessage = message; } @@ -755,7 +754,7 @@ U8* LLImageBase::reallocateData(S32 size) return mData; } -const U8* LLImageBase::getData() const +const U8* LLImageBase::getData() const { if(mBadBufferAllocation) { @@ -766,7 +765,7 @@ const U8* LLImageBase::getData() const return mData; } // read only -U8* LLImageBase::getData() +U8* LLImageBase::getData() { if(mBadBufferAllocation) { @@ -779,7 +778,7 @@ U8* LLImageBase::getData() bool LLImageBase::isBufferInvalid() const { - return mBadBufferAllocation || mData == NULL ; + return mBadBufferAllocation || mData == NULL; } void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents) @@ -855,6 +854,8 @@ LLImageRaw::~LLImageRaw() // virtual U8* LLImageRaw::allocateData(S32 size) { + LLImageDataLock lock(this); + U8* res = LLImageBase::allocateData(size); return res; } @@ -862,12 +863,16 @@ U8* LLImageRaw::allocateData(S32 size) // virtual U8* LLImageRaw::reallocateData(S32 size) { + LLImageDataLock lock(this); + U8* res = LLImageBase::reallocateData(size); return res; } void LLImageRaw::releaseData() { + LLImageDataLock lock(this); + LLImageBase::setSize(0, 0, 0); LLImageBase::setDataAndSize(nullptr, 0); } @@ -875,11 +880,15 @@ void LLImageRaw::releaseData() // virtual void LLImageRaw::deleteData() { + LLImageDataLock lock(this); + LLImageBase::deleteData(); } void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) -{ +{ + LLImageDataLock lock(this); + if(data == getData()) { return ; @@ -893,6 +902,8 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components) bool LLImageRaw::resize(U16 width, U16 height, S8 components) { + LLImageDataLock lock(this); + if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components) && !isBufferInvalid()) { return true; @@ -908,6 +919,8 @@ bool LLImageRaw::resize(U16 width, U16 height, S8 components) bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, const U8 *data, U32 stride, bool reverse_y) { + LLImageDataLock lock(this); + if (!getData()) { return false; @@ -935,6 +948,9 @@ bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height, void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a) { llassert( getComponents() <= 4 ); + + LLImageDataLock lock(this); + // This is fairly bogus, but it'll do for now. if (isBufferInvalid()) { @@ -975,6 +991,8 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a) // Reverses the order of the rows in the image void LLImageRaw::verticalFlip() { + LLImageDataLock lock(this); + S32 row_bytes = getWidth() * getComponents(); llassert(row_bytes > 0); std::vector<U8> line_buffer(row_bytes); @@ -1014,6 +1032,8 @@ bool LLImageRaw::checkHasTransparentPixels() bool LLImageRaw::optimizeAwayAlpha() { + LLImageDataLock lock(this); + if (getComponents() == 4) { U8* data = getData(); @@ -1079,6 +1099,8 @@ bool LLImageRaw::makeAlpha() void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) { + LLImageDataLock lock(this); + // Find new sizes S32 new_width = expandDimToPowerOfTwo(getWidth(), max_dim); S32 new_height = expandDimToPowerOfTwo(getHeight(), max_dim); @@ -1088,6 +1110,8 @@ void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image) void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image) { + LLImageDataLock lock(this); + // Find new sizes S32 new_width = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE); S32 new_height = contractDimToPowerOfTwo(getHeight(), MIN_IMAGE_SIZE); @@ -1137,6 +1161,8 @@ S32 LLImageRaw::contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim) void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim) { + LLImageDataLock lock(this); + // Find new sizes S32 new_width = biasedDimToPowerOfTwo(getWidth(),max_dim); S32 new_height = biasedDimToPowerOfTwo(getHeight(),max_dim); @@ -1144,6 +1170,7 @@ void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim) scale( new_width, new_height ); } +// static // Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f). Thanks, Jim Blinn! inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b ) { @@ -1152,10 +1179,13 @@ inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b ) } -void LLImageRaw::composite( LLImageRaw* src ) +void LLImageRaw::composite( const LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(this); + if (!validateSrcAndDst("LLImageRaw::composite", src, dst)) { return; @@ -1194,12 +1224,14 @@ void LLImageRaw::composite( LLImageRaw* src ) // Src and dst can be any size. Src has 4 components. Dst has 3 components. -void LLImageRaw::compositeScaled4onto3(LLImageRaw* src) +void LLImageRaw::compositeScaled4onto3(const LLImageRaw* src) { LL_INFOS() << "compositeScaled4onto3" << LL_ENDL; LLImageRaw* dst = this; // Just for clarity. + LLImageDataLock lock(this); + llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); @@ -1221,14 +1253,16 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src) // Src and dst are same size. Src has 4 components. Dst has 3 components. -void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) +void LLImageRaw::compositeUnscaled4onto3( const LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataLock lock(this); + llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - U8* src_data = src->getData(); + const U8* src_data = src->getData(); U8* dst_data = dst->getData(); S32 pixels = getWidth() * getHeight(); while( pixels-- ) @@ -1258,10 +1292,13 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) } -void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) +void LLImageRaw::copyUnscaledAlphaMask( const LLImageRaw* src, const LLColor4U& fill) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(this); + if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) { return; @@ -1272,7 +1309,7 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); + const U8* src_data = src->getData(); U8* dst_data = dst->getData(); for ( S32 i = 0; i < pixels; i++ ) { @@ -1289,6 +1326,8 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) // Fill the buffer with a constant color void LLImageRaw::fill( const LLColor4U& color ) { + LLImageDataLock lock(this); + if (isBufferInvalid()) { LL_WARNS() << "Invalid image buffer" << LL_ENDL; @@ -1350,16 +1389,21 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate() return this; //nobody else refences to this image, no need to duplicate. } + LLImageDataSharedLock lock(this); + //make a duplicate LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents()); return dup; } // Src and dst can be any size. Src and dst can each have 3 or 4 components. -void LLImageRaw::copy(LLImageRaw* src) +void LLImageRaw::copy(const LLImageRaw* src) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(this); + if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) { return; @@ -1405,10 +1449,12 @@ void LLImageRaw::copy(LLImageRaw* src) } // Src and dst are same size. Src and dst have same number of components. -void LLImageRaw::copyUnscaled(LLImageRaw* src) +void LLImageRaw::copyUnscaled(const LLImageRaw* src) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataLock lock(this); + llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert( src->getComponents() == dst->getComponents() ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); @@ -1418,7 +1464,7 @@ void LLImageRaw::copyUnscaled(LLImageRaw* src) // Src and dst can be any size. Src has 3 components. Dst has 4 components. -void LLImageRaw::copyScaled3onto4(LLImageRaw* src) +void LLImageRaw::copyScaled3onto4(const LLImageRaw* src) { llassert( (3 == src->getComponents()) && (4 == getComponents()) ); @@ -1430,7 +1476,7 @@ void LLImageRaw::copyScaled3onto4(LLImageRaw* src) // Src and dst can be any size. Src has 4 components. Dst has 3 components. -void LLImageRaw::copyScaled4onto3(LLImageRaw* src) +void LLImageRaw::copyScaled4onto3(const LLImageRaw* src) { llassert( (4 == src->getComponents()) && (3 == getComponents()) ); @@ -1442,15 +1488,17 @@ void LLImageRaw::copyScaled4onto3(LLImageRaw* src) // Src and dst are same size. Src has 4 components. Dst has 3 components. -void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src ) +void LLImageRaw::copyUnscaled4onto3( const LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataLock lock(this); + llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); + const U8* src_data = src->getData(); U8* dst_data = dst->getData(); for( S32 i=0; i<pixels; i++ ) { @@ -1464,15 +1512,18 @@ void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src ) // Src and dst are same size. Src has 3 components. Dst has 4 components. -void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src ) +void LLImageRaw::copyUnscaled3onto4( const LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + + LLImageDataLock lock(this); + llassert( 3 == src->getComponents() ); llassert( 4 == dst->getComponents() ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); S32 pixels = getWidth() * getHeight(); - U8* src_data = src->getData(); + const U8* src_data = src->getData(); U8* dst_data = dst->getData(); for( S32 i=0; i<pixels; i++ ) { @@ -1487,10 +1538,13 @@ void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src ) // Src and dst can be any size. Src and dst have same number of components. -void LLImageRaw::copyScaled( LLImageRaw* src ) +void LLImageRaw::copyScaled( const LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(this); + if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst)) { return; @@ -1532,6 +1586,8 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) { + LLImageDataLock lock(this); + S32 components = getComponents(); if (components != 1 && components != 3 && components != 4) { @@ -1618,6 +1674,8 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height) { LLPointer<LLImageRaw> result; + LLImageDataLock lock(this); + S32 components = getComponents(); if (components != 1 && components != 3 && components != 4) { @@ -1663,7 +1721,7 @@ LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height) return result; } -void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) +void LLImageRaw::copyLineScaled( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) { const S32 components = getComponents(); llassert( components >= 1 && components <= 4 ); @@ -1690,7 +1748,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe S32 t0 = x * out_pixel_step * components; S32 t1 = index0 * in_pixel_step * components; U8* outp = out + t0; - U8* inp = in + t1; + const U8* inp = in + t1; for (S32 i = 0; i < components; ++i) { *outp = *inp; @@ -1778,7 +1836,7 @@ void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixe } } -void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ) +void LLImageRaw::compositeRowScaled4onto3( const U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len ) { llassert( getComponents() == 3 ); @@ -1940,9 +1998,12 @@ void LLImageRaw::addEmissiveScaled(LLImageRaw* src) dst->addEmissiveUnscaled(&temp); } - -bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst) +// static +bool LLImageRaw::validateSrcAndDst(std::string func, const LLImageRaw* src, const LLImageRaw* dst) { + LLImageDataSharedLock lockIn(src); + LLImageDataLock lockOut(dst); + if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid()) { LL_WARNS() << func << ": Source: "; @@ -2255,6 +2316,8 @@ bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32 decode_time, S3 // virtual U8* LLImageFormatted::allocateData(S32 size) { + LLImageDataLock lock(this); + U8* res = LLImageBase::allocateData(size); // calls deleteData() sGlobalFormattedMemory += getDataSize(); return res; @@ -2263,6 +2326,8 @@ U8* LLImageFormatted::allocateData(S32 size) // virtual U8* LLImageFormatted::reallocateData(S32 size) { + LLImageDataLock lock(this); + sGlobalFormattedMemory -= getDataSize(); U8* res = LLImageBase::reallocateData(size); sGlobalFormattedMemory += getDataSize(); @@ -2272,6 +2337,12 @@ U8* LLImageFormatted::reallocateData(S32 size) // virtual void LLImageFormatted::deleteData() { + LLImageDataLock lock(this); + + if (mDecoding) + { + LL_ERRS() << "LLImageFormatted::deleteData() is called during decoding" << LL_ENDL; + } sGlobalFormattedMemory -= getDataSize(); LLImageBase::deleteData(); } @@ -2297,6 +2368,8 @@ void LLImageFormatted::sanityCheck() bool LLImageFormatted::copyData(U8 *data, S32 size) { + LLImageDataLock lock(this); + if ( data && ((data != getData()) || (size != getDataSize())) ) { deleteData(); @@ -2309,6 +2382,8 @@ bool LLImageFormatted::copyData(U8 *data, S32 size) // LLImageFormatted becomes the owner of data void LLImageFormatted::setData(U8 *data, S32 size) { + LLImageDataLock lock(this); + if (data && data != getData()) { deleteData(); @@ -2322,6 +2397,8 @@ void LLImageFormatted::appendData(U8 *data, S32 size) { if (data) { + LLImageDataLock lock(this); + if (!getData()) { setData(data, size); @@ -2363,6 +2440,9 @@ bool LLImageFormatted::load(const std::string &filename, int load_size) { load_size = file_size; } + + LLImageDataLock lock(this); + bool res; U8 *data = allocateData(load_size); if (data) @@ -2400,7 +2480,9 @@ bool LLImageFormatted::save(const std::string &filename) setLastError("Unable to open file for writing", filename); return false; } - + + LLImageDataSharedLock lock(this); + S32 result = outfile.write(getData(), getDataSize()); outfile.close() ; return (result != 0); |