Merge branch 'develop' of https://github.com/secondlife/viewer
# Conflicts: # indra/llrender/llrender2dutils.cpp # indra/llui/llfolderviewitem.cppmaster
commit
3c6aab0812
|
|
@ -6,7 +6,7 @@ add_library( ll::tracy INTERFACE IMPORTED )
|
|||
|
||||
# default Tracy profiling on for test builds, but off for all others
|
||||
string(TOLOWER ${VIEWER_CHANNEL} channel_lower)
|
||||
if(WINDOWS AND channel_lower MATCHES "^second life test")
|
||||
if(channel_lower MATCHES "^second life test")
|
||||
option(USE_TRACY "Use Tracy profiler." ON)
|
||||
else()
|
||||
option(USE_TRACY "Use Tracy profiler." OFF)
|
||||
|
|
@ -30,6 +30,11 @@ if (USE_TRACY)
|
|||
target_compile_definitions(ll::tracy INTERFACE -DTRACY_NO_BROADCAST=1 -DTRACY_ONLY_LOCALHOST=1)
|
||||
endif ()
|
||||
|
||||
# GHA runners don't always provide invariant TSC support, but always build with LL_TESTS enabled
|
||||
if (DARWIN AND LL_TESTS)
|
||||
target_compile_definitions(ll::tracy INTERFACE -DTRACY_TIMER_FALLBACK=1)
|
||||
endif ()
|
||||
|
||||
# See: indra/llcommon/llprofiler.h
|
||||
add_compile_definitions(LL_PROFILER_CONFIGURATION=3)
|
||||
endif (USE_TRACY)
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,11 @@ bool LLGLManager::initGL()
|
|||
mGLVendorShort = "INTEL";
|
||||
mIsIntel = true;
|
||||
}
|
||||
else if (mGLVendor.find("APPLE") != std::string::npos)
|
||||
{
|
||||
mGLVendorShort = "APPLE";
|
||||
mIsApple = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mGLVendorShort = "MISC";
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public:
|
|||
bool mIsAMD;
|
||||
bool mIsNVIDIA;
|
||||
bool mIsIntel;
|
||||
bool mIsApple = false;
|
||||
|
||||
// hints to the render pipe
|
||||
U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -290,22 +290,58 @@ static GLuint gen_buffer()
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void delete_buffers(S32 count, GLuint* buffers)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
// wait a few frames before actually deleting the buffers to avoid
|
||||
// synchronization issues with the GPU
|
||||
static std::vector<GLuint> sFreeList[4];
|
||||
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
U32 idx = LLImageGL::sFrameCount % 4;
|
||||
|
||||
for (S32 i = 0; i < count; ++i)
|
||||
{
|
||||
sFreeList[idx].push_back(buffers[i]);
|
||||
}
|
||||
|
||||
idx = (LLImageGL::sFrameCount + 3) % 4;
|
||||
|
||||
if (!sFreeList[idx].empty())
|
||||
{
|
||||
glDeleteBuffers((GLsizei)sFreeList[idx].size(), sFreeList[idx].data());
|
||||
sFreeList[idx].resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ANALYZE_VBO_POOL 0
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
// experimental -- disable VBO pooling on OS X and use glMapBuffer
|
||||
// VBO Pool interface
|
||||
class LLVBOPool
|
||||
{
|
||||
public:
|
||||
virtual ~LLVBOPool() = default;
|
||||
virtual void allocate(GLenum type, U32 size, GLuint& name, U8*& data) = 0;
|
||||
virtual void free(GLenum type, U32 size, GLuint name, U8* data) = 0;
|
||||
virtual U64 getVramBytesUsed() = 0;
|
||||
};
|
||||
|
||||
// VBO Pool for Apple GPUs (as in M1/M2 etc, not Intel macs)
|
||||
// Effectively disables VBO pooling
|
||||
class LLAppleVBOPool final: public LLVBOPool
|
||||
{
|
||||
public:
|
||||
U64 mAllocated = 0;
|
||||
|
||||
U64 getVramBytesUsed()
|
||||
U64 getVramBytesUsed() override
|
||||
{
|
||||
return mAllocated;
|
||||
}
|
||||
|
||||
void allocate(GLenum type, U32 size, GLuint& name, U8*& data)
|
||||
void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
STOP_GLERROR;
|
||||
|
|
@ -325,7 +361,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void free(GLenum type, U32 size, GLuint name, U8* data)
|
||||
void free(GLenum type, U32 size, GLuint name, U8* data) override
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
|
@ -340,19 +376,17 @@ public:
|
|||
STOP_GLERROR;
|
||||
if (name)
|
||||
{
|
||||
glDeleteBuffers(1, &name);
|
||||
delete_buffers(1, &name);
|
||||
}
|
||||
STOP_GLERROR;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class LLVBOPool
|
||||
// VBO Pool for GPUs that benefit from VBO pooling
|
||||
class LLDefaultVBOPool final : public LLVBOPool
|
||||
{
|
||||
public:
|
||||
typedef std::chrono::steady_clock::time_point Time;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
U8* mData;
|
||||
|
|
@ -360,7 +394,7 @@ public:
|
|||
Time mAge;
|
||||
};
|
||||
|
||||
~LLVBOPool()
|
||||
~LLDefaultVBOPool() override
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
|
@ -378,7 +412,7 @@ public:
|
|||
U32 mMisses = 0;
|
||||
U32 mHits = 0;
|
||||
|
||||
U64 getVramBytesUsed()
|
||||
U64 getVramBytesUsed() override
|
||||
{
|
||||
return mAllocated + mReserved;
|
||||
}
|
||||
|
|
@ -394,7 +428,7 @@ public:
|
|||
size += block_size - (size % block_size);
|
||||
}
|
||||
|
||||
void allocate(GLenum type, U32 size, GLuint& name, U8*& data)
|
||||
void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
|
@ -450,7 +484,7 @@ public:
|
|||
clean();
|
||||
}
|
||||
|
||||
void free(GLenum type, U32 size, GLuint name, U8* data)
|
||||
void free(GLenum type, U32 size, GLuint name, U8* data) override
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
|
||||
|
|
@ -513,7 +547,7 @@ public:
|
|||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo cache timeout");
|
||||
auto& entry = entries.back();
|
||||
ll_aligned_free_16(entry.mData);
|
||||
glDeleteBuffers(1, &entry.mGLName);
|
||||
delete_buffers(1, &entry.mGLName);
|
||||
llassert(mReserved >= iter->first);
|
||||
mReserved -= iter->first;
|
||||
entries.pop_back();
|
||||
|
|
@ -549,7 +583,7 @@ public:
|
|||
for (auto& entry : entries.second)
|
||||
{
|
||||
ll_aligned_free_16(entry.mData);
|
||||
glDeleteBuffers(1, &entry.mGLName);
|
||||
delete_buffers(1, &entry.mGLName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +592,7 @@ public:
|
|||
for (auto& entry : entries.second)
|
||||
{
|
||||
ll_aligned_free_16(entry.mData);
|
||||
glDeleteBuffers(1, &entry.mGLName);
|
||||
delete_buffers(1, &entry.mGLName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -568,7 +602,6 @@ public:
|
|||
mVBOPool.clear();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static LLVBOPool* sVBOPool = nullptr;
|
||||
|
||||
|
|
@ -915,7 +948,16 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
|||
void LLVertexBuffer::initClass(LLWindow* window)
|
||||
{
|
||||
llassert(sVBOPool == nullptr);
|
||||
sVBOPool = new LLVBOPool();
|
||||
if (gGLManager.mIsApple)
|
||||
{
|
||||
LL_INFOS() << "VBO Pooling Disabled" << LL_ENDL;
|
||||
sVBOPool = new LLAppleVBOPool();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "VBO Pooling Enabled" << LL_ENDL;
|
||||
sVBOPool = new LLDefaultVBOPool();
|
||||
}
|
||||
|
||||
#if ENABLE_GL_WORK_QUEUE
|
||||
sQueue = new GLWorkQueue();
|
||||
|
|
@ -983,7 +1025,6 @@ void LLVertexBuffer::flushBuffers()
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
|
||||
// must only be called from main thread
|
||||
llassert(LLCoros::on_main_thread_main_coro());
|
||||
for (auto& buffer : sMappedBuffers)
|
||||
{
|
||||
buffer->_unmapBuffer();
|
||||
|
|
@ -1250,28 +1291,29 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
|
|||
count = mNumVerts - index;
|
||||
}
|
||||
|
||||
#if !LL_DARWIN
|
||||
U32 start = mOffsets[type] + sTypeSize[type] * index;
|
||||
U32 end = start + sTypeSize[type] * count-1;
|
||||
|
||||
bool flagged = false;
|
||||
// flag region as mapped
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
if (!gGLManager.mIsApple)
|
||||
{
|
||||
MappedRegion& region = mMappedVertexRegions[i];
|
||||
if (expand_region(region, start, end))
|
||||
U32 start = mOffsets[type] + sTypeSize[type] * index;
|
||||
U32 end = start + sTypeSize[type] * count-1;
|
||||
|
||||
bool flagged = false;
|
||||
// flag region as mapped
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
{
|
||||
flagged = true;
|
||||
break;
|
||||
MappedRegion& region = mMappedVertexRegions[i];
|
||||
if (expand_region(region, start, end))
|
||||
{
|
||||
flagged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flagged)
|
||||
{
|
||||
//didn't expand an existing region, make a new one
|
||||
mMappedVertexRegions.push_back({ start, end });
|
||||
}
|
||||
}
|
||||
|
||||
if (!flagged)
|
||||
{
|
||||
//didn't expand an existing region, make a new one
|
||||
mMappedVertexRegions.push_back({ start, end });
|
||||
}
|
||||
#endif
|
||||
return mMappedData+mOffsets[type]+sTypeSize[type]*index;
|
||||
}
|
||||
|
||||
|
|
@ -1286,29 +1328,30 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
|
|||
count = mNumIndices-index;
|
||||
}
|
||||
|
||||
#if !LL_DARWIN
|
||||
U32 start = sizeof(U16) * index;
|
||||
U32 end = start + sizeof(U16) * count-1;
|
||||
|
||||
bool flagged = false;
|
||||
// flag region as mapped
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
if (!gGLManager.mIsApple)
|
||||
{
|
||||
MappedRegion& region = mMappedIndexRegions[i];
|
||||
if (expand_region(region, start, end))
|
||||
U32 start = sizeof(U16) * index;
|
||||
U32 end = start + sizeof(U16) * count-1;
|
||||
|
||||
bool flagged = false;
|
||||
// flag region as mapped
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
{
|
||||
flagged = true;
|
||||
break;
|
||||
MappedRegion& region = mMappedIndexRegions[i];
|
||||
if (expand_region(region, start, end))
|
||||
{
|
||||
flagged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flagged)
|
||||
{
|
||||
//didn't expand an existing region, make a new one
|
||||
mMappedIndexRegions.push_back({ start, end });
|
||||
}
|
||||
}
|
||||
|
||||
if (!flagged)
|
||||
{
|
||||
//didn't expand an existing region, make a new one
|
||||
mMappedIndexRegions.push_back({ start, end });
|
||||
}
|
||||
#endif
|
||||
|
||||
return mMappedIndexData + sizeof(U16)*index;
|
||||
}
|
||||
|
||||
|
|
@ -1320,37 +1363,40 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
|
|||
// dst -- mMappedData or mMappedIndexData
|
||||
void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst)
|
||||
{
|
||||
#if LL_DARWIN
|
||||
// on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call
|
||||
// _mapBuffer to tag the buffer for flushing to GL
|
||||
_mapBuffer();
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy");
|
||||
STOP_GLERROR;
|
||||
// copy into mapped buffer
|
||||
memcpy(dst+start, data, end-start+1);
|
||||
#else
|
||||
llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices);
|
||||
|
||||
// skip mapped data and stream to GPU via glBufferSubData
|
||||
if (end != 0)
|
||||
if (gGLManager.mIsApple)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData");
|
||||
LL_PROFILE_ZONE_NUM(start);
|
||||
LL_PROFILE_ZONE_NUM(end);
|
||||
LL_PROFILE_ZONE_NUM(end-start);
|
||||
// on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call
|
||||
// _mapBuffer to tag the buffer for flushing to GL
|
||||
_mapBuffer();
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy");
|
||||
STOP_GLERROR;
|
||||
// copy into mapped buffer
|
||||
memcpy(dst+start, data, end-start+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices);
|
||||
|
||||
constexpr U32 block_size = 65536;
|
||||
|
||||
for (U32 i = start; i <= end; i += block_size)
|
||||
// skip mapped data and stream to GPU via glBufferSubData
|
||||
if (end != 0)
|
||||
{
|
||||
//LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block");
|
||||
//LL_PROFILE_GPU_ZONE("glBufferSubData");
|
||||
U32 tend = llmin(i + block_size, end);
|
||||
U32 size = tend - i + 1;
|
||||
glBufferSubData(target, i, size, (U8*) data + (i-start));
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData");
|
||||
LL_PROFILE_ZONE_NUM(start);
|
||||
LL_PROFILE_ZONE_NUM(end);
|
||||
LL_PROFILE_ZONE_NUM(end-start);
|
||||
|
||||
constexpr U32 block_size = 65536;
|
||||
|
||||
for (U32 i = start; i <= end; i += block_size)
|
||||
{
|
||||
//LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block");
|
||||
//LL_PROFILE_GPU_ZONE("glBufferSubData");
|
||||
U32 tend = llmin(i + block_size, end);
|
||||
U32 size = tend - i + 1;
|
||||
glBufferSubData(target, i, size, (U8*) data + (i-start));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer()
|
||||
|
|
@ -1383,114 +1429,116 @@ void LLVertexBuffer::_unmapBuffer()
|
|||
}
|
||||
};
|
||||
|
||||
#if LL_DARWIN
|
||||
STOP_GLERROR;
|
||||
if (mMappedData)
|
||||
if (gGLManager.mIsApple)
|
||||
{
|
||||
if (mGLBuffer)
|
||||
STOP_GLERROR;
|
||||
if (mMappedData)
|
||||
{
|
||||
glDeleteBuffers(1, &mGLBuffer);
|
||||
if (mGLBuffer)
|
||||
{
|
||||
delete_buffers(1, &mGLBuffer);
|
||||
}
|
||||
mGLBuffer = gen_buffer();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW);
|
||||
}
|
||||
mGLBuffer = gen_buffer();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW);
|
||||
}
|
||||
else if (mGLBuffer != sGLRenderBuffer)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
}
|
||||
STOP_GLERROR;
|
||||
|
||||
if (mMappedIndexData)
|
||||
{
|
||||
if (mGLIndices)
|
||||
{
|
||||
glDeleteBuffers(1, &mGLIndices);
|
||||
}
|
||||
|
||||
mGLIndices = gen_buffer();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
|
||||
sGLRenderIndices = mGLIndices;
|
||||
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW);
|
||||
}
|
||||
else if (mGLIndices != sGLRenderIndices)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
|
||||
sGLRenderIndices = mGLIndices;
|
||||
}
|
||||
STOP_GLERROR;
|
||||
#else
|
||||
|
||||
if (!mMappedVertexRegions.empty())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex");
|
||||
|
||||
if (sGLRenderBuffer != mGLBuffer)
|
||||
else if (mGLBuffer != sGLRenderBuffer)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
}
|
||||
STOP_GLERROR;
|
||||
|
||||
U32 start = 0;
|
||||
U32 end = 0;
|
||||
|
||||
std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion());
|
||||
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
if (mMappedIndexData)
|
||||
{
|
||||
const MappedRegion& region = mMappedVertexRegions[i];
|
||||
if (region.mStart == end + 1)
|
||||
if (mGLIndices)
|
||||
{
|
||||
end = region.mEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
|
||||
start = region.mStart;
|
||||
end = region.mEnd;
|
||||
delete_buffers(1, &mGLIndices);
|
||||
}
|
||||
|
||||
mGLIndices = gen_buffer();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
|
||||
sGLRenderIndices = mGLIndices;
|
||||
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
|
||||
mMappedVertexRegions.clear();
|
||||
}
|
||||
|
||||
if (!mMappedIndexRegions.empty())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index");
|
||||
|
||||
if (mGLIndices != sGLRenderIndices)
|
||||
else if (mGLIndices != sGLRenderIndices)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
|
||||
sGLRenderIndices = mGLIndices;
|
||||
}
|
||||
U32 start = 0;
|
||||
U32 end = 0;
|
||||
|
||||
std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion());
|
||||
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
STOP_GLERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mMappedVertexRegions.empty())
|
||||
{
|
||||
const MappedRegion& region = mMappedIndexRegions[i];
|
||||
if (region.mStart == end + 1)
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex");
|
||||
|
||||
if (sGLRenderBuffer != mGLBuffer)
|
||||
{
|
||||
end = region.mEnd;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
|
||||
sGLRenderBuffer = mGLBuffer;
|
||||
}
|
||||
else
|
||||
|
||||
U32 start = 0;
|
||||
U32 end = 0;
|
||||
|
||||
std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion());
|
||||
|
||||
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
|
||||
{
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
|
||||
start = region.mStart;
|
||||
end = region.mEnd;
|
||||
const MappedRegion& region = mMappedVertexRegions[i];
|
||||
if (region.mStart == end + 1)
|
||||
{
|
||||
end = region.mEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
|
||||
start = region.mStart;
|
||||
end = region.mEnd;
|
||||
}
|
||||
}
|
||||
|
||||
flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData);
|
||||
mMappedVertexRegions.clear();
|
||||
}
|
||||
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
|
||||
mMappedIndexRegions.clear();
|
||||
if (!mMappedIndexRegions.empty())
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index");
|
||||
|
||||
if (mGLIndices != sGLRenderIndices)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
|
||||
sGLRenderIndices = mGLIndices;
|
||||
}
|
||||
U32 start = 0;
|
||||
U32 end = 0;
|
||||
|
||||
std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion());
|
||||
|
||||
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
|
||||
{
|
||||
const MappedRegion& region = mMappedIndexRegions[i];
|
||||
if (region.mStart == end + 1)
|
||||
{
|
||||
end = region.mEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
|
||||
start = region.mStart;
|
||||
end = region.mEnd;
|
||||
}
|
||||
}
|
||||
|
||||
flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
|
||||
mMappedIndexRegions.clear();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1743,7 +1743,7 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
|
|||
{
|
||||
LLRect local_rect = item->getLocalRect();
|
||||
S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
|
||||
S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight();
|
||||
S32 label_height = getLabelFont()->getLineHeight();
|
||||
// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
|
||||
S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight();
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
|
|||
// statics
|
||||
std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
|
||||
|
||||
bool LLFolderViewItem::sColorSetInitialized = false;
|
||||
LLUIColor LLFolderViewItem::sFgColor;
|
||||
LLUIColor LLFolderViewItem::sHighlightBgColor;
|
||||
LLUIColor LLFolderViewItem::sFlashBgColor;
|
||||
|
|
@ -62,6 +61,10 @@ LLUIColor LLFolderViewItem::sSuffixColor;
|
|||
LLUIColor LLFolderViewItem::sSearchStatusColor;
|
||||
// <FS:Ansariel> Special for protected items
|
||||
LLUIColor LLFolderViewItem::sProtectedColor;
|
||||
S32 LLFolderViewItem::sTopPad = 0;
|
||||
LLUIImagePtr LLFolderViewItem::sFolderArrowImg;
|
||||
LLUIImagePtr LLFolderViewItem::sSelectionImg;
|
||||
LLFontGL* LLFolderViewItem::sSuffixFont = nullptr;
|
||||
|
||||
// only integers can be initialized in header
|
||||
const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
|
||||
|
|
@ -87,15 +90,51 @@ LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
|
|||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
const LLFontGL* LLFolderViewItem::getLabelFont()
|
||||
{
|
||||
if (!pLabelFont)
|
||||
{
|
||||
pLabelFont = getLabelFontForStyle(mLabelStyle);
|
||||
}
|
||||
return pLabelFont;
|
||||
}
|
||||
//static
|
||||
void LLFolderViewItem::initClass()
|
||||
{
|
||||
const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
|
||||
sTopPad = default_params.item_top_pad;
|
||||
sFolderArrowImg = default_params.folder_arrow_image;
|
||||
sSelectionImg = default_params.selection_image;
|
||||
sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL);
|
||||
|
||||
// <FS:Ansariel> Make inventory selection color independent from menu color
|
||||
//sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
|
||||
//sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
|
||||
sFgColor = LLUIColorTable::instance().getColor("InventoryItemEnabledColor", DEFAULT_WHITE);
|
||||
sHighlightBgColor = LLUIColorTable::instance().getColor("InventoryItemHighlightBgColor", DEFAULT_WHITE);
|
||||
// </FS:Ansariel>
|
||||
sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
|
||||
sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
|
||||
sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
|
||||
sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
|
||||
sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
|
||||
// <FS:Ansariel> Fix misleading color name
|
||||
//sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
|
||||
sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE);
|
||||
// </FS:Ansariel>
|
||||
sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
|
||||
// <FS:Ansariel> Special for protected items
|
||||
sProtectedColor = LLUIColorTable::instance().getColor("InventoryProtectedColor", DEFAULT_WHITE);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFolderViewItem::cleanupClass()
|
||||
{
|
||||
sFonts.clear();
|
||||
sFolderArrowImg = nullptr;
|
||||
sSelectionImg = nullptr;
|
||||
sSuffixFont = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -141,6 +180,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
mIsItemCut(false),
|
||||
mCutGeneration(0),
|
||||
mLabelStyle( LLFontGL::NORMAL ),
|
||||
pLabelFont(nullptr),
|
||||
mHasVisibleChildren(false),
|
||||
mLocalIndentation(p.folder_indentation),
|
||||
mIndentation(0),
|
||||
|
|
@ -168,29 +208,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
mForInventory(p.for_inventory),
|
||||
mItemTopPad(p.item_top_pad)
|
||||
{
|
||||
if (!sColorSetInitialized)
|
||||
{
|
||||
// <FS:Ansariel> Make inventory selection color independent from menu color
|
||||
//sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
|
||||
//sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
|
||||
sFgColor = LLUIColorTable::instance().getColor("InventoryItemEnabledColor", DEFAULT_WHITE);
|
||||
sHighlightBgColor = LLUIColorTable::instance().getColor("InventoryItemHighlightBgColor", DEFAULT_WHITE);
|
||||
// </FS:Ansariel> Make inventory selection color independent from menu color
|
||||
sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
|
||||
sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
|
||||
sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
|
||||
sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
|
||||
sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
|
||||
// <FS:Ansariel> Fix misleading color name
|
||||
//sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
|
||||
sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemSuffixColor", DEFAULT_WHITE);
|
||||
// </FS:Ansariel>
|
||||
sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
|
||||
// <FS:Ansariel> Special for protected items
|
||||
sProtectedColor = LLUIColorTable::instance().getColor("InventoryProtectedColor", DEFAULT_WHITE);
|
||||
sColorSetInitialized = true;
|
||||
}
|
||||
|
||||
if (mViewModelItem)
|
||||
{
|
||||
mViewModelItem->setFolderViewItem(this);
|
||||
|
|
@ -339,6 +356,7 @@ void LLFolderViewItem::refresh()
|
|||
// Very Expensive!
|
||||
// Can do a number of expensive checks, like checking active motions, wearables or friend list
|
||||
mLabelStyle = vmi.getLabelStyle();
|
||||
pLabelFont = nullptr; // refresh can be called from a coro, don't use getLabelFontForStyle, coro trips font list tread safety
|
||||
mLabelSuffix = utf8str_to_wstring(vmi.getLabelSuffix());
|
||||
mSuffixFontBuffer.reset();
|
||||
}
|
||||
|
|
@ -365,6 +383,7 @@ void LLFolderViewItem::refreshSuffix()
|
|||
// Very Expensive!
|
||||
// Can do a number of expensive checks, like checking active motions, wearables or friend list
|
||||
mLabelStyle = vmi->getLabelStyle();
|
||||
pLabelFont = nullptr;
|
||||
mLabelSuffix = utf8str_to_wstring(vmi->getLabelSuffix());
|
||||
}
|
||||
|
||||
|
|
@ -805,21 +824,18 @@ bool LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
|
|||
return handled;
|
||||
}
|
||||
|
||||
void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color)
|
||||
void LLFolderViewItem::drawOpenFolderArrow()
|
||||
{
|
||||
//--------------------------------------------------------------------------------//
|
||||
// Draw open folder arrow
|
||||
//
|
||||
// <FS:Ansariel> Inventory specials
|
||||
//const S32 TOP_PAD = default_params.item_top_pad;
|
||||
const S32 TOP_PAD = mItemTopPad;
|
||||
|
||||
if (hasVisibleChildren() || !isFolderComplete())
|
||||
{
|
||||
LLUIImage* arrow_image = default_params.folder_arrow_image;
|
||||
gl_draw_scaled_rotated_image(
|
||||
mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
|
||||
mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color);
|
||||
// <FS:Ansariel> Inventory specials
|
||||
mIndentation, getRect().getHeight() - mArrowSize - mTextPad - mItemTopPad,
|
||||
mArrowSize, mArrowSize, mControlLabelRotation, sFolderArrowImg->getImage(), sFgColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -835,7 +851,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
|
|||
|
||||
/*virtual*/ bool LLFolderViewItem::isFadeItem()
|
||||
{
|
||||
LLClipboard& clipboard = LLClipboard::instance();
|
||||
static const LLClipboard& clipboard = LLClipboard::instance(); // Make it a 'simpleton'?
|
||||
if (mCutGeneration != clipboard.getGeneration())
|
||||
{
|
||||
mCutGeneration = clipboard.getGeneration();
|
||||
|
|
@ -971,18 +987,14 @@ void LLFolderViewItem::draw()
|
|||
const bool show_context = (getRoot() ? getRoot()->getShowSelectionContext() : false);
|
||||
const bool filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : false); // If we have keyboard focus, draw selection filled
|
||||
|
||||
const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
|
||||
// <FS:Ansariel> Inventory specials
|
||||
//const S32 TOP_PAD = default_params.item_top_pad;
|
||||
const S32 TOP_PAD = mItemTopPad;
|
||||
|
||||
const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
|
||||
const LLFontGL* font = getLabelFont();
|
||||
S32 line_height = font->getLineHeight();
|
||||
|
||||
getViewModelItem()->update();
|
||||
|
||||
if (!mSingleFolderMode)
|
||||
{
|
||||
drawOpenFolderArrow(default_params, sFgColor);
|
||||
drawOpenFolderArrow();
|
||||
}
|
||||
|
||||
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
|
||||
|
|
@ -991,18 +1003,19 @@ void LLFolderViewItem::draw()
|
|||
// Draw open icon
|
||||
//
|
||||
const S32 icon_x = mIndentation + mArrowSize + mTextPad;
|
||||
const S32 rect_height = getRect().getHeight();
|
||||
if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
|
||||
{
|
||||
mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
|
||||
mIconOpen->draw(icon_x, rect_height - mIconOpen->getHeight() - mItemTopPad + 1);
|
||||
}
|
||||
else if (mIcon)
|
||||
{
|
||||
mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
|
||||
mIcon->draw(icon_x, rect_height - mIcon->getHeight() - mItemTopPad + 1);
|
||||
}
|
||||
|
||||
if (mIconOverlay && getRoot()->showItemLinkOverlays())
|
||||
{
|
||||
mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
|
||||
mIconOverlay->draw(icon_x, rect_height - mIcon->getHeight() - mItemTopPad + 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
|
|
@ -1015,24 +1028,22 @@ void LLFolderViewItem::draw()
|
|||
|
||||
S32 filter_string_length = mViewModelItem->hasFilterStringMatch() ? (S32)mViewModelItem->getFilterStringSize() : 0;
|
||||
F32 right_x = 0;
|
||||
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
F32 y = (F32)rect_height - line_height - (F32)mTextPad - (F32)mItemTopPad;
|
||||
F32 text_left = (F32)getLabelXPos();
|
||||
LLWString combined_string = mLabel + mLabelSuffix;
|
||||
|
||||
const LLFontGL* suffix_font = getLabelFontForStyle(LLFontGL::NORMAL);
|
||||
S32 filter_offset = static_cast<S32>(mViewModelItem->getFilterStringOffset());
|
||||
if (filter_string_length > 0)
|
||||
{
|
||||
S32 bottom = getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD;
|
||||
S32 top = getRect().getHeight() - TOP_PAD;
|
||||
if(mLabelSuffix.empty() || (font == suffix_font))
|
||||
S32 bottom = rect_height - line_height - 3 - mItemTopPad;
|
||||
S32 top = rect_height - mItemTopPad;
|
||||
if(mLabelSuffix.empty() || (font == sSuffixFont))
|
||||
{
|
||||
S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, static_cast<S32>(mViewModelItem->getFilterStringOffset())) - 2;
|
||||
S32 right = left + font->getWidth(combined_string.c_str(), static_cast<S32>(mViewModelItem->getFilterStringOffset()), filter_string_length) + 2;
|
||||
S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, filter_offset) - 2;
|
||||
S32 right = left + font->getWidth(combined_string.c_str(), filter_offset, filter_string_length) + 2;
|
||||
|
||||
LLUIImage* box_image = default_params.selection_image;
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
box_image->draw(box_rect, sFilterBGColor);
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
sSelectionImg->draw(box_rect, sFilterBGColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1041,19 +1052,17 @@ void LLFolderViewItem::draw()
|
|||
{
|
||||
S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, llmin(filter_offset, (S32)mLabel.size()))) - 2;
|
||||
S32 right = left + (S32)font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length) + 2;
|
||||
LLUIImage* box_image = default_params.selection_image;
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
box_image->draw(box_rect, sFilterBGColor);
|
||||
sSelectionImg->draw(box_rect, sFilterBGColor);
|
||||
}
|
||||
S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length;
|
||||
if(suffix_filter_length > 0)
|
||||
{
|
||||
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
|
||||
S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2;
|
||||
S32 right = left + (S32)suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2;
|
||||
LLUIImage* box_image = default_params.selection_image;
|
||||
S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2;
|
||||
S32 right = left + (S32)sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2;
|
||||
LLRect box_rect(left, top, right, bottom);
|
||||
box_image->draw(box_rect, sFilterBGColor);
|
||||
sSelectionImg->draw(box_rect, sFilterBGColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1092,7 +1101,7 @@ void LLFolderViewItem::draw()
|
|||
//
|
||||
if (!mLabelSuffix.empty())
|
||||
{
|
||||
mSuffixFontBuffer.render(suffix_font, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(),
|
||||
mSuffixFontBuffer.render(sSuffixFont, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(),
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x);
|
||||
}
|
||||
|
|
@ -1102,10 +1111,10 @@ void LLFolderViewItem::draw()
|
|||
//
|
||||
if (filter_string_length > 0)
|
||||
{
|
||||
if(mLabelSuffix.empty() || (font == suffix_font))
|
||||
if(mLabelSuffix.empty() || (font == sSuffixFont))
|
||||
{
|
||||
F32 match_string_left = text_left + font->getWidthF32(combined_string.c_str(), 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string.c_str(), filter_offset, filter_string_length);
|
||||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)mItemTopPad;
|
||||
font->render(combined_string, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x);
|
||||
|
|
@ -1116,7 +1125,7 @@ void LLFolderViewItem::draw()
|
|||
if(label_filter_length > 0)
|
||||
{
|
||||
F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length);
|
||||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)mItemTopPad;
|
||||
font->render(mLabel, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
label_filter_length, S32_MAX, &right_x);
|
||||
|
|
@ -1126,9 +1135,9 @@ void LLFolderViewItem::draw()
|
|||
if(suffix_filter_length > 0)
|
||||
{
|
||||
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
|
||||
F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length);
|
||||
F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
suffix_font->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
|
||||
F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast<S32>(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length);
|
||||
F32 yy = (F32)rect_height - sSuffixFont->getLineHeight() - (F32)mTextPad - (F32)mItemTopPad;
|
||||
sSuffixFont->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
suffix_filter_length, S32_MAX, &right_x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,6 @@ protected:
|
|||
S32 mItemTopPad;
|
||||
|
||||
// For now assuming all colors are the same in derived classes.
|
||||
static bool sColorSetInitialized;
|
||||
static LLUIColor sFgColor;
|
||||
static LLUIColor sFgDisabledColor;
|
||||
static LLUIColor sHighlightBgColor;
|
||||
|
|
@ -168,6 +167,7 @@ protected:
|
|||
virtual void setFlashState(bool) { }
|
||||
|
||||
static LLFontGL* getLabelFontForStyle(U8 style);
|
||||
const LLFontGL* getLabelFont();
|
||||
|
||||
bool mIsSelected;
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ public:
|
|||
|
||||
// virtual void handleDropped();
|
||||
virtual void draw();
|
||||
void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
|
||||
void drawOpenFolderArrow();
|
||||
void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor);
|
||||
void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
|
||||
virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
|
||||
|
|
@ -323,9 +323,14 @@ public:
|
|||
|
||||
private:
|
||||
static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
|
||||
static S32 sTopPad;
|
||||
static LLUIImagePtr sFolderArrowImg;
|
||||
static LLUIImagePtr sSelectionImg;
|
||||
static LLFontGL* sSuffixFont;
|
||||
|
||||
LLFontVertexBuffer mLabelFontBuffer;
|
||||
LLFontVertexBuffer mSuffixFontBuffer;
|
||||
LLFontGL* pLabelFont{nullptr};
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 60
|
||||
version 61
|
||||
// The version number above should be incremented IF AND ONLY IF some
|
||||
// change has been made that is sufficiently important to justify
|
||||
// resetting the graphics preferences of all users to the recommended
|
||||
|
|
@ -68,7 +68,8 @@ RenderFSAASamples 1 3
|
|||
RenderMaxTextureIndex 1 16
|
||||
RenderGLContextCoreProfile 1 1
|
||||
RenderGLMultiThreadedTextures 1 0
|
||||
RenderGLMultiThreadedMedia 1 0
|
||||
RenderGLMultiThreadedMedia 1 1
|
||||
RenderAppleUseMultGL 1 1
|
||||
RenderReflectionsEnabled 1 1
|
||||
RenderReflectionProbeDetail 1 2
|
||||
RenderScreenSpaceReflections 1 1
|
||||
|
|
@ -381,6 +382,15 @@ list Intel
|
|||
RenderAnisotropic 1 0
|
||||
RenderFSAASamples 1 0
|
||||
|
||||
// AppleGPU and NonAppleGPU can be thought of as Apple silicon vs Intel Mac
|
||||
list AppleGPU
|
||||
RenderGLMultiThreadedMedia 1 1
|
||||
RenderAppleUseMultGL 1 1
|
||||
|
||||
list NonAppleGPU
|
||||
RenderGLMultiThreadedMedia 1 0
|
||||
RenderAppleUseMultGL 1 0
|
||||
|
||||
list GL3
|
||||
RenderFSAASamples 0 0
|
||||
RenderReflectionProbeDetail 0 0
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ void LLConversationViewSession::draw()
|
|||
{
|
||||
// update the rotation angle of open folder arrow
|
||||
updateLabelRotation();
|
||||
drawOpenFolderArrow(default_params, sFgColor);
|
||||
drawOpenFolderArrow();
|
||||
}
|
||||
LLView::draw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@ bool LLViewerDynamicTexture::updateAllInstances()
|
|||
}
|
||||
llassert(preview_target.getWidth() >= LLPipeline::MAX_PREVIEW_WIDTH);
|
||||
llassert(preview_target.getHeight() >= LLPipeline::MAX_PREVIEW_WIDTH);
|
||||
llassert(bake_target.getWidth() >= LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH);
|
||||
llassert(bake_target.getHeight() >= LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT);
|
||||
llassert(bake_target.getWidth() >= (U32) LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH);
|
||||
llassert(bake_target.getHeight() >= (U32) LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT);
|
||||
|
||||
preview_target.bindTarget();
|
||||
preview_target.clear();
|
||||
|
|
|
|||
|
|
@ -666,6 +666,14 @@ void LLFeatureManager::applyBaseMasks()
|
|||
{
|
||||
maskFeatures("Intel");
|
||||
}
|
||||
if (gGLManager.mIsApple)
|
||||
{
|
||||
maskFeatures("AppleGPU");
|
||||
}
|
||||
else
|
||||
{
|
||||
maskFeatures("NonAppleGPU");
|
||||
}
|
||||
if (gGLManager.mGLVersion < 3.f)
|
||||
{
|
||||
maskFeatures("OpenGLPre30");
|
||||
|
|
|
|||
|
|
@ -4064,6 +4064,7 @@ void LLMeshRepository::notifyLoadedMeshes()
|
|||
for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;)
|
||||
{
|
||||
auto copy_iter = iter++;
|
||||
LLUUID id = copy_iter->first;
|
||||
|
||||
//skinbytes += U64Bytes(sizeof(LLMeshSkinInfo));
|
||||
//skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string));
|
||||
|
|
@ -4077,7 +4078,6 @@ void LLMeshRepository::notifyLoadedMeshes()
|
|||
}
|
||||
|
||||
// erase from background thread
|
||||
LLUUID id = iter->first;
|
||||
mThread->mWorkQueue.post([=]()
|
||||
{
|
||||
mThread->mSkinMap.erase(id);
|
||||
|
|
|
|||
|
|
@ -2556,8 +2556,6 @@ void LLVOAvatar::updateMeshData()
|
|||
{
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
S32 f_num = 0 ;
|
||||
const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer.
|
||||
const auto num_parts = mMeshLOD.size();
|
||||
|
|
@ -2684,7 +2682,6 @@ void LLVOAvatar::updateMeshData()
|
|||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
buff->unmapBuffer();
|
||||
|
||||
if(!f_num)
|
||||
|
|
@ -11806,9 +11803,8 @@ void LLVOAvatar::updateRiggingInfo()
|
|||
getAssociatedVolumes(volumes);
|
||||
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key")
|
||||
HBXXH128 hash;
|
||||
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key");
|
||||
size_t hash = 0;
|
||||
// Get current rigging info key
|
||||
for (LLVOVolume* vol : volumes)
|
||||
{
|
||||
|
|
@ -11817,22 +11813,20 @@ void LLVOAvatar::updateRiggingInfo()
|
|||
const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID();
|
||||
S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD);
|
||||
|
||||
hash.update(mesh_id.mData, sizeof(mesh_id.mData));
|
||||
hash.update(&max_lod, sizeof(max_lod));
|
||||
boost::hash_combine(hash, mesh_id);
|
||||
boost::hash_combine(hash, max_lod);
|
||||
}
|
||||
}
|
||||
|
||||
LLUUID curr_rigging_info_key = hash.digest();
|
||||
|
||||
// Check for key change, which indicates some change in volume composition or LOD.
|
||||
if (curr_rigging_info_key == mLastRiggingInfoKey)
|
||||
if (hash == mLastRiggingInfoKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Something changed. Update.
|
||||
mLastRiggingInfoKey = curr_rigging_info_key;
|
||||
mLastRiggingInfoKey = hash;
|
||||
}
|
||||
|
||||
mJointRiggingInfoTab.clear();
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ public:
|
|||
// virtual
|
||||
void updateRiggingInfo();
|
||||
// This encodes mesh id and LOD, so we can see whether display is up-to-date.
|
||||
LLUUID mLastRiggingInfoKey;
|
||||
size_t mLastRiggingInfoKey;
|
||||
|
||||
std::set<LLUUID> mActiveOverrideMeshes;
|
||||
virtual void onActiveOverrideMeshesChanged();
|
||||
|
|
|
|||
|
|
@ -774,7 +774,6 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
|
|||
}
|
||||
}
|
||||
|
||||
buffer->unmapBuffer();
|
||||
mFaceList.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,63 +54,6 @@ void LLVOPartGroup::initClass()
|
|||
void LLVOPartGroup::restoreGL()
|
||||
{
|
||||
|
||||
//TODO: optimize out binormal mask here. Specular and normal coords as well.
|
||||
#if 0
|
||||
sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
|
||||
U32 count = LL_MAX_PARTICLE_COUNT;
|
||||
if (!sVB->allocateBuffer(count*4, count*6))
|
||||
{
|
||||
LL_WARNS() << "Failed to allocate Vertex Buffer to "
|
||||
<< count*4 << " vertices and "
|
||||
<< count * 6 << " indices" << LL_ENDL;
|
||||
// we are likelly to crash at following getTexCoord0Strider(), so unref and return
|
||||
sVB = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
//indices and texcoords are always the same, set once
|
||||
LLStrider<U16> indicesp;
|
||||
|
||||
LLStrider<LLVector4a> verticesp;
|
||||
|
||||
sVB->getIndexStrider(indicesp);
|
||||
sVB->getVertexStrider(verticesp);
|
||||
|
||||
LLVector4a v;
|
||||
v.set(0,0,0,0);
|
||||
|
||||
|
||||
U16 vert_offset = 0;
|
||||
|
||||
for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
|
||||
{
|
||||
*indicesp++ = vert_offset + 0;
|
||||
*indicesp++ = vert_offset + 1;
|
||||
*indicesp++ = vert_offset + 2;
|
||||
|
||||
*indicesp++ = vert_offset + 1;
|
||||
*indicesp++ = vert_offset + 3;
|
||||
*indicesp++ = vert_offset + 2;
|
||||
|
||||
*verticesp++ = v;
|
||||
|
||||
vert_offset += 4;
|
||||
}
|
||||
|
||||
LLStrider<LLVector2> texcoordsp;
|
||||
sVB->getTexCoord0Strider(texcoordsp);
|
||||
|
||||
for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
|
||||
{
|
||||
*texcoordsp++ = LLVector2(0.f, 1.f);
|
||||
*texcoordsp++ = LLVector2(0.f, 0.f);
|
||||
*texcoordsp++ = LLVector2(1.f, 1.f);
|
||||
*texcoordsp++ = LLVector2(1.f, 0.f);
|
||||
}
|
||||
|
||||
sVB->unmapBuffer();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -969,7 +912,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
|
|||
}
|
||||
}
|
||||
|
||||
buffer->unmapBuffer();
|
||||
mFaceList.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1078,7 +1078,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
|
|||
gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, indices, region_width);
|
||||
}
|
||||
|
||||
buffer->unmapBuffer();
|
||||
mFaceList.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3873,6 +3873,7 @@ void LLPipeline::postSort(LLCamera &camera)
|
|||
}
|
||||
}
|
||||
|
||||
LLVertexBuffer::flushBuffers();
|
||||
// LLSpatialGroup::sNoDelete = false;
|
||||
LL_PUSH_CALLSTACKS();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue