summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontfreetype.cpp64
-rw-r--r--indra/llrender/llfontfreetype.h2
-rw-r--r--indra/llrender/llfontregistry.cpp2
-rw-r--r--indra/llrender/llgl.cpp1
-rw-r--r--indra/llrender/llglslshader.cpp34
-rw-r--r--indra/llrender/llimagegl.cpp40
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llrender/llrender.cpp61
-rw-r--r--indra/llrender/llshadermgr.cpp201
-rw-r--r--indra/llrender/llvertexbuffer.cpp23
10 files changed, 283 insertions, 147 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index de26d19efc..5c1f4ff8b3 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -106,6 +106,8 @@ LLFontFreetype::LLFontFreetype()
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
+ pFontBuffer(NULL),
+ mBufferSize(0),
mIsFallback(FALSE),
mFTFace(NULL),
mRenderGlyphCount(0),
@@ -128,6 +130,8 @@ LLFontFreetype::~LLFontFreetype()
mCharGlyphInfoMap.clear();
delete mFontBitmapCachep;
+ delete pFontBuffer;
+ disclaimMem(mBufferSize);
// mFallbackFonts cleaned up by LLPointer destructor
}
@@ -143,13 +147,64 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
int error;
+#ifdef LL_WINDOWS
+
+ if (mBufferSize > 0)
+ {
+ delete pFontBuffer;
+ disclaimMem(mBufferSize);
+ pFontBuffer = NULL;
+ mBufferSize = 0;
+ }
+
+ S32 file_size = 0;
+ LLFILE* file = LLFile::fopen(filename, "rb");
+ if (!file)
+ {
+ return FALSE;
+ }
+
+ if (!fseek(file, 0, SEEK_END))
+ {
+ file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ }
+
+ // Don't delete before FT_Done_Face
+ pFontBuffer = new(std::nothrow) U8[file_size];
+ if (!pFontBuffer)
+ {
+ fclose(file);
+ return FALSE;
+ }
+
+ mBufferSize = fread(pFontBuffer, 1, file_size, file);
+ fclose(file);
+
+ if (mBufferSize != file_size)
+ {
+ delete pFontBuffer;
+ mBufferSize = 0;
+ return FALSE;
+ }
+
+ error = FT_New_Memory_Face( gFTLibrary,
+ (FT_Byte*) pFontBuffer,
+ mBufferSize,
+ 0,
+ &mFTFace);
+#else
error = FT_New_Face( gFTLibrary,
filename.c_str(),
0,
- &mFTFace );
+ &mFTFace);
+#endif
- if (error)
+ if (error)
{
+ delete pFontBuffer;
+ pFontBuffer = NULL;
+ mBufferSize = 0;
return FALSE;
}
@@ -166,10 +221,15 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
{
// Clean up freetype libs.
FT_Done_Face(mFTFace);
+ delete pFontBuffer;
+ pFontBuffer = NULL;
+ mBufferSize = 0;
mFTFace = NULL;
return FALSE;
}
+ claimMem(mBufferSize);
+
F32 y_max, y_min, x_max, x_min;
F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
F32 pixels_per_unit = pixels_per_em * ems_per_unit;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index a5ece42b88..26ba695418 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -158,6 +158,8 @@ private:
F32 mLineHeight;
LLFT_Face mFTFace;
+ U8* pFontBuffer;
+ S32 mBufferSize;
BOOL mIsFallback;
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index d003687415..3c829596ce 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -447,7 +447,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
if (!fontp->loadFace(font_path, extra_scale * point_size,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
{
- LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
+ LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
delete fontp;
fontp = NULL;
}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 1847c661d7..155c2402bd 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -55,7 +55,6 @@
BOOL gDebugSession = FALSE;
-BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
BOOL gGLActive = FALSE;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 5d669fb955..970502f2d6 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -408,7 +408,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
{
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
- if (shaderhandle > 0)
+ if (shaderhandle)
{
attachObject(shaderhandle);
}
@@ -997,7 +997,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
void LLGLSLShader::uniform1i(U32 index, GLint x)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1019,7 +1019,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1041,7 +1041,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1064,7 +1064,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1087,7 +1087,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1110,7 +1110,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1133,7 +1133,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1156,7 +1156,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1179,7 +1179,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1202,7 +1202,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1225,7 +1225,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1242,7 +1242,7 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1259,7 +1259,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1276,7 +1276,7 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose,
void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
- if (mProgramObject > 0)
+ if (mProgramObject)
{
if (mUniform.size() <= index)
{
@@ -1294,7 +1294,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
GLint ret = -1;
- if (mProgramObject > 0)
+ if (mProgramObject)
{
LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
if (iter != mUniformMap.end())
@@ -1318,7 +1318,7 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
GLint LLGLSLShader::getUniformLocation(U32 index)
{
GLint ret = -1;
- if (mProgramObject > 0)
+ if (mProgramObject)
{
llassert(index < mUniform.size());
return mUniform[index];
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 20cba68f84..89500dcc04 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -622,7 +622,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
}
static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
-void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
+BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
bool is_compressed = false;
@@ -787,19 +787,33 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llassert(prev_mip_data);
llassert(cur_mip_size == bytes*4);
#endif
- U8* new_data = new U8[bytes];
+ U8* new_data = new(std::nothrow) U8[bytes];
+ if (!new_data)
+ {
+ stop_glerror();
+
+ if (prev_mip_data)
+ delete[] prev_mip_data;
+ if (cur_mip_data)
+ delete[] cur_mip_data;
+
+ mGLTextureCreated = false;
+ return FALSE;
+ }
+ else
+ {
#ifdef SHOW_ASSERT
- llassert(prev_mip_data);
- llassert(cur_mip_size == bytes*4);
- llassert_always(new_data);
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes * 4);
#endif
- LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
- cur_mip_data = new_data;
+ LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
+ cur_mip_data = new_data;
#ifdef SHOW_ASSERT
- cur_mip_size = bytes;
+ cur_mip_size = bytes;
#endif
+ }
}
llassert(w > 0 && h > 0 && cur_mip_data);
@@ -886,6 +900,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
stop_glerror();
mGLTextureCreated = true;
+ return TRUE;
}
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
@@ -1355,8 +1370,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
{
// This will only be true if the size has not changed
- setImage(data_in, data_hasmips);
- return TRUE;
+ return setImage(data_in, data_hasmips);
}
U32 old_name = mTexName;
@@ -1398,7 +1412,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
mCurrentDiscardLevel = discard_level;
- setImage(data_in, data_hasmips);
+ if (!setImage(data_in, data_hasmips))
+ {
+ stop_glerror();
+ return FALSE;
+ }
// Set texture options to our defaults.
gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index ad2aea9067..2be54be062 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -105,7 +105,7 @@ public:
S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
- void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
+ BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 3e7c69611d..76f28bb43f 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1829,48 +1829,6 @@ void LLRender::flush()
{
if (mCount > 0)
{
-#if 0
- if (!glIsEnabled(GL_VERTEX_ARRAY))
- {
- LL_ERRS() << "foo 1" << LL_ENDL;
- }
-
- if (!glIsEnabled(GL_COLOR_ARRAY))
- {
- LL_ERRS() << "foo 2" << LL_ENDL;
- }
-
- if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY))
- {
- LL_ERRS() << "foo 3" << LL_ENDL;
- }
-
- if (glIsEnabled(GL_NORMAL_ARRAY))
- {
- LL_ERRS() << "foo 7" << LL_ENDL;
- }
-
- GLvoid* pointer;
-
- glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
- if (pointer != &(mBuffer[0].v))
- {
- LL_ERRS() << "foo 4" << LL_ENDL;
- }
-
- glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
- if (pointer != &(mBuffer[0].c))
- {
- LL_ERRS() << "foo 5" << LL_ENDL;
- }
-
- glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
- if (pointer != &(mBuffer[0].uv))
- {
- LL_ERRS() << "foo 6" << LL_ENDL;
- }
-#endif
-
if (!mUIOffset.empty())
{
sUICalls++;
@@ -2046,7 +2004,8 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
}
}
- mVerticesp[mCount] = mVerticesp[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)
@@ -2103,8 +2062,11 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v
}
}
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+ if (mCount > 0)
+ {
+ mVerticesp[mCount] = mVerticesp[mCount - 1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
+ }
}
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
@@ -2162,9 +2124,12 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol
}
}
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
+ if (mCount > 0)
+ {
+ mVerticesp[mCount] = mVerticesp[mCount - 1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
+ mColorsp[mCount] = mColorsp[mCount - 1];
+ }
}
void LLRender::vertex2i(const GLint& x, const GLint& y)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 55f0791174..e721ad93fa 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -575,10 +575,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
//we can't have any lines longer than 1024 characters
//or any shaders longer than 4096 lines... deal - DaveP
- GLcharARB buff[1024];
- GLcharARB* text[4096];
- GLuint count = 0;
-
+ GLcharARB buff[1024];
+ GLcharARB *extra_code_text[1024];
+ GLcharARB *shader_code_text[4096 + LL_ARRAY_SIZE(extra_code_text)] = { NULL };
+ GLuint extra_code_count = 0, shader_code_count = 0;
+ BOOST_STATIC_ASSERT(LL_ARRAY_SIZE(extra_code_text) < LL_ARRAY_SIZE(shader_code_text));
+
+
S32 major_version = gGLManager.mGLSLVersionMajor;
S32 minor_version = gGLManager.mGLSLVersionMinor;
@@ -593,20 +596,20 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (minor_version <= 19)
{
- text[count++] = strdup("#version 110\n");
- text[count++] = strdup("#define ATTRIBUTE attribute\n");
- text[count++] = strdup("#define VARYING varying\n");
- text[count++] = strdup("#define VARYING_FLAT varying\n");
+ shader_code_text[shader_code_count++] = strdup("#version 110\n");
+ extra_code_text[extra_code_count++] = strdup("#define ATTRIBUTE attribute\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING varying\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING_FLAT varying\n");
}
else if (minor_version <= 29)
{
//set version to 1.20
- text[count++] = strdup("#version 120\n");
- text[count++] = strdup("#define FXAA_GLSL_120 1\n");
- text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
- text[count++] = strdup("#define ATTRIBUTE attribute\n");
- text[count++] = strdup("#define VARYING varying\n");
- text[count++] = strdup("#define VARYING_FLAT varying\n");
+ shader_code_text[shader_code_count++] = strdup("#version 120\n");
+ extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_120 1\n");
+ extra_code_text[extra_code_count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
+ extra_code_text[extra_code_count++] = strdup("#define ATTRIBUTE attribute\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING varying\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING_FLAT varying\n");
}
}
else
@@ -614,44 +617,43 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (major_version < 4)
{
//set version to 1.30
- text[count++] = strdup("#version 130\n");
-
+ shader_code_text[shader_code_count++] = strdup("#version 130\n");
//some implementations of GLSL 1.30 require integer precision be explicitly declared
- text[count++] = strdup("precision mediump int;\n");
- text[count++] = strdup("precision highp float;\n");
+ extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
+ extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
}
else
{ //set version to 400
- text[count++] = strdup("#version 400\n");
+ shader_code_text[shader_code_count++] = strdup("#version 400\n");
}
- text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
- text[count++] = strdup("#define FXAA_GLSL_130 1\n");
+ extra_code_text[extra_code_count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
+ extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
- text[count++] = strdup("#define ATTRIBUTE in\n");
+ extra_code_text[extra_code_count++] = strdup("#define ATTRIBUTE in\n");
if (type == GL_VERTEX_SHADER_ARB)
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
// ("varying" is deprecated after version 1.20)
- text[count++] = strdup("#define VARYING out\n");
- text[count++] = strdup("#define VARYING_FLAT flat out\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING out\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING_FLAT flat out\n");
}
else
{
- text[count++] = strdup("#define VARYING in\n");
- text[count++] = strdup("#define VARYING_FLAT flat in\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING in\n");
+ extra_code_text[extra_code_count++] = strdup("#define VARYING_FLAT flat in\n");
}
//backwards compatibility with legacy texture lookup syntax
- text[count++] = strdup("#define texture2D texture\n");
- text[count++] = strdup("#define textureCube texture\n");
- text[count++] = strdup("#define texture2DLod textureLod\n");
- text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
+ extra_code_text[extra_code_count++] = strdup("#define texture2D texture\n");
+ extra_code_text[extra_code_count++] = strdup("#define textureCube texture\n");
+ extra_code_text[extra_code_count++] = strdup("#define texture2DLod textureLod\n");
+ extra_code_text[extra_code_count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
if (major_version > 1 || minor_version >= 40)
{ //GLSL 1.40 replaces texture2DRect et al with texture
- text[count++] = strdup("#define texture2DRect texture\n");
- text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
+ extra_code_text[extra_code_count++] = strdup("#define texture2DRect texture\n");
+ extra_code_text[extra_code_count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
@@ -660,13 +662,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
for (boost::unordered_map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
- text[count++] = (GLcharARB *) strdup(define.c_str());
+ extra_code_text[extra_code_count++] = (GLcharARB *) strdup(define.c_str());
}
}
if( gGLManager.mIsATI )
{
- text[ count++ ] = strdup( "#define IS_AMD_CARD 1\n" );
+ extra_code_text[extra_code_count++] = strdup( "#define IS_AMD_CARD 1\n" );
}
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
@@ -704,28 +706,28 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
*/
- text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
+ extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string decl = llformat("uniform sampler2D tex%d;\n", i);
- text[count++] = strdup(decl.c_str());
+ extra_code_text[extra_code_count++] = strdup(decl.c_str());
}
if (texture_index_channels > 1)
{
- text[count++] = strdup("VARYING_FLAT int vary_texture_index;\n");
+ extra_code_text[extra_code_count++] = strdup("VARYING_FLAT int vary_texture_index;\n");
}
- text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
- text[count++] = strdup("{\n");
+ extra_code_text[extra_code_count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
+ extra_code_text[extra_code_count++] = strdup("{\n");
if (texture_index_channels == 1)
{ //don't use flow control, that's silly
- text[count++] = strdup("return texture2D(tex0, texcoord);\n");
- text[count++] = strdup("}\n");
+ extra_code_text[extra_code_count++] = strdup("return texture2D(tex0, texcoord);\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
}
else if (major_version > 1 || minor_version >= 30)
{ //switches are supported in GLSL 1.30 and later
@@ -734,27 +736,27 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
for (U32 i = 0; i < texture_index_channels; ++i)
{
std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture2D(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
- text[count++] = strdup(if_string.c_str());
+ extra_code_text[extra_code_count++] = strdup(if_string.c_str());
}
- text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
- text[count++] = strdup("}\n");
+ extra_code_text[extra_code_count++] = strdup("\treturn vec4(1,0,1,1);\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
}
else
{
- text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
- text[count++] = strdup("\tswitch (vary_texture_index)\n");
- text[count++] = strdup("\t{\n");
+ extra_code_text[extra_code_count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
+ extra_code_text[extra_code_count++] = strdup("\tswitch (vary_texture_index)\n");
+ extra_code_text[extra_code_count++] = strdup("\t{\n");
//switch body
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
- text[count++] = strdup(case_str.c_str());
+ extra_code_text[extra_code_count++] = strdup(case_str.c_str());
}
- text[count++] = strdup("\t}\n");
- text[count++] = strdup("\treturn ret;\n");
- text[count++] = strdup("}\n");
+ extra_code_text[extra_code_count++] = strdup("\t}\n");
+ extra_code_text[extra_code_count++] = strdup("\treturn ret;\n");
+ extra_code_text[extra_code_count++] = strdup("}\n");
}
}
else
@@ -765,14 +767,89 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
else
{
- text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
+ extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
}
+
//copy file into memory
- while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
+ enum {
+ flag_write_to_out_of_extra_block_area = 0x01
+ , flag_extra_block_marker_was_found = 0x02
+ };
+
+ unsigned char flags = flag_write_to_out_of_extra_block_area;
+
+ GLuint out_of_extra_block_counter = 0, start_shader_code = shader_code_count, file_lines_count = 0;
+
+ while(NULL != fgets((char *)buff, 1024, file)
+ && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)))
{
- text[count++] = (GLcharARB *)strdup((char *)buff);
+ file_lines_count++;
+
+ bool extra_block_area_found = NULL != strstr((const char*)buff, "[EXTRA_CODE_HERE]");
+
+ if(extra_block_area_found && !(flag_extra_block_marker_was_found & flags))
+ {
+ if(!(flag_write_to_out_of_extra_block_area & flags))
+ {
+ //shift
+ for(GLuint to = start_shader_code, from = extra_code_count + start_shader_code;
+ from < shader_code_count; ++to, ++from)
+ {
+ shader_code_text[to] = shader_code_text[from];
+ }
+
+ shader_code_count -= extra_code_count;
+ }
+
+ //copy extra code
+ for(GLuint n = 0; n < extra_code_count
+ && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)); ++n)
+ {
+ shader_code_text[shader_code_count++] = extra_code_text[n];
+ }
+
+ extra_code_count = 0;
+
+ flags &= ~flag_write_to_out_of_extra_block_area;
+ flags |= flag_extra_block_marker_was_found;
+ }
+ else
+ {
+ shader_code_text[shader_code_count] = (GLcharARB *)strdup((char *)buff);
+
+ if(flag_write_to_out_of_extra_block_area & flags)
+ {
+ shader_code_text[extra_code_count + start_shader_code + out_of_extra_block_counter]
+ = shader_code_text[shader_code_count];
+ out_of_extra_block_counter++;
+
+ if(out_of_extra_block_counter == extra_code_count)
+ {
+ shader_code_count += extra_code_count;
+ flags &= ~flag_write_to_out_of_extra_block_area;
+ }
+ }
+
+ ++shader_code_count;
+ }
+ } //while
+
+ if(!(flag_extra_block_marker_was_found & flags))
+ {
+ for(GLuint n = start_shader_code; n < extra_code_count + start_shader_code; ++n)
+ {
+ shader_code_text[n] = extra_code_text[n - start_shader_code];
+ }
+
+ if (file_lines_count < extra_code_count)
+ {
+ shader_code_count += extra_code_count;
+ }
+
+ extra_code_count = 0;
}
+
fclose(file);
//create shader object
@@ -787,7 +864,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
//load source
- glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
+ glShaderSourceARB(ret, shader_code_count, (const GLcharARB**) shader_code_text, NULL);
if (gDebugGL)
{
@@ -826,9 +903,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
#if LL_WINDOWS
std::stringstream ostr;
//dump shader source for debugging
- for (GLuint i = 0; i < count; i++)
+ for (GLuint i = 0; i < shader_code_count; i++)
{
- ostr << i << ": " << text[i];
+ ostr << i << ": " << shader_code_text[i];
if (i % 128 == 0)
{ //dump every 128 lines
@@ -843,8 +920,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
#else
std::string str;
- for (GLuint i = 0; i < count; i++) {
- str.append(text[i]);
+ for (GLuint i = 0; i < shader_code_count; i++) {
+ str.append(shader_code_text[i]);
if (i % 128 == 0)
{
@@ -853,7 +930,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
}
#endif
-
+
ret = 0;
}
}
@@ -865,9 +942,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
stop_glerror();
//free memory
- for (GLuint i = 0; i < count; i++)
+ for (GLuint i = 0; i < shader_code_count; i++)
{
- free(text[i]);
+ free(shader_code_text[i]);
}
//successfully loaded, save results
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2761a90566..c06fdd9700 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -191,6 +191,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (mUsage != GL_DYNAMIC_COPY_ARB)
{ //data will be provided by application
ret = (U8*) ll_aligned_malloc<64>(size);
+ if (!ret)
+ {
+ LL_ERRS() << "Failed to allocate for LLVBOPool buffer" << LL_ENDL;
+ }
}
}
else
@@ -1057,10 +1061,12 @@ LLVertexBuffer::~LLVertexBuffer()
if (mFence)
{
+ // Sanity check. We have weird crashes in this destructor (on delete). Yet mFence is disabled.
+ // TODO: mFence was added in scope of SH-2038, but was never enabled, consider removing mFence.
+ LL_ERRS() << "LLVertexBuffer destruction failed" << LL_ENDL;
delete mFence;
+ mFence = NULL;
}
-
- mFence = NULL;
sVertexCount -= mNumVerts;
sIndexCount -= mNumIndices;
@@ -1471,13 +1477,22 @@ void LLVertexBuffer::setupVertexArray()
//glVertexattribIPointer requires GLSL 1.30 or later
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{
- glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]);
+ glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (const GLvoid*) mOffsets[i]);
}
#endif
}
else
{
- glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
+ // nat 2016-12-16: With 64-bit clang compile, the compiler
+ // produces an error if we simply cast mOffsets[i] -- an S32
+ // -- to (GLvoid *), the type of the parameter. It correctly
+ // points out that there's no way an S32 could fit a real
+ // pointer value. Ruslan asserts that in this case the last
+ // param is interpreted as an array data offset within the VBO
+ // rather than as an actual pointer, so it's okay.
+ glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i],
+ attrib_normalized[i], sTypeSize[i],
+ reinterpret_cast<GLvoid*>(mOffsets[i]));
}
}
else