Skip to content

fix for alpha-gamma-bypass prototype #2538

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
539 changes: 227 additions & 312 deletions indra/llprimitive/llprimitive.cpp

Large diffs are not rendered by default.

63 changes: 40 additions & 23 deletions indra/llprimitive/llprimitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,28 +399,42 @@ class LLRenderMaterialParams : public LLNetworkData
// more obvious. This should be refactored to remove the duplication, at which
// point we can fix the names as well.
// - Vir
struct LLTEContents
class LLTEContents
{
static const U32 MAX_TES = 45;

LLUUID image_data[MAX_TES];
LLColor4U colors[MAX_TES];
F32 scale_s[MAX_TES];
F32 scale_t[MAX_TES];
S16 offset_s[MAX_TES];
S16 offset_t[MAX_TES];
S16 image_rot[MAX_TES];
U8 bump[MAX_TES];
U8 alpha_gamma[MAX_TES];
U8 media_flags[MAX_TES];
U8 glow[MAX_TES];
LLMaterialID material_ids[MAX_TES];

static const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];

U32 size;
U32 face_count;
public:
static const size_t MAX_TES = 45;
static const size_t MAX_TE_BUFFER = 4096;

// delete the default ctor
LLTEContents() = delete;

// please use ctor which expects the number of textures as argument
LLTEContents(size_t N);

~LLTEContents();

U8 getNumTEs() const { return (U8)(num_textures); }

private:
U8* data; // one big chunk of data
size_t num_textures;

public:
// re-cast offsets into data
LLUUID* image_ids;
LLMaterialID* material_ids;
LLColor4U* colors;
F32* scale_s;
F32* scale_t;
S16* offset_s;
S16* offset_t;
S16* rot;
U8* bump;
U8* media_flags;
U8* glow;
U8* alpha_gamma;
// Note: we keep larger elements near the front so they are always 16-byte aligned,
// even for odd num_textures, and byte-sized elements to the back.
};

class LLPrimitive : public LLXform
Expand Down Expand Up @@ -498,12 +512,15 @@ class LLPrimitive : public LLXform

void copyTEs(const LLPrimitive *primitive);
S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const;

S32 packTEMessageBuffer(U8* packed_buffer) const;
bool packTEMessage(LLMessageSystem *mesgsys) const;
bool packTEMessage(LLDataPacker &dp) const;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packTEMessage() that expected an LLDataPacker& argument has been removed: it was never called anywhere.


S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
S32 unpackTEMessage(LLDataPacker &dp);
S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
S32 applyParsedTEMessage(LLTEContents& tec);
static S32 parseTEMessage(U8* packed_buffer, U32 data_size, LLTEContents& tec);
S32 applyParsedTEMessage(const LLTEContents& tec);

#ifdef CHECK_FOR_FINITE
inline void setPosition(const LLVector3& pos);
Expand Down
2 changes: 1 addition & 1 deletion indra/llprimitive/llprimtexturelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry& te)
return TEM_CHANGE_NONE;
}

// we're changing an existing entry
// we're changing an existing entry
llassert(mEntryList[index]);
delete (mEntryList[index]);
if (&te)
Expand Down
2 changes: 1 addition & 1 deletion indra/llprimitive/lltextureentry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)

void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 offset_s, F32 offset_t, F32 rotation, U8 bump, U8 alphagamma)
{
setID(tex_id);
mID = tex_id;

mScaleS = scale_s;
mScaleT = scale_t;
Expand Down
207 changes: 168 additions & 39 deletions indra/llprimitive/tests/llprimitive_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@

#include "../../llmath/llvolumemgr.h"

#include "../llmaterialid.cpp"
#include "lltextureentry_stub.cpp"
#include "llprimtexturelist_stub.cpp"

class DummyVolumeMgr : public LLVolumeMgr
{
public:
Expand Down Expand Up @@ -71,45 +75,6 @@ class DummyVolumeMgr : public LLVolumeMgr
S32 mCurrDetailTest;
};

LLMaterialID::LLMaterialID() {}
LLMaterialID::LLMaterialID(LLMaterialID const &m) = default;
LLMaterialID::~LLMaterialID() {}
void LLMaterialID::set(void const*) { }
U8 const * LLMaterialID::get() const { return mID; }

LLPrimTextureList::LLPrimTextureList() { }
LLPrimTextureList::~LLPrimTextureList() { }
S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry &te) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setFullbright(const U8 index, const U8 t) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; }
S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen) { return TEM_CHANGE_NONE; }

LLMaterialPtr LLPrimTextureList::getMaterialParams(const U8 index) { return LLMaterialPtr(); }
void LLPrimTextureList::copy(LLPrimTextureList const & ptl) { mEntryList = ptl.mEntryList; } // do we need to call getTexture()->newCopy()?
void LLPrimTextureList::take(LLPrimTextureList &other_list) { }
void LLPrimTextureList::setSize(S32 new_size) { mEntryList.resize(new_size); }
void LLPrimTextureList::setAllIDs(const LLUUID &id) { }
LLTextureEntry * LLPrimTextureList::getTexture(const U8 index) const { return nullptr; }
S32 LLPrimTextureList::size() const { return static_cast<S32>(mEntryList.size()); }

class PRIMITIVE_TEST_SETUP
{
Expand Down Expand Up @@ -266,6 +231,170 @@ namespace tut
// Ensure that we now have a different volume
ensure(new_volume != primitive.getVolume());
}

template<> template<>
void llprimitive_object_t::test<7>()
{
set_test_name("Test LLPrimitive pack/unpackTEMessageBuffer().");

// init some values
LLUUID image_id;
LLUUID material_uuid;
LLColor4 color(0.0f, 0.0f, 0.0f, 0.0f);
F32 scale_s = 1.0;
F32 scale_t = 1.0;
S16 offset_s = 0;
S16 offset_t = 0;
S16 rot = 0;
U8 bump = 0;
U8 media_flags = 0;
U8 glow = 0;
U8 alpha_gamma = 31;

// init some deltas
LLColor4 d_color(0.05f, 0.07f, 0.11f, 0.13f);
F32 d_scale_s = 0.1f;
F32 d_scale_t = 0.3f;
S16 d_offset_s = 5;
S16 d_offset_t = 7;
S16 d_rot = 11;
U8 d_bump = 3;
U8 d_media_flags = 5;
U8 d_glow = 7;
U8 d_alpha_gamma = 11;

// prep the containers
U8 num_textures = 5;
LLPrimitive primitive_A;
primitive_A.setNumTEs(num_textures);
LLTextureEntry texture_entry;
LLTEContents contents_A(num_textures);
LLTEContents contents_B(num_textures);

// fill contents_A and primitive_A
for (U8 i = 0; i < num_textures; ++i)
{
// generate fake texture data
image_id.generate();
material_uuid.generate();
color += d_color;
scale_s += d_scale_s;
scale_t -= d_scale_t;
offset_s += d_offset_s;
offset_t -= d_offset_t;
rot += d_rot;
bump += d_bump;
media_flags += d_media_flags;
glow += d_glow;
alpha_gamma += d_alpha_gamma;

// store the fake texture data in contents
contents_A.image_ids[i] = image_id;

LLMaterialID material_id;
material_id.set(material_uuid.mData);
contents_A.material_ids[i] = material_id;

contents_A.colors[i].setVecScaleClamp(color);

contents_A.scale_s[i] = scale_s;
contents_A.scale_t[i] = scale_t;
contents_A.offset_s[i] = offset_s;
contents_A.offset_t[i] = offset_t;
contents_A.rot[i] = rot;
contents_A.bump[i] = bump;
contents_A.glow[i] = glow;
contents_A.media_flags[i] = media_flags & TEM_MEDIA_MASK;
contents_A.alpha_gamma[i] = alpha_gamma;

// store the fake texture data in texture_entry
F32 f_offset_s = (F32)offset_s / (F32)0x7FFF;
F32 f_offset_t = (F32)offset_t / (F32)0x7FFF;

// Texture rotations are sent over the wire as a S16. This is used to scale the actual float
// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it
// can't be divided by 2. See DEV-19108
constexpr F32 TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000);
F32 f_rotation = ((F32)rot / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI;

F32 f_glow = (F32)glow / (F32)0xFF;

texture_entry.init(image_id, scale_s, scale_t, f_offset_s, f_offset_t, f_rotation, bump, alpha_gamma);
texture_entry.setMaterialID(material_id);
texture_entry.setColor(color);
texture_entry.setMediaFlags(media_flags);
texture_entry.setGlow(f_glow);
texture_entry.setAlphaGamma(alpha_gamma);

// store texture_entry in primitive_A
primitive_A.setTE(i, texture_entry);
}

// pack buffer from primitive_A
constexpr size_t MAX_TE_BUFFER = 4096;
U8 buffer[MAX_TE_BUFFER];
S32 num_bytes = primitive_A.packTEMessageBuffer(buffer);
ensure_not_equals(num_bytes, 0);

// unpack buffer into contents_B
// but first manually null-terminate the buffer as required by LLPrimitive::parseTEMessage()
// because last TEField is not null-terminated in the message,
// but it needs to be null-terminated for unpacking
buffer[num_bytes] = 0;
++num_bytes;
bool success = LLPrimitive::parseTEMessage(buffer, num_bytes, contents_B);
ensure(success);

// compare contents
for (U8 i = 0; i < num_textures; ++i)
{
ensure_equals(contents_A.image_ids[i], contents_B.image_ids[i]);
ensure_equals(contents_A.material_ids[i], contents_B.material_ids[i]);
ensure_equals(contents_A.colors[i], contents_B.colors[i]);
ensure_equals(contents_A.scale_s[i], contents_B.scale_s[i]);
ensure_equals(contents_A.scale_t[i], contents_B.scale_t[i]);
ensure_equals(contents_A.offset_s[i], contents_B.offset_s[i]);
ensure_equals(contents_A.offset_t[i], contents_B.offset_t[i]);
ensure_equals(contents_A.rot[i], contents_B.rot[i]);
ensure_equals(contents_A.bump[i], contents_B.bump[i]);
ensure_equals(contents_A.media_flags[i], contents_B.media_flags[i]);
ensure_equals(contents_A.glow[i], contents_B.glow[i]);
ensure_equals(contents_A.alpha_gamma[i], contents_B.alpha_gamma[i]);
}

// create primitive_B
LLPrimitive primitive_B;
primitive_B.setNumTEs(num_textures);

// apply contents_B
primitive_B.applyParsedTEMessage(contents_B);

// compare primitives
for (U8 i = 0; i < num_textures; ++i)
{
LLTextureEntry* te_A = primitive_A.getTE(i);
LLTextureEntry* te_B = primitive_B.getTE(i);

ensure_equals(te_A->getID(), te_B->getID());
ensure_equals(te_A->getMaterialID(), te_B->getMaterialID());

// color can experience quantization error after pack/unpack, so we check for proximity
ensure(distVec(te_A->getColor(), te_B->getColor()) < 0.005f);

// Note: ;scale, offset, and rotation can also experience a little quantization error
// however it happens to be zero for the values we use in this test
ensure_equals(te_A->getScaleS(), te_B->getScaleS());
ensure_equals(te_A->getScaleT(), te_B->getScaleT());
ensure_equals(te_A->getOffsetS(), te_B->getOffsetS());
ensure_equals(te_A->getOffsetT(), te_B->getOffsetT());
ensure_equals(te_A->getRotation(), te_B->getRotation());

ensure_equals(te_A->getBumpShinyFullbright(), te_B->getBumpShinyFullbright());
ensure_equals(te_A->getMediaFlags(), te_B->getMediaFlags());
ensure_equals(te_A->getGlow(), te_B->getGlow());
ensure_equals(te_A->getAlphaGamma(), te_B->getAlphaGamma());
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding this unit-test for the TextureEntry pack/unpack logic.

}

#include "llmessagesystem_stub.cpp"
Loading
Loading