diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 64 | ||||
-rw-r--r-- | indra/llrender/llfontfreetype.h | 2 | ||||
-rw-r--r-- | indra/llrender/llfontregistry.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 1 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 34 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 40 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 2 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 61 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 201 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 23 |
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 |