summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontgl.cpp96
-rw-r--r--indra/llrender/llfontgl.h9
-rw-r--r--indra/llrender/llglslshader.cpp21
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llshadermgr.cpp5
-rw-r--r--indra/llrender/llvertexbuffer.cpp286
-rw-r--r--indra/llrender/llvertexbuffer.h58
7 files changed, 229 insertions, 247 deletions
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 82e8227ffe..fccbf37a8d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -56,8 +56,9 @@ std::string LLFontGL::sAppDir;
LLColor4 LLFontGL::sShadowColor(0.f, 0.f, 0.f, 1.f);
LLFontRegistry* LLFontGL::sFontRegistry = NULL;
-LLCoordFont LLFontGL::sCurOrigin;
-std::vector<LLCoordFont> LLFontGL::sOriginStack;
+LLCoordGL LLFontGL::sCurOrigin;
+F32 LLFontGL::sCurDepth;
+std::vector<std::pair<LLCoordGL, F32> > LLFontGL::sOriginStack;
const F32 EXT_X_BEARING = 1.f;
const F32 EXT_Y_BEARING = 0.f;
@@ -68,20 +69,6 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
-static F32 llfont_round_x(F32 x)
-{
- //return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
- //return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
- return x;
-}
-
-static F32 llfont_round_y(F32 y)
-{
- //return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
- //return llfloor(y+0.5f);
- return y;
-}
-
LLFontGL::LLFontGL()
{
}
@@ -115,23 +102,23 @@ static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
{
- F32 x = rect.mLeft;
+ F32 x = (F32)rect.mLeft;
F32 y = 0.f;
switch(valign)
{
case TOP:
- y = rect.mTop;
+ y = (F32)rect.mTop;
break;
case VCENTER:
- y = rect.getCenterY();
+ y = (F32)rect.getCenterY();
break;
case BASELINE:
case BOTTOM:
- y = rect.mBottom;
+ y = (F32)rect.mBottom;
break;
default:
- y = rect.mBottom;
+ y = (F32)rect.mBottom;
break;
}
return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses);
@@ -177,21 +164,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
gGL.loadUIIdentity();
- //gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);
-
- // this code snaps the text origin to a pixel grid to start with
- //F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
- //F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
- //gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f);
-
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
- // snap the text origin to a pixel grid to start with
- origin.mV[VX] -= llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
- origin.mV[VY] -= llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
- // Depth translation, so that floating text appears 'inworld'
- // and is correclty occluded.
- gGL.translatef(0.f,0.f,sCurOrigin.mZ);
+ // Depth translation, so that floating text appears 'in-world'
+ // and is correctly occluded.
+ gGL.translatef(0.f,0.f,sCurDepth);
S32 chars_drawn = 0;
S32 i;
@@ -215,16 +192,17 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_y = ((F32)y * sScaleY) + origin.mV[VY];
// Offset y by vertical alignment.
+ // use unscaled font metrics here
switch (valign)
{
case TOP:
- cur_y -= mFontFreetype->getAscenderHeight();
+ cur_y -= llceil(mFontFreetype->getAscenderHeight());
break;
case BOTTOM:
- cur_y += mFontFreetype->getDescenderHeight();
+ cur_y += llceil(mFontFreetype->getDescenderHeight());
break;
case VCENTER:
- cur_y -= (mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight()) / 2.f;
+ cur_y -= llceil((llceil(mFontFreetype->getAscenderHeight()) - llceil(mFontFreetype->getDescenderHeight())) / 2.f);
break;
case BASELINE:
// Baseline, do nothing.
@@ -250,7 +228,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_render_y = cur_y;
cur_render_x = cur_x;
- F32 start_x = llround(cur_x);
+ F32 start_x = (F32)llround(cur_x);
const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
@@ -334,10 +312,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
(fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
// snap glyph origin to whole screen pixel
- LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
- llround(cur_render_y + (F32)fgi->mYBearing),
- llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
- llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
+ LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
+ (F32)llround(cur_render_y + (F32)fgi->mYBearing),
+ (F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
+ (F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
if (glyph_count >= GLYPH_BATCH_SIZE)
{
@@ -390,12 +368,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
//FIXME: add underline as glyph?
if (style_to_add & UNDERLINE)
{
- F32 descender = mFontFreetype->getDescenderHeight();
+ F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin(LLRender::LINES);
- gGL.vertex2f(start_x, cur_y - (descender));
- gGL.vertex2f(cur_x, cur_y - (descender));
+ gGL.vertex2f(start_x, cur_y - descender);
+ gGL.vertex2f(cur_x, cur_y - descender);
gGL.end();
}
@@ -444,19 +422,9 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
}
// font metrics - override for LLFontFreetype that returns units of virtual pixels
-F32 LLFontGL::getLineHeight() const
+S32 LLFontGL::getLineHeight() const
{
- return (F32)llround(mFontFreetype->getLineHeight() / sScaleY);
-}
-
-F32 LLFontGL::getAscenderHeight() const
-{
- return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY);
-}
-
-F32 LLFontGL::getDescenderHeight() const
-{
- return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY);
+ return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
}
S32 LLFontGL::getWidth(const std::string& utf8text) const
@@ -645,7 +613,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
}
// Round after kerning.
- cur_x = llround(cur_x);
+ cur_x = (F32)llround(cur_x);
drawn_x = cur_x;
}
@@ -716,7 +684,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
}
// Round after kerning.
- total_width = llround(total_width);
+ total_width = (F32)llround(total_width);
}
if (drawable_chars == 0)
@@ -799,7 +767,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
// Round after kerning.
- cur_x = llround(cur_x);
+ cur_x = (F32)llround(cur_x);
}
return llmin(max_chars, pos - begin_offset);
@@ -1146,22 +1114,22 @@ void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* c
{
S32 index = 0;
- vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop), 0.f);
+ vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop), 0.f);
+ vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mBottom), 0.f);
+ vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
colors_out[index] = color;
index++;
- vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mBottom), 0.f);
+ vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
colors_out[index] = color;
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index dc8d848ed2..74bdbb43e7 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -115,9 +115,7 @@ public:
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
// font metrics - override for LLFontFreetype that returns units of virtual pixels
- F32 getLineHeight() const;
- F32 getAscenderHeight() const;
- F32 getDescenderHeight() const;
+ S32 getLineHeight() const;
S32 getWidth(const std::string& utf8text) const;
S32 getWidth(const llwchar* wchars) const;
@@ -188,8 +186,9 @@ public:
static std::string getFontPathLocal();
static std::string getFontPathSystem();
- static LLCoordFont sCurOrigin;
- static std::vector<LLCoordFont> sOriginStack;
+ static LLCoordGL sCurOrigin;
+ static F32 sCurDepth;
+ static std::vector<std::pair<LLCoordGL, F32> > sOriginStack;
static LLColor4 sShadowColor;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 6b2852670a..3773568ad8 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -64,10 +64,23 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
}
LLShaderFeatures::LLShaderFeatures()
-: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
-hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
-hasGamma(false), hasLighting(false), isAlphaLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
-hasAlphaMask(false)
+ : atmosphericHelpers(false)
+ , calculatesLighting(false)
+ , calculatesAtmospherics(false)
+ , hasLighting(false)
+ , isAlphaLighting(false)
+ , isShiny(false)
+ , isFullbright(false)
+ , isSpecular(false)
+ , hasWaterFog(false)
+ , hasTransport(false)
+ , hasSkinning(false)
+ , hasObjectSkinning(false)
+ , hasAtmospherics(false)
+ , hasGamma(false)
+ , mIndexedTextureChannels(0)
+ , disableTextureIndex(false)
+ , hasAlphaMask(false)
{
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 00b4b0dbd4..7873fe3c4e 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -33,6 +33,7 @@
class LLShaderFeatures
{
public:
+ bool atmosphericHelpers;
bool calculatesLighting;
bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 1a03aeebb7..908443e8cf 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -94,13 +94,16 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
- if (features->calculatesLighting)
+ if (features->calculatesLighting || features->atmosphericHelpers)
{
if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
{
return FALSE;
}
+ }
+ if (features->calculatesLighting)
+ {
if (features->isSpecular)
{
if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index eb302392bb..e4a5cd0299 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -53,31 +53,31 @@ U32 nhpo2(U32 v)
//============================================================================
//static
-LLVBOPool LLVertexBuffer::sStreamVBOPool;
-LLVBOPool LLVertexBuffer::sDynamicVBOPool;
-LLVBOPool LLVertexBuffer::sStreamIBOPool;
-LLVBOPool LLVertexBuffer::sDynamicIBOPool;
+LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
U32 LLVBOPool::sBytesPooled = 0;
-LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
+LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
S32 LLVertexBuffer::sGLCount = 0;
S32 LLVertexBuffer::sMappedCount = 0;
-BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
-BOOL LLVertexBuffer::sEnableVBOs = TRUE;
+bool LLVertexBuffer::sDisableVBOMapping = false;
+bool LLVertexBuffer::sEnableVBOs = true;
U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderArray = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0;
U32 LLVertexBuffer::sLastMask = 0;
-BOOL LLVertexBuffer::sVBOActive = FALSE;
-BOOL LLVertexBuffer::sIBOActive = FALSE;
+bool LLVertexBuffer::sVBOActive = false;
+bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0;
-BOOL LLVertexBuffer::sMapped = FALSE;
-BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
-BOOL LLVertexBuffer::sUseVAO = FALSE;
-BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
+bool LLVertexBuffer::sMapped = false;
+bool LLVertexBuffer::sUseStreamDraw = true;
+bool LLVertexBuffer::sUseVAO = false;
+bool LLVertexBuffer::sPreferStreamDraw = false;
const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
@@ -204,15 +204,14 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
Record rec;
rec.mGLName = name;
rec.mClientData = buffer;
-
- sBytesPooled += size;
- if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
+ if (buffer == NULL)
{
glDeleteBuffersARB(1, &rec.mGLName);
}
else
{
+ sBytesPooled += size;
mFreeList[i].push_back(rec);
}
}
@@ -283,7 +282,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (sLastMask != data_mask)
{
- BOOL error = FALSE;
+ bool error = false;
if (LLGLSLShader::sNoFixedFunction)
{
@@ -344,7 +343,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
}
else
@@ -364,7 +363,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
@@ -430,7 +429,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
U32 count = pos.size();
llassert_always(norm.size() >= pos.size());
- llassert_always(count > 0) ;
+ llassert_always(count > 0);
unbind();
@@ -548,7 +547,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
validateRange(start, end, count, indices_offset);
- mMappable = FALSE;
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -603,7 +602,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- mMappable = FALSE;
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumIndices >= 0);
@@ -649,7 +648,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- mMappable = FALSE;
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -689,23 +688,13 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
//static
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
- sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
- sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
+ sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
+ sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
- if(!sPrivatePoolp)
+ if (!sPrivatePoolp)
{
- sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
+ sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
}
-
- sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB;
- sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB;
- sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
- sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB;
-
- sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB;
- sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
- sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
- sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
}
//static
@@ -718,18 +707,18 @@ void LLVertexBuffer::unbind()
#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
if (sVBOActive)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- sVBOActive = FALSE;
+ sVBOActive = false;
}
if (sIBOActive)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- sIBOActive = FALSE;
+ sIBOActive = false;
}
sGLRenderBuffer = 0;
@@ -751,73 +740,80 @@ void LLVertexBuffer::cleanupClass()
if(sPrivatePoolp)
{
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
- sPrivatePoolp = NULL ;
+ LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp);
+ sPrivatePoolp = NULL;
}
}
//----------------------------------------------------------------------------
-LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
- LLRefCount(),
-
- mNumVerts(0),
- mNumIndices(0),
- mUsage(usage),
- mGLBuffer(0),
- mGLArray(0),
- mGLIndices(0),
- mMappedData(NULL),
- mMappedIndexData(NULL),
- mVertexLocked(FALSE),
- mIndexLocked(FALSE),
- mFinal(FALSE),
- mEmpty(TRUE),
- mFence(NULL)
+S32 LLVertexBuffer::determineUsage(S32 usage)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
- mFence = NULL;
+ S32 ret_usage = usage;
+
if (!sEnableVBOs)
{
- mUsage = 0 ;
+ ret_usage = 0;
}
-
- if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+
+ if (ret_usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{
- mUsage = 0;
+ ret_usage = 0;
}
- if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
+ if (ret_usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
{
- mUsage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW_ARB;
}
-
- if (mUsage == 0 && LLRender::sGLCoreProfile)
+
+ if (ret_usage == 0 && LLRender::sGLCoreProfile)
{ //MUST use VBOs for all rendering
- mUsage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW_ARB;
}
-
- if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
+
+ if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
- mUsage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW_ARB;
}
else
{
- mUsage = GL_DYNAMIC_DRAW_ARB;
+ ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
+ return ret_usage;
+}
- if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
- {
- mMappable = TRUE;
- }
- else
- {
- mMappable = FALSE;
- }
+LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
+ LLRefCount(),
+
+ mNumVerts(0),
+ mNumIndices(0),
+ mAlignedOffset(0),
+ mAlignedIndexOffset(0),
+ mSize(0),
+ mIndicesSize(0),
+ mTypeMask(typemask),
+ mUsage(LLVertexBuffer::determineUsage(usage)),
+ mGLBuffer(0),
+ mGLIndices(0),
+ mGLArray(0),
+ mMappedData(NULL),
+ mMappedIndexData(NULL),
+ mMappedDataUsingVBOs(false),
+ mMappedIndexDataUsingVBOs(false),
+ mVertexLocked(false),
+ mIndexLocked(false),
+ mFinal(false),
+ mEmpty(true),
+ mMappable(false),
+ mFence(NULL)
+{
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
+
+ mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
@@ -825,12 +821,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mOffsets[i] = 0;
}
- mTypeMask = typemask;
- mSize = 0;
- mIndicesSize = 0;
- mAlignedOffset = 0;
- mAlignedIndexOffset = 0;
-
sCount++;
}
@@ -902,7 +892,7 @@ LLVertexBuffer::~LLVertexBuffer()
mFence = NULL;
- llassert_always(!mMappedData && !mMappedIndexData) ;
+ llassert_always(!mMappedData && !mMappedIndexData);
};
void LLVertexBuffer::placeFence() const
@@ -1011,9 +1001,11 @@ void LLVertexBuffer::createGLBuffer(U32 size)
return;
}
- mEmpty = TRUE;
+ mEmpty = true;
- if (useVBOs())
+ mMappedDataUsingVBOs = useVBOs();
+
+ if (mMappedDataUsingVBOs)
{
genBuffer(size);
}
@@ -1040,12 +1032,14 @@ void LLVertexBuffer::createGLIndices(U32 size)
return;
}
- mEmpty = TRUE;
+ mEmpty = true;
//pad by 16 bytes for aligned copies
size += 16;
- if (useVBOs())
+ mMappedIndexDataUsingVBOs = useVBOs();
+
+ if (mMappedIndexDataUsingVBOs)
{
//pad by another 16 bytes for VBO pointer adjustment
size += 16;
@@ -1065,15 +1059,15 @@ void LLVertexBuffer::destroyGLBuffer()
LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
if (mGLBuffer)
{
- if (useVBOs())
+ if (mMappedDataUsingVBOs)
{
releaseBuffer();
}
else
{
- FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedData);
mMappedData = NULL;
- mEmpty = TRUE;
+ mEmpty = true;
}
}
@@ -1086,15 +1080,15 @@ void LLVertexBuffer::destroyGLIndices()
LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
if (mGLIndices)
{
- if (useVBOs())
+ if (mMappedIndexDataUsingVBOs)
{
releaseIndices();
}
else
{
- FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
mMappedIndexData = NULL;
- mEmpty = TRUE;
+ mEmpty = true;
}
}
@@ -1279,16 +1273,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
}
}
-BOOL LLVertexBuffer::useVBOs() const
+bool LLVertexBuffer::useVBOs() const
{
//it's generally ineffective to use VBO for things that are streaming on apple
-
- if (!mUsage)
- {
- return FALSE;
- }
-
- return TRUE;
+ return (mUsage != 0);
}
//----------------------------------------------------------------------------
@@ -1368,7 +1356,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (!mVertexLocked)
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
- mVertexLocked = TRUE;
+ mVertexLocked = true;
sMappedCount++;
stop_glerror();
@@ -1447,17 +1435,17 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
{
log_glerror();
- //check the availability of memory
- LLMemory::logMemoryInfo(TRUE) ;
+ //check the availability of memory
+ LLMemory::logMemoryInfo(true);
if(mMappable)
{
//--------------------
//print out more debug info before crash
- llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
- GLint size ;
- glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
- llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
+ llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl;
+ GLint size;
+ glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl;
//--------------------
GLint buff;
@@ -1472,7 +1460,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
else
{
- llerrs << "memory allocation for vertex data failed." << llendl ;
+ llerrs << "memory allocation for vertex data failed." << llendl;
}
}
}
@@ -1547,7 +1535,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
- mIndexLocked = TRUE;
+ mIndexLocked = true;
sMappedCount++;
stop_glerror();
@@ -1626,7 +1614,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (!mMappedIndexData)
{
log_glerror();
- LLMemory::logMemoryInfo(TRUE) ;
+ LLMemory::logMemoryInfo(true);
if(mMappable)
{
@@ -1641,7 +1629,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
- llerrs << "memory allocation for Index data failed. " << llendl ;
+ llerrs << "memory allocation for Index data failed. " << llendl;
}
}
}
@@ -1672,10 +1660,10 @@ void LLVertexBuffer::unmapBuffer()
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (!useVBOs())
{
- return ; //nothing to unmap
+ return; //nothing to unmap
}
- bool updated_all = false ;
+ bool updated_all = false;
if (mMappedData && mVertexLocked)
{
@@ -1742,7 +1730,7 @@ void LLVertexBuffer::unmapBuffer()
mMappedData = NULL;
}
- mVertexLocked = FALSE ;
+ mVertexLocked = false;
sMappedCount--;
}
@@ -1806,16 +1794,16 @@ void LLVertexBuffer::unmapBuffer()
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
- mMappedIndexData = NULL ;
+ mMappedIndexData = NULL;
}
- mIndexLocked = FALSE ;
+ mIndexLocked = false;
sMappedCount--;
}
if(updated_all)
{
- mEmpty = FALSE;
+ mEmpty = false;
}
}
@@ -1835,12 +1823,12 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL)
{
llwarns << "mapIndexBuffer failed!" << llendl;
- return FALSE;
+ return false;
}
strider = (T*)ptr;
strider.setStride(0);
- return TRUE;
+ return true;
}
else if (vbo.hasDataType(type))
{
@@ -1851,18 +1839,18 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL)
{
llwarns << "mapVertexBuffer failed!" << llendl;
- return FALSE;
+ return false;
}
strider = (T*)ptr;
strider.setStride(stride);
- return TRUE;
+ return true;
}
else
{
llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
}
- return FALSE;
+ return false;
}
};
@@ -1961,7 +1949,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
- sVBOActive = TRUE;
+ sVBOActive = true;
if (mGLArray)
{
@@ -1993,7 +1981,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
sGLRenderIndices = mGLIndices;
stop_glerror();
sBindCount++;
- sIBOActive = TRUE;
+ sIBOActive = true;
ret = true;
}
@@ -2015,7 +2003,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
- BOOL setup = (sLastMask != data_mask);
+ bool setup = (sLastMask != data_mask);
if (gDebugGL && data_mask != 0)
{ //make sure data requirements are fulfilled
@@ -2049,21 +2037,17 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (mGLArray)
{
bindGLArray();
- setup = FALSE; //do NOT perform pointer setup if using VAO
+ setup = false; //do NOT perform pointer setup if using VAO
}
else
{
- if (bindGLBuffer())
- {
- setup = TRUE;
- }
- if (bindGLIndices())
- {
- setup = TRUE;
- }
+ const bool bindBuffer = bindGLBuffer();
+ const bool bindIndices = bindGLIndices();
+
+ setup = setup || bindBuffer || bindIndices;
}
- BOOL error = FALSE;
+ bool error = false;
if (gDebugGL && !mGLArray)
{
GLint buff;
@@ -2072,7 +2056,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
}
else
@@ -2088,7 +2072,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
}
else
@@ -2110,7 +2094,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
if (mGLBuffer)
@@ -2119,13 +2103,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
sBindCount++;
- sVBOActive = FALSE;
- setup = TRUE; // ... or a VBO is deactivated
+ sVBOActive = false;
+ setup = true; // ... or a VBO is deactivated
}
if (sGLRenderBuffer != mGLBuffer)
{
sGLRenderBuffer = mGLBuffer;
- setup = TRUE; // ... or a client memory pointer changed
+ setup = true; // ... or a client memory pointer changed
}
}
if (mGLIndices)
@@ -2134,7 +2118,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
sBindCount++;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
sGLRenderIndices = mGLIndices;
@@ -2222,19 +2206,19 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
}
if (data_mask & MAP_WEIGHT4)
{
S32 loc = TYPE_WEIGHT4;
void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
}
if (data_mask & MAP_CLOTHWEIGHT)
{
S32 loc = TYPE_CLOTHWEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
}
if (data_mask & MAP_TEXTURE_INDEX)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index e1cbfd3b61..d859199663 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,9 +55,14 @@ class LLVBOPool
{
public:
static U32 sBytesPooled;
+
+ LLVBOPool(U32 vboUsage, U32 vboType)
+ : mUsage(vboUsage)
+ , mType(vboType)
+ {}
- U32 mUsage;
- U32 mType;
+ const U32 mUsage;
+ const U32 mType;
//size MUST be a power of 2
volatile U8* allocate(U32& name, U32 size);
@@ -88,7 +93,7 @@ public:
//============================================================================
// base class
-class LLPrivateMemoryPool ;
+class LLPrivateMemoryPool;
class LLVertexBuffer : public LLRefCount
{
public:
@@ -103,6 +108,7 @@ public:
};
LLVertexBuffer(const LLVertexBuffer& rhs)
+ : mUsage(rhs.mUsage)
{
*this = rhs;
}
@@ -118,9 +124,9 @@ public:
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
- static BOOL sUseStreamDraw;
- static BOOL sUseVAO;
- static BOOL sPreferStreamDraw;
+ static bool sUseStreamDraw;
+ static bool sUseVAO;
+ static bool sPreferStreamDraw;
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
@@ -201,7 +207,7 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
- virtual BOOL useVBOs() const;
+ bool useVBOs() const;
void unmapBuffer();
public:
@@ -239,8 +245,8 @@ public:
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
- BOOL isEmpty() const { return mEmpty; }
- BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
+ bool isEmpty() const { return mEmpty; }
+ bool isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
@@ -254,7 +260,7 @@ public:
volatile U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
- BOOL isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; }
+ bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -274,18 +280,25 @@ protected:
S32 mSize;
S32 mIndicesSize;
U32 mTypeMask;
- S32 mUsage; // GL usage
+
+ const S32 mUsage; // GL usage
+
U32 mGLBuffer; // GL VBO handle
U32 mGLIndices; // GL IBO handle
U32 mGLArray; // GL VAO handle
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
- BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
- BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
- BOOL mFinal; // if TRUE, buffer can not be mapped again
- BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
- mutable BOOL mMappable; // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
+
+ U32 mMappedDataUsingVBOs : 1;
+ U32 mMappedIndexDataUsingVBOs : 1;
+ U32 mVertexLocked : 1; // if true, vertex buffer is being or has been written to in client memory
+ U32 mIndexLocked : 1; // if true, index buffer is being or has been written to in client memory
+ U32 mFinal : 1; // if true, buffer can not be mapped again
+ U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded.
+
+ mutable bool mMappable; // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
+
S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions;
@@ -296,26 +309,27 @@ protected:
void placeFence() const;
void waitFence() const;
+ static S32 determineUsage(S32 usage);
private:
- static LLPrivateMemoryPool* sPrivatePoolp ;
+ static LLPrivateMemoryPool* sPrivatePoolp;
public:
static S32 sCount;
static S32 sGLCount;
static S32 sMappedCount;
- static BOOL sMapped;
+ static bool sMapped;
typedef std::list<LLVertexBuffer*> buffer_list_t;
- static BOOL sDisableVBOMapping; //disable glMapBufferARB
- static BOOL sEnableVBOs;
+ static bool sDisableVBOMapping; //disable glMapBufferARB
+ static bool sEnableVBOs;
static S32 sTypeSize[TYPE_MAX];
static U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer;
static U32 sGLRenderArray;
static U32 sGLRenderIndices;
- static BOOL sVBOActive;
- static BOOL sIBOActive;
+ static bool sVBOActive;
+ static bool sIBOActive;
static U32 sLastMask;
static U32 sAllocatedBytes;
static U32 sBindCount;