summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontfreetype.cpp10
-rw-r--r--indra/llrender/llfontfreetypesvg.cpp4
-rw-r--r--indra/llrender/llfontfreetypesvg.h6
-rw-r--r--indra/llrender/llfontgl.cpp61
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llgl.cpp20
-rw-r--r--indra/llrender/llgl.h1
-rw-r--r--indra/llrender/llglheaders.h37
-rw-r--r--indra/llrender/llrender.cpp232
-rw-r--r--indra/llrender/llrender.h10
-rw-r--r--indra/llrender/llrender2dutils.cpp546
-rw-r--r--indra/llrender/llrendersphere.cpp62
-rw-r--r--indra/llrender/llrendersphere.h1
-rw-r--r--indra/llrender/llvertexbuffer.cpp390
14 files changed, 821 insertions, 563 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 6128e03fa7..fa76669258 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -52,7 +52,9 @@
#include "llfontbitmapcache.h"
#include "llgl.h"
-#define ENABLE_OT_SVG_SUPPORT
+#if !defined(LL_NO_OTSVG)
+ #define ENABLE_OT_SVG_SUPPORT
+#endif
FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL;
@@ -87,7 +89,7 @@ LLFontManager::LLFontManager()
FT_Done_FreeType(gFTLibrary);
}
-#ifdef ENABLE_OT_SVG_SUPPORT
+#if defined(ENABLE_OT_SVG_SUPPORT)
SVG_RendererHooks hooks = {
LLFontFreeTypeSvgRenderer::OnInit,
LLFontFreeTypeSvgRenderer::OnFree,
@@ -483,8 +485,8 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type
continue;
}
glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
- if (glyph_index)
- {
+ if (glyph_index)
+ {
return addGlyphFromFont(pair.first, wch, glyph_index,
glyph_type);
}
diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp
index 71f751329e..15251fe1b1 100644
--- a/indra/llrender/llfontfreetypesvg.cpp
+++ b/indra/llrender/llfontfreetypesvg.cpp
@@ -80,6 +80,7 @@ void LLFontFreeTypeSvgRenderer::OnDataFinalizer(void* objectp)
//static
FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer*)
{
+#ifndef LL_NO_OTSVG
FT_SVG_Document document = static_cast<FT_SVG_Document>(glyph_slot->other);
llassert(!glyph_slot->generic.data || !cache || glyph_slot->glyph_index == ((LLSvgRenderData*)glyph_slot->generic.data)->GlyphIndex);
@@ -166,6 +167,9 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot,
}
return FT_Err_Ok;
+#else
+ return FT_Err_Unimplemented_Feature;
+#endif
}
// static
diff --git a/indra/llrender/llfontfreetypesvg.h b/indra/llrender/llfontfreetypesvg.h
index 4170cab273..94b83d5fff 100644
--- a/indra/llrender/llfontfreetypesvg.h
+++ b/indra/llrender/llfontfreetypesvg.h
@@ -29,7 +29,11 @@
#include <ft2build.h>
#include FT_TYPES_H
#include FT_MODULE_H
-#include FT_OTSVG_H
+#ifdef FT_OTSVG_H
+ #include FT_OTSVG_H
+#else
+ #define LL_NO_OTSVG
+#endif
// See https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html
class LLFontFreeTypeSvgRenderer
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 9721b020c7..94daba0817 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -271,9 +271,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontGlyphInfo* next_glyph = NULL;
static constexpr S32 GLYPH_BATCH_SIZE = 30;
- static thread_local LLVector3 vertices[GLYPH_BATCH_SIZE * 4];
- static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 4];
- static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 4];
+ static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];
+ static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6];
+ static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 6];
LLColor4U text_color(color);
// Preserve the transparency to render fading emojis in fading text (e.g.
@@ -305,9 +305,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
// otherwise the queued glyphs will be taken from wrong textures.
if (glyph_count > 0)
{
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6);
}
gGL.end();
glyph_count = 0;
@@ -338,9 +338,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
if (glyph_count >= GLYPH_BATCH_SIZE)
{
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6);
}
gGL.end();
@@ -376,9 +376,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_render_y = cur_y;
}
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6);
}
gGL.end();
@@ -1227,31 +1227,42 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)
return *this;
}
-void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const
+void LLFontGL::renderTriangle(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const
{
S32 index = 0;
- vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f);
- uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+ vertex_out[index].set(screen_rect.mRight, screen_rect.mTop, 0.f);
+ uv_out[index].set(uv_rect.mRight, uv_rect.mTop);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f);
- uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+ vertex_out[index].set(screen_rect.mLeft, screen_rect.mTop, 0.f);
+ uv_out[index].set(uv_rect.mLeft, uv_rect.mTop);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f);
- uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+ vertex_out[index].set(screen_rect.mLeft, screen_rect.mBottom, 0.f);
+ uv_out[index].set(uv_rect.mLeft, uv_rect.mBottom);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f);
- uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+
+ vertex_out[index].set(screen_rect.mRight, screen_rect.mTop, 0.f);
+ uv_out[index].set(uv_rect.mRight, uv_rect.mTop);
+ colors_out[index] = color;
+ index++;
+
+ vertex_out[index].set(screen_rect.mLeft, screen_rect.mBottom, 0.f);
+ uv_out[index].set(uv_rect.mLeft, uv_rect.mBottom);
+ colors_out[index] = color;
+ index++;
+
+ vertex_out[index].set(screen_rect.mRight, screen_rect.mBottom, 0.f);
+ uv_out[index].set(uv_rect.mRight, uv_rect.mBottom);
colors_out[index] = color;
}
-void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
+void LLFontGL::drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
{
F32 slant_offset;
slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
@@ -1265,7 +1276,7 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_
LLRectf screen_rect_offset = screen_rect;
screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_offset, uv_rect, color, slant_offset);
glyph_count++;
}
}
@@ -1296,10 +1307,10 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_
break;
}
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_offset, uv_rect, shadow_color, slant_offset);
glyph_count++;
}
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
else if (shadow == DROP_SHADOW)
@@ -1308,14 +1319,14 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_
shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength);
LLRectf screen_rect_shadow = screen_rect;
screen_rect_shadow.translate(1.f, -1.f);
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
glyph_count++;
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
else // normal rendering
{
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset);
glyph_count++;
}
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index de7529a583..4bb6c55c65 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -238,8 +238,8 @@ private:
LLFontDescriptor mFontDescriptor;
LLPointer<LLFontFreetype> mFontFreetype;
- void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
- void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
+ void renderTriangle(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
+ void drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
// Registry holds all instantiated fonts.
static LLFontRegistry* sFontRegistry;
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c62cacdce6..15fb289de3 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -215,8 +215,6 @@ LLMatrix4 gGLObliqueProjectionInverse;
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
-#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
-
#if LL_WINDOWS
// WGL_ARB_create_context
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr;
@@ -236,8 +234,6 @@ PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = n
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr;
-#endif
-
// GL_VERSION_1_2
//PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr;
//PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
@@ -1170,6 +1166,11 @@ bool LLGLManager::initGL()
mGLVendorShort = "INTEL";
mIsIntel = true;
}
+ else if (mGLVendor.find("APPLE") != std::string::npos)
+ {
+ mGLVendorShort = "APPLE";
+ mIsApple = true;
+ }
else
{
mGLVendorShort = "MISC";
@@ -1402,6 +1403,9 @@ void LLGLManager::shutdownGL()
void LLGLManager::initExtensions()
{
+#if LL_LINUX
+ glh_init_extensions("");
+#endif
#if LL_DARWIN
GLint num_extensions = 0;
std::string all_extensions{""};
@@ -1432,10 +1436,9 @@ void LLGLManager::initExtensions()
mInited = true;
-#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
+#if LL_WINDOWS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
-#if LL_WINDOWS
// WGL_AMD_gpu_association
wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
@@ -1453,8 +1456,6 @@ void LLGLManager::initExtensions()
// WGL_ARB_create_context
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
-#endif
-
// Load entire OpenGL API through GetProcAddress, leaving sections beyond mGLVersion unloaded
@@ -2582,6 +2583,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
{
return;
}
+ LL_INFOS() << "GL: " << version << LL_ENDL;
version_string->assign(version);
@@ -2957,5 +2959,3 @@ extern "C"
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
-
-
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 17f825bd71..f5b1e8d786 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -102,6 +102,7 @@ public:
bool mIsAMD;
bool mIsNVIDIA;
bool mIsIntel;
+ bool mIsApple = false;
// hints to the render pipe
U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index c5e1ff3e23..921adc0f8c 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -41,12 +41,28 @@
# include "GL/glh_extensions.h"
# undef __APPLE__
+#elif LL_LINUX
+#define GL_GLEXT_PROTOTYPES
+#define GLX_GLEXT_PROTOTYPES
+
+#include "GL/gl.h"
+#include "GL/glext.h"
+#include "GL/glu.h"
+
+// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
+# define __APPLE__
+# include "GL/glh_extensions.h"
+# undef __APPLE__
+
+# include "GL/glx.h"
+# include "GL/glxext.h"
+
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
// windows gl headers depend on things like APIENTRY, so include windows.
-#include "llwin32headerslean.h"
+#include "llwin32headers.h"
//----------------------------------------------------------------------------
#include <GL/gl.h>
@@ -1029,6 +1045,25 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#include <OpenGL/gl.h>
+#elif LL_LINUX
+
+#define GL_GLEXT_PROTOTYPES
+#define GLX_GLEXT_PROTOTYPES
+
+#include "GL/gl.h"
+#include "GL/glu.h"
+#include "GL/glext.h"
+#include "GL/glx.h"
+
+// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
+# define __APPLE__
+# include "GL/glh_extensions.h"
+# undef __APPLE__
+
+// #include <X11/Xlib.h>
+// #include <X11/Xutil.h>
+#include "GL/glh_extensions.h"
+
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
// Even when GL_ARB_depth_clamp is available in the driver, the (correct)
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 16a8309a9a..e182b870dc 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -803,7 +803,6 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
LLRender::LLRender()
: mDirty(false),
mCount(0),
- mQuadCycle(0),
mMode(LLRender::TRIANGLES),
mCurrTextureUnitIndex(0)
{
@@ -1299,7 +1298,7 @@ void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
- mUIOffset.push_back(LLVector3(0,0,0));
+ mUIOffset.emplace_back(0.f,0.f,0.f);
}
else
{
@@ -1308,7 +1307,7 @@ void LLRender::pushUIMatrix()
if (mUIScale.empty())
{
- mUIScale.push_back(LLVector3(1,1,1));
+ mUIScale.emplace_back(1.f,1.f,1.f);
}
else
{
@@ -1532,13 +1531,7 @@ void LLRender::begin(const GLuint& mode)
{
if (mode != mMode)
{
- if (mode == LLRender::QUADS)
- {
- mQuadCycle = 1;
- }
-
- if (mMode == LLRender::QUADS ||
- mMode == LLRender::LINES ||
+ if (mMode == LLRender::LINES ||
mMode == LLRender::TRIANGLES ||
mMode == LLRender::POINTS)
{
@@ -1561,8 +1554,7 @@ void LLRender::end()
//IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL;
}
- if ((mMode != LLRender::QUADS &&
- mMode != LLRender::LINES &&
+ if ((mMode != LLRender::LINES &&
mMode != LLRender::TRIANGLES &&
mMode != LLRender::POINTS) ||
mCount > 2048)
@@ -1587,28 +1579,19 @@ void LLRender::flush()
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
U32 count = mCount;
- if (mMode == LLRender::QUADS && !sGLCoreProfile)
- {
- if (mCount%4 != 0)
- {
- count -= (mCount % 4);
- LL_WARNS() << "Incomplete quad requested." << LL_ENDL;
- }
- }
-
- if (mMode == LLRender::TRIANGLES)
+ if (mMode == LLRender::TRIANGLES)
+ {
+ if (mCount%3 != 0)
{
- if (mCount%3 != 0)
- {
- count -= (mCount % 3);
- LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
- }
+ count -= (mCount % 3);
+ LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
}
+ }
- if (mMode == LLRender::LINES)
+ if (mMode == LLRender::LINES)
+ {
+ if (mCount%2 != 0)
{
- if (mCount%2 != 0)
- {
count -= (mCount % 2);
LL_WARNS() << "Incomplete line requested." << LL_ENDL;
}
@@ -1735,7 +1718,7 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
vb->setBuffer();
- vb->setPositionData((LLVector4a*)mVerticesp.get());
+ vb->setPositionData(mVerticesp.get());
if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
{
@@ -1758,16 +1741,7 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
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);
- }
+ vb->drawArrays(mode, 0, count);
}
void LLRender::resetStriders(S32 count)
@@ -1788,7 +1762,6 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
case LLRender::POINTS: flush(); break;
case LLRender::TRIANGLES: if (mCount%3==0) flush(); break;
- case LLRender::QUADS: if(mCount%4 == 0) flush(); break;
case LLRender::LINES: if (mCount%2 == 0) flush(); break;
}
}
@@ -1801,31 +1774,12 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
if (mUIOffset.empty())
{
- mVerticesp[mCount] = LLVector3(x,y,z);
+ mVerticesp[mCount].set(x,y,z);
}
else
{
LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
- mVerticesp[mCount] = vert;
- }
-
- if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
- {
- mQuadCycle++;
- if (mQuadCycle == 4)
- { //copy two vertices so fourth quad element will add a triangle
- mQuadCycle = 0;
-
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-3];
- mColorsp[mCount] = mColorsp[mCount-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
-
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-2];
- mColorsp[mCount] = mColorsp[mCount-2];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
- }
+ mVerticesp[mCount].set(vert.mV[VX], vert.mV[VY], vert.mV[VZ]);
}
mCount++;
@@ -1834,7 +1788,7 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
}
-void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1842,57 +1796,20 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
return;
}
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy two
- mVerticesp[mCount++] = verts[i-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
+ mVerticesp[mCount] = verts[i];
- mCount++;
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
+ mCount++;
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
}
if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen
mVerticesp[mCount] = mVerticesp[mCount-1];
}
-void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1900,50 +1817,13 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v
return;
}
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount++] = uvs[i-3];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount++] = uvs[i-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
- mCount++;
- mColorsp[mCount] = mColorsp[mCount-1];
- }
+ mCount++;
+ mColorsp[mCount] = mColorsp[mCount-1];
}
if (mCount > 0)
@@ -1953,7 +1833,7 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v
}
}
-void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1961,51 +1841,13 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol
return;
}
-
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount] = uvs[i-3];
- mColorsp[mCount++] = colors[i-3];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount] = uvs[i-1];
- mColorsp[mCount++] = colors[i-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount] = colors[i];
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount] = colors[i];
- mCount++;
- }
+ mCount++;
}
if (mCount > 0)
@@ -2038,7 +1880,7 @@ void LLRender::vertex3fv(const GLfloat* v)
void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
{
- mTexcoordsp[mCount] = LLVector2(x,y);
+ mTexcoordsp[mCount].set(x,y);
}
void LLRender::texCoord2i(const GLint& x, const GLint& y)
@@ -2055,7 +1897,7 @@ void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, co
{
if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
{
- mColorsp[mCount] = LLColor4U(r,g,b,a);
+ mColorsp[mCount].set(r,g,b,a);
}
else
{ //not using shaders or shader reads color from a uniform
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 2645597b1a..fc7c5ccc18 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -319,7 +319,6 @@ public:
POINTS,
LINES,
LINE_STRIP,
- QUADS,
LINE_LOOP,
NUM_MODES
};
@@ -450,9 +449,9 @@ public:
void diffuseColor4ubv(const U8* c);
void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
- void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
- void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
- void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
+ void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count);
+ void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count);
+ void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
void setColorMask(bool writeColor, bool writeAlpha);
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
@@ -508,14 +507,13 @@ private:
LLColor4 mAmbientLightColor;
bool mDirty;
- U32 mQuadCycle;
U32 mCount;
U32 mMode;
U32 mCurrTextureUnitIndex;
bool mCurrColorMask[4];
LLPointer<LLVertexBuffer> mBuffer;
- LLStrider<LLVector3> mVerticesp;
+ LLStrider<LLVector4a> mVerticesp;
LLStrider<LLVector2> mTexcoordsp;
LLStrider<LLColor4U> mColorsp;
std::array<LLTexUnit, LL_NUM_TEXTURE_LAYERS> mTexUnits;
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 428370057e..20ad0275bd 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -122,10 +122,13 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, bool filled )
// Counterclockwise quad will face the viewer
if( filled )
{
- gGL.begin( LLRender::QUADS );
+ gGL.begin( LLRender::TRIANGLES );
gGL.vertex2i(left, top);
gGL.vertex2i(left, bottom);
gGL.vertex2i(right, bottom);
+
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(right, bottom);
gGL.vertex2i(right, top);
gGL.end();
}
@@ -172,50 +175,70 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st
LLColor4 end_color = start_color;
end_color.mV[VALPHA] = 0.f;
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
// Right edge, CCW faces screen
gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, top-lines);
- gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top - lines);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right + lines, bottom);
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, top - lines);
gGL.color4fv(end_color.mV);
- gGL.vertex2i(right+lines, bottom);
- gGL.vertex2i(right+lines, top-lines);
+ gGL.vertex2i(right + lines, bottom);
+ gGL.vertex2i(right + lines, top - lines);
// Bottom edge, CCW faces screen
gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(left+lines, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(left + lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left + lines, bottom - lines);
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
gGL.color4fv(end_color.mV);
- gGL.vertex2i(left+lines, bottom-lines);
- gGL.vertex2i(right, bottom-lines);
+ gGL.vertex2i(left + lines, bottom - lines);
+ gGL.vertex2i(right, bottom - lines);
// bottom left Corner
gGL.color4fv(start_color.mV);
- gGL.vertex2i(left+lines, bottom);
+ gGL.vertex2i(left + lines, bottom);
gGL.color4fv(end_color.mV);
- gGL.vertex2i(left, bottom);
+ gGL.vertex2i(left, bottom);
// make the bottom left corner not sharp
- gGL.vertex2i(left+1, bottom-lines+1);
- gGL.vertex2i(left+lines, bottom-lines);
+ gGL.vertex2i(left + 1, bottom - lines + 1);
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(left + lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left + 1, bottom - lines + 1);
+ gGL.vertex2i(left + lines, bottom - lines);
// bottom right corner
gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, bottom);
gGL.color4fv(end_color.mV);
- gGL.vertex2i(right, bottom-lines);
+ gGL.vertex2i(right, bottom - lines);
// make the rightmost corner not sharp
- gGL.vertex2i(right+lines-1, bottom-lines+1);
- gGL.vertex2i(right+lines, bottom);
+ gGL.vertex2i(right + lines - 1, bottom - lines + 1);
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right + lines - 1, bottom - lines + 1);
+ gGL.vertex2i(right + lines, bottom);
// top right corner
gGL.color4fv(start_color.mV);
- gGL.vertex2i( right, top-lines );
+ gGL.vertex2i(right, top - lines);
gGL.color4fv(end_color.mV);
- gGL.vertex2i( right+lines, top-lines );
+ gGL.vertex2i(right + lines, top - lines);
// make the corner not sharp
- gGL.vertex2i( right+lines-1, top-1 );
- gGL.vertex2i( right, top );
+ gGL.vertex2i(right + lines - 1, top - 1);
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, top - lines);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right + lines - 1, top - 1);
+ gGL.vertex2i(right, top);
gGL.end();
stop_glerror();
@@ -423,171 +446,251 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
ui_translation.mV[VX] + width * ui_scale.mV[VX],
ui_translation.mV[VY]);
- LLGLSUIDefault gls_ui;
-
gGL.getTexUnit(0)->bind(image, true);
gGL.color4fv(color.mV);
- const S32 NUM_VERTICES = 9 * 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
+ constexpr S32 NUM_VERTICES = 9 * 2 * 3; // 9 quads, 2 triangles per quad, 3 vertices per triangle
+ static thread_local LLVector2 uv[NUM_VERTICES];
+ static thread_local LLVector4a pos[NUM_VERTICES];
S32 index = 0;
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
- // draw bottom left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ // draw bottom left triangles
+ // 1
+ uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ // 2
+ uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
- // draw bottom middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ // draw bottom middle triangles
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
- // draw bottom right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ // 2
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- // draw left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ // draw bottom right triangles
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+ pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ // 2
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
index++;
- // draw middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ // draw left triangles
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- // draw right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ // 2
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
- // draw top left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ // draw middle triangles
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ // 2
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
index++;
- // draw top middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ // draw right triangles
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- // draw top right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ // 2
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
index++;
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
index++;
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw top left triangles
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // 2
+ uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+ pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top middle triangles
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // 2
+ uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top right triangles
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mTop);
+ pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // 2
+ uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mTop);
+ pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
index++;
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
@@ -614,8 +717,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
return;
}
- LLGLSUIDefault gls_ui;
-
if(image != NULL)
{
gGL.getTexUnit(0)->bind(image, true);
@@ -629,11 +730,11 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
if (degrees == 0.f)
{
- const S32 NUM_VERTICES = 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
+ constexpr S32 NUM_VERTICES = 2 * 3;
+ static thread_local LLVector2 uv[NUM_VERTICES +1];
+ static thread_local LLVector4a pos[NUM_VERTICES +1];
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
LLVector3 ui_scale = gGL.getUIScale();
LLVector3 ui_translation = gGL.getUITranslation();
@@ -644,20 +745,28 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
S32 scaled_width = ll_round(width * ui_scale.mV[VX]);
S32 scaled_height = ll_round(height * ui_scale.mV[VY]);
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+ uv[index].set(uv_rect.mRight, uv_rect.mTop);
+ pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index].set(uv_rect.mLeft, uv_rect.mTop);
+ pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index].set(uv_rect.mLeft, uv_rect.mBottom);
+ pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
index++;
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+ uv[index].set(uv_rect.mRight, uv_rect.mTop);
+ pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
index++;
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+ uv[index].set(uv_rect.mLeft, uv_rect.mBottom);
+ pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
index++;
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+ uv[index].set(uv_rect.mRight, uv_rect.mBottom);
+ pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
index++;
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
@@ -687,7 +796,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
gGL.color4fv(color.mV);
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
LLVector3 v;
@@ -703,6 +812,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
gGL.vertex2f(v.mV[0], v.mV[1] );
+ v = LLVector3(offset_x, offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+ gGL.vertex2f(v.mV[0], v.mV[1]);
+
+ v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+ gGL.vertex2f(v.mV[0], v.mV[1]);
+
v = LLVector3(offset_x, -offset_y, 0.f) * quat;
gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
gGL.vertex2f(v.mV[0], v.mV[1] );
@@ -948,7 +1065,7 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians,
void gl_rect_2d_simple_tex( S32 width, S32 height )
{
- gGL.begin( LLRender::QUADS );
+ gGL.begin( LLRender::TRIANGLES );
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2i(width, height);
@@ -959,6 +1076,12 @@ void gl_rect_2d_simple_tex( S32 width, S32 height )
gGL.texCoord2f(0.f, 0.f);
gGL.vertex2i(0, 0);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(width, height);
+
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(0, 0);
+
gGL.texCoord2f(1.f, 0.f);
gGL.vertex2i(width, 0);
@@ -967,10 +1090,13 @@ void gl_rect_2d_simple_tex( S32 width, S32 height )
void gl_rect_2d_simple( S32 width, S32 height )
{
- gGL.begin( LLRender::QUADS );
+ gGL.begin( LLRender::TRIANGLES );
gGL.vertex2i(width, height);
gGL.vertex2i(0, height);
gGL.vertex2i(0, 0);
+
+ gGL.vertex2i(width, height);
+ gGL.vertex2i(0, 0);
gGL.vertex2i(width, 0);
gGL.end();
}
@@ -1011,7 +1137,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
LLVector2 width_vec((F32)width, 0.f);
LLVector2 height_vec(0.f, (F32)height);
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
// draw bottom left
gGL.texCoord2f(0.f, 0.f);
@@ -1023,6 +1149,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2f(0.f, 0.f);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
gGL.vertex2fv(border_height_bottom.mV);
@@ -1036,6 +1168,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(border_width_left.mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((border_width_left + border_height_bottom).mV);
@@ -1049,6 +1187,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec + border_height_bottom).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((width_vec - border_width_right).mV);
+
+ gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
@@ -1062,6 +1206,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+ gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv(border_height_bottom.mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((height_vec - border_height_top).mV);
@@ -1075,6 +1225,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
@@ -1088,6 +1244,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
@@ -1101,6 +1263,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((border_width_left + height_vec).mV);
+ gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((border_width_left + height_vec).mV);
+
gGL.texCoord2f(0.f, 1.f);
gGL.vertex2fv((height_vec).mV);
@@ -1114,6 +1282,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((border_width_left + height_vec).mV);
@@ -1127,6 +1301,12 @@ void gl_segmented_rect_2d_tex(const S32 left,
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2fv((width_vec + height_vec).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2fv((width_vec + height_vec).mV);
+
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
}
@@ -1181,7 +1361,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
LLVector2 x_min;
LLVector2 x_max;
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
if (start_fragment < middle_start)
{
@@ -1200,6 +1380,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv(x_min.mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + border_height_bottom).mV);
@@ -1213,6 +1399,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
@@ -1226,6 +1418,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, 1.f);
gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
gGL.texCoord2f(u_min, 1.f);
gGL.vertex2fv((x_min + height_vec).mV);
}
@@ -1245,6 +1443,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(x_min.mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + border_height_bottom).mV);
@@ -1258,6 +1462,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
@@ -1271,6 +1481,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
gGL.vertex2fv((x_min + height_vec).mV);
}
@@ -1292,6 +1508,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv((x_min).mV);
+
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
+
gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + border_height_bottom).mV);
@@ -1305,6 +1527,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
@@ -1318,6 +1546,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
gGL.texCoord2f(u_max, 1.f);
gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
gGL.texCoord2f(u_min, 1.f);
gGL.vertex2fv((x_min + height_vec).mV);
}
@@ -1332,7 +1566,7 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::TRIANGLES);
{
// draw bottom left
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
@@ -1344,6 +1578,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3f(0.f, 0.f, 0.f);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
@@ -1357,6 +1597,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
@@ -1370,6 +1616,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
@@ -1383,6 +1635,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
@@ -1396,6 +1654,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
@@ -1409,6 +1673,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
@@ -1422,6 +1692,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop* height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft* width_vec + center_draw_rect.mTop * height_vec).mV);
+
gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((height_vec).mV);
@@ -1435,6 +1711,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft* width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mTop * height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
@@ -1448,6 +1730,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((width_vec + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mTop * height_vec).mV);
+
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((width_vec + height_vec).mV);
+
gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
}
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index 9570180554..cd8ef7d68e 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -34,6 +34,8 @@
#include "llerror.h"
#include "llglheaders.h"
+#include "llvertexbuffer.h"
+#include "llglslshader.h"
LLRenderSphere gSphere;
@@ -53,12 +55,20 @@ inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
void LLRenderSphere::renderGGL()
{
+ LL_PROFILE_ZONE_SCOPED;
S32 const LATITUDE_SLICES = 20;
S32 const LONGITUDE_SLICES = 30;
- if (mSpherePoints.empty())
+ if (mVertexBuffer.isNull())
{
mSpherePoints.resize(LATITUDE_SLICES + 1);
+ mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ mVertexBuffer->allocateBuffer((U32)(LATITUDE_SLICES + 1) * (LONGITUDE_SLICES + 1), LATITUDE_SLICES * LONGITUDE_SLICES * 6);
+
+ LLStrider<LLVector3> v;
+ mVertexBuffer->getVertexStrider(v);
+
for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
{
mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
@@ -68,24 +78,52 @@ void LLRenderSphere::renderGGL()
F32 lon = (F32)lon_i / LONGITUDE_SLICES;
mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
+ v[lat_i * (LONGITUDE_SLICES + 1) + lon_i] = mSpherePoints[lat_i][lon_i];
}
}
+
+ LLStrider<U16> i;
+ mVertexBuffer->getIndexStrider(i);
+
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
+ {
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+ {
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 0] = lat_i * (LONGITUDE_SLICES + 1) + lon_i;
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 1] = lat_i * (LONGITUDE_SLICES + 1) + lon_i + 1;
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 2] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i;
+
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 3] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i;
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 4] = lat_i * (LONGITUDE_SLICES + 1) + lon_i + 1;
+ i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 5] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i + 1;
+ }
+ }
+
+ mVertexBuffer->unmapBuffer();
}
- gGL.begin(LLRender::TRIANGLES);
- for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
- {
- for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+ if (LLGLSLShader::sCurBoundShaderPtr->mAttributeMask == LLVertexBuffer::MAP_VERTEX)
+ { // shader expects only vertex positions in vertex buffer, use fast path
+ mVertexBuffer->setBuffer();
+ mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, mVertexBuffer->getNumVerts(), mVertexBuffer->getNumIndices(), 0);
+ }
+ else
+ { //shader wants colors in the vertex stream, use slow path
+ gGL.begin(LLRender::TRIANGLES);
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
{
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+ {
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i + 1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i + 1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i + 1].mV);
+ }
}
+ gGL.end();
}
- gGL.end();
}
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index e2e886fa06..5b6eabecb8 100644
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
@@ -45,6 +45,7 @@ public:
private:
std::vector< std::vector<LLVector3> > mSpherePoints;
+ LLPointer<LLVertexBuffer> mVertexBuffer;
};
extern LLRenderSphere gSphere;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8524b470de..6f4828397a 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -289,22 +289,58 @@ static GLuint gen_buffer()
return ret;
}
-#define ANALYZE_VBO_POOL 0
+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;
-#if LL_DARWIN
+ for (S32 i = 0; i < count; ++i)
+ {
+ sFreeList[idx].push_back(buffers[i]);
+ }
+
+ idx = (LLImageGL::sFrameCount + 3) % 4;
-// experimental -- disable VBO pooling on OS X and use glMapBuffer
+ if (!sFreeList[idx].empty())
+ {
+ glDeleteBuffers((GLsizei)sFreeList[idx].size(), sFreeList[idx].data());
+ sFreeList[idx].resize(0);
+ }
+ }
+}
+
+
+#define ANALYZE_VBO_POOL 0
+
+// 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;
@@ -324,7 +360,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);
@@ -339,19 +375,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;
@@ -359,7 +393,7 @@ public:
Time mAge;
};
- ~LLVBOPool()
+ ~LLDefaultVBOPool() override
{
clear();
}
@@ -377,7 +411,7 @@ public:
U32 mMisses = 0;
U32 mHits = 0;
- U64 getVramBytesUsed()
+ U64 getVramBytesUsed() override
{
return mAllocated + mReserved;
}
@@ -393,7 +427,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);
@@ -449,7 +483,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);
@@ -512,7 +546,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();
@@ -548,7 +582,7 @@ public:
for (auto& entry : entries.second)
{
ll_aligned_free_16(entry.mData);
- glDeleteBuffers(1, &entry.mGLName);
+ delete_buffers(1, &entry.mGLName);
}
}
@@ -557,7 +591,7 @@ public:
for (auto& entry : entries.second)
{
ll_aligned_free_16(entry.mData);
- glDeleteBuffers(1, &entry.mGLName);
+ delete_buffers(1, &entry.mGLName);
}
}
@@ -567,7 +601,6 @@ public:
mVBOPool.clear();
}
};
-#endif
static LLVBOPool* sVBOPool = nullptr;
@@ -600,15 +633,7 @@ void LLVertexBufferData::draw()
gGL.loadMatrix(glm::value_ptr(mTexture0));
mVB->setBuffer();
-
- if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
- {
- mVB->drawArrays(LLRender::TRIANGLES, 0, mCount);
- }
- else
- {
- mVB->drawArrays(mMode, 0, mCount);
- }
+ mVB->drawArrays(mMode, 0, mCount);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -681,7 +706,6 @@ const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
GL_POINTS,
GL_LINES,
GL_LINE_STRIP,
- GL_QUADS,
GL_LINE_LOOP,
};
@@ -896,7 +920,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();
@@ -964,7 +997,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();
@@ -1231,28 +1263,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;
}
@@ -1267,28 +1300,29 @@ 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;
}
@@ -1301,34 +1335,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
- 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);
-
- constexpr U32 block_size = 65536;
+ // 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);
- 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()
@@ -1338,8 +1378,6 @@ void LLVertexBuffer::unmapBuffer()
void LLVertexBuffer::_mapBuffer()
{
- // must only be called from main thread
- llassert(LLCoros::on_main_thread_main_coro());
if (!mMapped)
{
mMapped = true;
@@ -1363,114 +1401,116 @@ void LLVertexBuffer::_unmapBuffer()
}
};
-#if LL_DARWIN
- STOP_GLERROR;
- if (mMappedData)
- {
- if (mGLBuffer)
- {
- glDeleteBuffers(1, &mGLBuffer);
- }
- mGLBuffer = gen_buffer();
- glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
- sGLRenderBuffer = mGLBuffer;
- glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW);
- }
- else if (mGLBuffer != sGLRenderBuffer)
+ if (gGLManager.mIsApple)
{
- glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
- sGLRenderBuffer = mGLBuffer;
- }
- STOP_GLERROR;
-
- if (mMappedIndexData)
- {
- if (mGLIndices)
+ STOP_GLERROR;
+ if (mMappedData)
{
- glDeleteBuffers(1, &mGLIndices);
+ 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);
}
-
- 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;
+ delete_buffers(1, &mGLIndices);
}
- 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();
- }
-
- if (!mMappedIndexRegions.empty())
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index");
+ mGLIndices = gen_buffer();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
+ sGLRenderIndices = mGLIndices;
- if (mGLIndices != sGLRenderIndices)
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW);
+ }
+ else if (mGLIndices != sGLRenderIndices)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
}
- U32 start = 0;
- U32 end = 0;
+ STOP_GLERROR;
+ }
+ else
+ {
+ if (!mMappedVertexRegions.empty())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex");
- std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion());
+ if (sGLRenderBuffer != mGLBuffer)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
+ sGLRenderBuffer = mGLBuffer;
+ }
- for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
+ U32 start = 0;
+ U32 end = 0;
+
+ std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion());
+
+ for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
+ {
+ 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();
+ }
+
+ if (!mMappedIndexRegions.empty())
{
- const MappedRegion& region = mMappedIndexRegions[i];
- if (region.mStart == end + 1)
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index");
+
+ if (mGLIndices != sGLRenderIndices)
{
- end = region.mEnd;
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
+ sGLRenderIndices = mGLIndices;
}
- else
+ U32 start = 0;
+ U32 end = 0;
+
+ std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion());
+
+ for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
- flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
- start = region.mStart;
- end = region.mEnd;
+ 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();
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData);
+ mMappedIndexRegions.clear();
+ }
}
-#endif
}
//----------------------------------------------------------------------------
@@ -1592,12 +1632,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 in
void LLVertexBuffer::setBuffer()
{
STOP_GLERROR;
-#if LL_DARWIN
- if (!mGLBuffer)
- { // OS X doesn't allocate a buffer until we call unmapBuffer
- return;
- }
-#endif
if (mMapped)
{