summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2012-04-02 19:05:32 -0700
committerMerov Linden <merov@lindenlab.com>2012-04-02 19:05:32 -0700
commitdf09fd8e8b5b73330e4942c2cb218a216d7aca99 (patch)
tree7b945cde73ff1cc666c1f2b03d522452d2102eea /indra/llimage
parent792943c211f90738e245b11e128525190ff1b107 (diff)
SH-3060 : Preliminary implementation of the new byte range computation, implement setting to turn it on or off
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/llimage.cpp4
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llimage/llimagej2c.cpp47
3 files changed, 23 insertions, 33 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 937655a22d..7f95441075 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -48,11 +48,13 @@
//static
std::string LLImage::sLastErrorMessage;
LLMutex* LLImage::sMutex = NULL;
+bool LLImage::sUseNewByteRange = false;
LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
//static
-void LLImage::initClass()
+void LLImage::initClass(bool use_new_byte_range)
{
+ sUseNewByteRange = use_new_byte_range;
sMutex = new LLMutex(NULL);
LLImageBase::createPrivatePool() ;
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index eba8362f1c..b757547ab8 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -89,15 +89,18 @@ typedef enum e_image_codec
class LLImage
{
public:
- static void initClass();
+ static void initClass(bool use_new_byte_range = false);
static void cleanupClass();
static const std::string& getLastError();
static void setLastError(const std::string& message);
+ static bool useNewByteRange() { return sUseNewByteRange; }
+
protected:
static LLMutex* sMutex;
static std::string sLastErrorMessage;
+ static bool sUseNewByteRange;
};
//============================================================================
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index fbf4b769e1..cbb6f75b43 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -262,10 +262,12 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
//static
S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)
{
- // Note: this only provides an *estimate* of the size in bytes of an image level
- // *TODO: find a way to read the true size (when available) and convey the fact
- // that the result is an estimate in the other cases
- if (rate <= 0.f) rate = .125f;
+ // Note: This provides an estimation for the first quality layer of a given discard level
+ // This is however an efficient approximation, as the true discard level boundary would be
+ // in general too big for fast fetching.
+ // For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study
+ if (rate <= 0.f) rate = 1.f/8.f;
+ // Compute w/pow(2,discard_level) and h/pow(2,discard_level)
while (discard_level > 0)
{
if (w < 1 || h < 1)
@@ -274,7 +276,13 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
h >>= 1;
discard_level--;
}
- S32 bytes = (S32)((F32)(w*h*comp)*rate);
+ // Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange
+ // *TODO: Take the old code out once we have enough tests done
+ // *TODO: Replace the magic "7" by the number of quality layers in the j2c image
+ S32 bytes;
+ S32 new_bytes = sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/7.f;
+ S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
+ bytes = (LLImage::useNewByteRange() ? new_bytes : old_bytes);
bytes = llmax(bytes, calcHeaderSizeJ2C());
return bytes;
}
@@ -284,11 +292,7 @@ S32 LLImageJ2C::calcHeaderSize()
return calcHeaderSizeJ2C();
}
-
-// calcDataSize() returns how many bytes to read
-// to load discard_level (including header and higher discard levels)
-// *TODO: This is deeply wrong. That size should be taken from the image file header or other
-// relevant infos. In any case, this is only an approximation.
+// calcDataSize() returns how many bytes to read to load discard_level (including header)
S32 LLImageJ2C::calcDataSize(S32 discard_level)
{
discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL);
@@ -304,25 +308,6 @@ S32 LLImageJ2C::calcDataSize(S32 discard_level)
mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
level--;
}
-
- /* This is technically a more correct way to calculate the size required
- for each discard level, since they should include the size needed for
- lower levels. Unfortunately, this doesn't work well and will lead to
- download stalls. The true correct way is to parse the header. This will
- all go away with http textures at some point.
-
- // Calculate the size for each discard level. Lower levels (higher quality)
- // contain the cumulative size of higher levels
- S32 total_size = calcHeaderSizeJ2C();
-
- S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard
- while ( level >= 0 )
- { // Add in this discard level and all before it
- total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate);
- mDataSizes[level] = total_size;
- level--;
- }
- */
}
return mDataSizes[discard_level];
}
@@ -337,8 +322,8 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
}
while (1)
{
- S32 bytes_needed = calcDataSize(discard_level); // virtual
- if (bytes >= bytes_needed - (bytes_needed>>2)) // For J2c, up the res at 75% of the optimal number of bytes
+ S32 bytes_needed = calcDataSize(discard_level);
+ if (bytes >= bytes_needed)
{
break;
}