diff options
| author | Jonathan "Geenz" Goodman <geenz@lindenlab.com> | 2026-05-22 13:13:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-22 13:13:30 -0400 |
| commit | 6b4e3f3288ec1e9917cecd862a7a52945e5b4db2 (patch) | |
| tree | eb7f6952eaa5e78326308882db39500a4f149271 /indra/llkdu | |
| parent | 99ab6316b4ae9058f22d9f57d21e795ca45797fd (diff) | |
| parent | dad44ba5d67d04a73708a9a25bbe1ddec29a6a9a (diff) | |
Merge pull request #5829 from secondlife/geenz/texture-quality
Texture streaming rework
Diffstat (limited to 'indra/llkdu')
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.cpp | 30 | ||||
| -rw-r--r-- | indra/llkdu/llimagej2ckdu.h | 2 | ||||
| -rw-r--r-- | indra/llkdu/tests/llimagej2ckdu_test.cpp | 2 |
3 files changed, 34 insertions, 0 deletions
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index e7ac6bdb31..4330b1e5b1 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1513,3 +1513,33 @@ void kdc_flow_control::process_components() } } } + +// Layer-factored byte estimator. Walks the resolution pyramid to count +// layers, weights by layer_factor, then picks between a sqrt-based "new" +// estimate and a raw-dimensions "old" estimate per TextureNewByteRange. +// Reference: https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study +S32 LLImageJ2CKDU::estimateDataSize(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate) const +{ + S32 width = (w > 0) ? w : 2048; + S32 height = (h > 0) ? h : 2048; + S32 nb_layers = 1; + S32 surface = width * height; + S32 s = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; + while (surface > s) + { + nb_layers++; + s *= 4; + } + F32 layer_factor = 3.0f * (7 - llclamp(nb_layers, 1, 6)); + + width >>= discard_level; + height >>= discard_level; + width = llmax(width, 1); + height = llmax(height, 1); + + S32 new_bytes = (S32)(sqrtf((F32)(width * height)) * (F32)comp * rate * 1000.f / layer_factor); + S32 old_bytes = (S32)((F32)(width * height * comp) * rate); + S32 bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes)) ? new_bytes : old_bytes; + bytes = llmax(bytes, LLImageJ2C::calcHeaderSizeJ2C()); + return bytes; +} diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index c9aa0c5250..6079585948 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -67,6 +67,8 @@ protected: virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0); virtual std::string getEngineInfo() const; +public: + virtual S32 estimateDataSize(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate) const; private: bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL); diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index bc52a15c4a..6be2d3a078 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -83,6 +83,8 @@ void LLImageBase::setSize(S32 , S32 , S32 ) { } bool LLImageBase::isBufferInvalid() const { return false; } LLImageJ2CImpl::~LLImageJ2CImpl() { } +bool LLImage::sUseNewByteRange = false; +S32 LLImageJ2C::calcHeaderSizeJ2C() { return 0; } LLImageFormatted::LLImageFormatted(S8 ) { } LLImageFormatted::~LLImageFormatted() { } |
