summaryrefslogtreecommitdiff
path: root/indra/llrender/llrender.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-08-28 23:05:58 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-09-04 10:16:46 +0300
commit4ae1de1f8a78d795958d67afab8356f9a13f707d (patch)
treeea0fe05983562f061a4748a6f4af7253018f9660 /indra/llrender/llrender.cpp
parent36423bd6603c5708028c6e8e9705587b961a4bb2 (diff)
viewer#2411 LLFontGL::render optimizations
Diffstat (limited to 'indra/llrender/llrender.cpp')
-rw-r--r--indra/llrender/llrender.cpp197
1 files changed, 164 insertions, 33 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 7a52f9cfb5..8cd2d9cc15 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1570,6 +1570,51 @@ void LLRender::end()
flush();
}
}
+
+LLVertexBuffer* LLRender::beginNoCache(const GLuint& mode, S32& count)
+{
+ if (mode != mMode)
+ {
+ if (mode == LLRender::QUADS)
+ {
+ mQuadCycle = 1;
+ }
+
+ if (mMode == LLRender::QUADS ||
+ mMode == LLRender::LINES ||
+ mMode == LLRender::TRIANGLES ||
+ mMode == LLRender::POINTS)
+ {
+ return getBuffer(count);
+ }
+ else if (mCount != 0)
+ {
+ LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL;
+ }
+ mMode = mode;
+ }
+ return nullptr;
+}
+
+LLVertexBuffer* LLRender::endNoCache(S32& count)
+{
+ if (mCount == 0)
+ {
+ return nullptr;
+ //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL;
+ }
+
+ if ((mMode != LLRender::QUADS &&
+ mMode != LLRender::LINES &&
+ mMode != LLRender::TRIANGLES &&
+ mMode != LLRender::POINTS) ||
+ mCount > 2048)
+ {
+ return getBuffer(count);
+ }
+ return nullptr;
+}
+
void LLRender::flush()
{
STOP_GLERROR;
@@ -1664,27 +1709,7 @@ void LLRender::flush()
else
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
- vb = new LLVertexBuffer(attribute_mask);
- vb->allocateBuffer(count, 0);
-
- vb->setBuffer();
-
- vb->setPositionData((LLVector4a*) mVerticesp.get());
-
- if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
- {
- vb->setTexCoord0Data(mTexcoordsp.get());
- }
-
- if (attribute_mask & LLVertexBuffer::MAP_COLOR)
- {
- vb->setColorData(mColorsp.get());
- }
-
-#if LL_DARWIN
- vb->unmapBuffer();
-#endif
- vb->unbind();
+ vb = genBuffer(attribute_mask, count);
sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
@@ -1712,31 +1737,137 @@ void LLRender::flush()
}
}
- vb->setBuffer();
+ drawBuffer(vb, mMode, count);
+ }
+ else
+ {
+ // mBuffer is present in main thread and not present in an image thread
+ LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
+ }
+
+ resetStriders(count);
+ }
+}
+
+LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
+{
+ LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask);
+ vb->allocateBuffer(count, 0);
+
+ vb->setBuffer();
+
+ vb->setPositionData((LLVector4a*)mVerticesp.get());
+
+ if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ vb->setTexCoord0Data(mTexcoordsp.get());
+ }
- if (mMode == LLRender::QUADS && sGLCoreProfile)
+ if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ {
+ vb->setColorData(mColorsp.get());
+ }
+
+#if LL_DARWIN
+ vb->unmapBuffer();
+#endif
+ vb->unbind();
+
+ return vb;
+}
+
+void LLRender::drawBuffer(LLVertexBuffer* vb, U32 mode, S32 count)
+{
+ vb->setBuffer();
+
+ if (mode == LLRender::QUADS && sGLCoreProfile)
+ {
+ vb->drawArrays(LLRender::TRIANGLES, 0, count);
+ mQuadCycle = 1;
+ }
+ else
+ {
+ vb->drawArrays(mode, 0, count);
+ }
+}
+
+void LLRender::resetStriders(S32 count)
+{
+ mVerticesp[0] = mVerticesp[count];
+ mTexcoordsp[0] = mTexcoordsp[count];
+ mColorsp[0] = mColorsp[count];
+
+ mCount = 0;
+}
+
+LLVertexBuffer* LLRender::getBuffer(S32 & count)
+{
+ STOP_GLERROR;
+ LLVertexBuffer *vb;
+ if (mCount > 0)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ llassert(LLGLSLShader::sCurBoundShaderPtr != nullptr);
+ if (!mUIOffset.empty())
+ {
+ sUICalls++;
+ sUIVerts += mCount;
+ }
+
+ //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+ count = mCount;
+
+ if (mMode == LLRender::QUADS && !sGLCoreProfile)
+ {
+ if (mCount % 4 != 0)
{
- vb->drawArrays(LLRender::TRIANGLES, 0, count);
- mQuadCycle = 1;
+ count -= (mCount % 4);
+ LL_WARNS() << "Incomplete quad requested." << LL_ENDL;
}
- else
+ }
+
+ if (mMode == LLRender::TRIANGLES)
+ {
+ if (mCount % 3 != 0)
{
- vb->drawArrays(mMode, 0, count);
+ count -= (mCount % 3);
+ LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
}
}
+
+ if (mMode == LLRender::LINES)
+ {
+ if (mCount % 2 != 0)
+ {
+ count -= (mCount % 2);
+ LL_WARNS() << "Incomplete line requested." << LL_ENDL;
+ }
+ }
+
+ mCount = 0;
+
+ if (mBuffer)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
+
+ U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
+ vb = genBuffer(attribute_mask, count);
+ drawBuffer(vb, mMode, count);
+ }
else
{
// mBuffer is present in main thread and not present in an image thread
LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
}
-
- mVerticesp[0] = mVerticesp[count];
- mTexcoordsp[0] = mTexcoordsp[count];
- mColorsp[0] = mColorsp[count];
-
- mCount = 0;
+ resetStriders(count);
}
+ else
+ {
+ count = 0;
+ }
+
+ return vb;
}
void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)