summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontgl.cpp21
-rw-r--r--indra/llrender/llfontgl.h8
-rw-r--r--indra/llrender/llgl.cpp37
-rw-r--r--indra/llrender/llglstates.h2
-rw-r--r--indra/llrender/llimagegl.cpp84
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llrender/llrender.cpp2
-rw-r--r--indra/llrender/llvertexbuffer.cpp42
8 files changed, 143 insertions, 55 deletions
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 37a28ac721..1de1d6ded4 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -472,7 +472,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
}
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
-S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary) const
+S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -562,9 +562,24 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
drawn_x = cur_x;
}
- if( clip && end_on_word_boundary && (start_of_last_word != 0) )
+ if( clip )
{
- i = start_of_last_word;
+ switch (end_on_word_boundary)
+ {
+ case ONLY_WORD_BOUNDARIES:
+ i = start_of_last_word;
+ break;
+ case WORD_BOUNDARY_IF_POSSIBLE:
+ if (start_of_last_word != 0)
+ {
+ i = start_of_last_word;
+ }
+ break;
+ default:
+ case ANYWHERE:
+ // do nothing
+ break;
+ }
}
return i;
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index ea8eee7690..dfa4cf8ce5 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -122,7 +122,13 @@ public:
// The following are called often, frequently with large buffers, so do not use a string interface
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
- S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE) const;
+ typedef enum e_word_wrap_style
+ {
+ ONLY_WORD_BOUNDARIES,
+ WORD_BOUNDARY_IF_POSSIBLE,
+ ANYWHERE
+ } EWordWrapStyle ;
+ S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, EWordWrapStyle end_on_word_boundary = ANYWHERE) const;
// Returns the index of the first complete characters from text that can be drawn in max_pixels
// given that the character at start_pos should be the last character (or as close to last as possible).
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 3400a72385..187a9a984e 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1919,6 +1919,16 @@ LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, G
: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
{
stop_glerror();
+
+ checkState();
+
+ if (!depth_enabled)
+ { // always disable depth writes if depth testing is disabled
+ // GL spec defines this as a requirement, but some implementations allow depth writes with testing disabled
+ // The proper way to write to depth buffer with testing disabled is to enable testing and use a depth_func of GL_ALWAYS
+ write_enabled = FALSE;
+ }
+
if (depth_enabled != sDepthEnabled)
{
gGL.flush();
@@ -1942,6 +1952,7 @@ LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, G
LLGLDepthTest::~LLGLDepthTest()
{
+ checkState();
if (sDepthEnabled != mPrevDepthEnabled )
{
gGL.flush();
@@ -1963,6 +1974,32 @@ LLGLDepthTest::~LLGLDepthTest()
}
}
+void LLGLDepthTest::checkState()
+{
+ if (gDebugGL)
+ {
+ GLint func = 0;
+ GLboolean mask = FALSE;
+
+ glGetIntegerv(GL_DEPTH_FUNC, &func);
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &mask);
+
+ if (glIsEnabled(GL_DEPTH_TEST) != sDepthEnabled ||
+ sWriteEnabled != mask ||
+ sDepthFunc != func)
+ {
+ if (gDebugSession)
+ {
+ gFailLog << "Unexpected depth testing state." << std::endl;
+ }
+ else
+ {
+ LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL;
+ }
+ }
+ }
+}
+
LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P)
{
for (U32 i = 0; i < 4; i++)
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 4a51cac438..968a37cab0 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -46,6 +46,8 @@ public:
~LLGLDepthTest();
+ void checkState();
+
GLboolean mPrevDepthEnabled;
GLenum mPrevDepthFunc;
GLboolean mPrevWriteEnabled;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index f8d7ea00e0..cd493481d5 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -428,49 +428,56 @@ LLImageGL::~LLImageGL()
void LLImageGL::init(BOOL usemipmaps)
{
-#ifdef DEBUG_MISS
- mMissed = FALSE;
-#endif
+ // keep these members in the same order as declared in llimagehl.h
+ // so that it is obvious by visual inspection if we forgot to
+ // init a field.
+
+ mTextureMemory = 0;
+ mLastBindTime = 0.f;
+
+ mPickMask = NULL;
+ mUseMipMaps = usemipmaps;
+ mHasExplicitFormat = FALSE;
+ mAutoGenMips = FALSE;
+
+ mIsMask = FALSE;
+ mNeedsAlphaAndPickMask = TRUE ;
+ mAlphaStride = 0 ;
+ mAlphaOffset = 0 ;
- mPickMask = NULL;
- mTextureMemory = 0;
- mLastBindTime = 0.f;
+ mGLTextureCreated = FALSE ;
+ mTexName = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mCurrentDiscardLevel = -1;
+
+ mDiscardLevelInAtlas = -1 ;
+ mTexelsInAtlas = 0 ;
+ mTexelsInGLTexture = 0 ;
- mTarget = GL_TEXTURE_2D;
- mBindTarget = LLTexUnit::TT_TEXTURE;
- mUseMipMaps = usemipmaps;
- mHasMipMaps = false;
- mAutoGenMips = FALSE;
- mTexName = 0;
- mIsResident = 0;
+ mTarget = GL_TEXTURE_2D;
+ mBindTarget = LLTexUnit::TT_TEXTURE;
+ mHasMipMaps = false;
+
+ mIsResident = 0;
+
+ mComponents = 0;
+ mMaxDiscardLevel = MAX_DISCARD_LEVEL;
mTexOptionsDirty = true;
mAddressMode = LLTexUnit::TAM_WRAP;
mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
- mWidth = 0;
- mHeight = 0;
- mComponents = 0;
-
- mMaxDiscardLevel = MAX_DISCARD_LEVEL;
- mCurrentDiscardLevel = -1;
mFormatInternal = -1;
mFormatPrimary = (LLGLenum) 0;
mFormatType = GL_UNSIGNED_BYTE;
mFormatSwapBytes = FALSE;
- mHasExplicitFormat = FALSE;
-
- mGLTextureCreated = FALSE ;
- mIsMask = FALSE;
- mCategory = -1 ;
- mAlphaStride = 0 ;
- mAlphaOffset = 0 ;
- mNeedsAlphaAndPickMask = TRUE ;
+#ifdef DEBUG_MISS
+ mMissed = FALSE;
+#endif
- mDiscardLevelInAtlas = -1 ;
- mTexelsInAtlas = 0 ;
- mTexelsInGLTexture = 0 ;
+ mCategory = -1;
}
void LLImageGL::cleanup()
@@ -1669,7 +1676,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
}
if (mFormatType != GL_UNSIGNED_BYTE ||
- mFormatPrimary != GL_RGBA)
+ mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
delete [] mPickMask;
@@ -1729,12 +1736,25 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
if (u < 0.f || u > 1.f ||
v < 0.f || v > 1.f)
{
- llerrs << "WTF?" << llendl;
+ LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
+ u = v = 0.f;
+ llassert(false);
}
S32 x = (S32)(u * width);
S32 y = (S32)(v * height);
+ if (x >= width)
+ {
+ LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
+ x = llmax(0, width-1);
+ }
+ if (y >= height)
+ {
+ LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
+ y = llmax(0, height-1);
+ }
+
S32 idx = y*width+x;
S32 offset = idx%8;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 937065043c..facfb7bd62 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -224,7 +224,7 @@ protected:
bool mTexOptionsDirty;
LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP
- LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR
+ LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_ANISOTROPIC
LLGLint mFormatInternal; // = GL internalformat
LLGLenum mFormatPrimary; // = GL format (pixel data format)
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index fc45df8153..f97d81126e 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -162,6 +162,8 @@ void LLTexUnit::enable(eTextureType type)
disable(); // Force a disable of a previous texture type if it's enabled.
}
mCurrTexType = type;
+
+ gGL.flush();
glEnable(sGLTextureType[type]);
}
}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index db4189dfea..572ae13909 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -1061,17 +1061,20 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLIndices)
+ if (mGLIndices)
{
- if (gDebugSession)
- {
- error = TRUE;
- gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
- }
- else
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
}
@@ -1095,17 +1098,20 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLIndices)
+ if (mGLIndices != 0)
{
- if (gDebugSession)
- {
- error = TRUE;
- gFailLog << "Invalid GL index buffer bound: "<< std::endl;
- }
- else
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLIndices)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Invalid GL index buffer bound: "<< std::endl;
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
}
}
}