From ff91fa1327c24b261d6cc23fa456fe504d91b4bc Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 20 Feb 2016 19:24:33 -0400 Subject: [PATCH] Improved Shader:send performance by removing some temporary memory allocations. --- src/modules/graphics/opengl/Shader.h | 13 ++++ src/modules/graphics/opengl/wrap_Shader.cpp | 67 +++++---------------- 2 files changed, 27 insertions(+), 53 deletions(-) diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 042a696d8..c3cc2eb00 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -199,6 +199,17 @@ public: return program; } + template + T *getScratchBuffer(size_t count) + { + size_t bytes = sizeof(T) * count; + + if (scratchBuffer.size() < bytes) + scratchBuffer.resize(bytes); + + return (T *) scratchBuffer.data(); + } + static std::string getGLSLVersion(); static bool isSupported(); @@ -276,6 +287,8 @@ private: GLuint videoTextureUnits[3]; + std::vector scratchBuffer; + // Counts total number of textures bound to each texture unit in all shaders static std::vector textureCounters; diff --git a/src/modules/graphics/opengl/wrap_Shader.cpp b/src/modules/graphics/opengl/wrap_Shader.cpp index fa5d94ba4..1039e012d 100644 --- a/src/modules/graphics/opengl/wrap_Shader.cpp +++ b/src/modules/graphics/opengl/wrap_Shader.cpp @@ -47,10 +47,10 @@ int w_Shader_getWarnings(lua_State *L) } template -static T *_getScalars(lua_State *L, int count, size_t &dimension) +static T *_getScalars(lua_State *L, Shader *shader, int count, size_t &dimension) { dimension = 1; - T *values = new T[count]; + T *values = shader->getScratchBuffer(count); for (int i = 0; i < count; ++i) { @@ -60,7 +60,6 @@ static T *_getScalars(lua_State *L, int count, size_t &dimension) values[i] = static_cast(lua_toboolean(L, 3 + i)); else { - delete[] values; luax_typerror(L, 3 + i, "number or boolean"); return 0; } @@ -70,24 +69,22 @@ static T *_getScalars(lua_State *L, int count, size_t &dimension) } template -static T *_getVectors(lua_State *L, int count, size_t &dimension) +static T *_getVectors(lua_State *L, Shader *shader, int count, size_t &dimension) { dimension = luax_objlen(L, 3); - T *values = new T[count * dimension]; + T *values = shader->getScratchBuffer(count * dimension); for (int i = 0; i < count; ++i) { if (!lua_istable(L, 3 + i)) { - delete[] values; luax_typerror(L, 3 + i, "table"); return 0; } if (luax_objlen(L, 3 + i) != dimension) { - delete[] values; luaL_error(L, "Error in argument %d: Expected table size %d, got %d.", - 3+i, dimension, luax_objlen(L, 3+i)); + 3+i, dimension, luax_objlen(L, 3+i)); return 0; } @@ -100,7 +97,6 @@ static T *_getVectors(lua_State *L, int count, size_t &dimension) values[i * dimension + k - 1] = static_cast(lua_toboolean(L, -1)); else { - delete[] values; luax_typerror(L, -1, "number or boolean"); return 0; } @@ -124,31 +120,16 @@ int w_Shader_sendInt(lua_State *L) size_t dimension = 1; if (lua_isnumber(L, 3) || lua_isboolean(L, 3)) - values = _getScalars(L, count, dimension); + values = _getScalars(L, shader, count, dimension); else if (lua_istable(L, 3)) - values = _getVectors(L, count, dimension); + values = _getVectors(L, shader, count, dimension); else return luax_typerror(L, 3, "number, boolean, or table"); if (!values) return luaL_error(L, "Error in arguments."); - bool should_error = false; - try - { - shader->sendInt(name, (int) dimension, values, count); - } - catch (love::Exception &e) - { - should_error = true; - lua_pushstring(L, e.what()); - } - - delete[] values; - - if (should_error) - return luaL_error(L, "%s", lua_tostring(L, -1)); - + luax_catchexcept(L, [&]() { shader->sendInt(name, (int) dimension, values, count); }); return 0; } @@ -165,9 +146,9 @@ static int w__Shader_sendFloat(lua_State *L, bool colors) size_t dimension = 1; if (lua_isnumber(L, 3) || lua_isboolean(L, 3)) - values = _getScalars(L, count, dimension); + values = _getScalars(L, shader, count, dimension); else if (lua_istable(L, 3)) - values = _getVectors(L, count, dimension); + values = _getVectors(L, shader, count, dimension); else return luax_typerror(L, 3, "number, boolean, or table"); @@ -192,22 +173,7 @@ static int w__Shader_sendFloat(lua_State *L, bool colors) } } - bool should_error = false; - try - { - shader->sendFloat(name, (int) dimension, values, count); - } - catch (love::Exception &e) - { - should_error = true; - lua_pushstring(L, e.what()); - } - - delete[] values; - - if (should_error) - return luaL_error(L, "%s", lua_tostring(L, -1)); - + luax_catchexcept(L, [&]() { shader->sendFloat(name, (int) dimension, values, count); }); return 0; } @@ -253,7 +219,7 @@ int w_Shader_sendMatrix(lua_State *L) return luaL_error(L, "Invalid matrix size: %dx%d (only 2x2, 3x3 and 4x4 matrices are supported).", dimension, dimension); - float *values = new float[dimension * dimension * count]; + float *values = shader->getScratchBuffer(dimension * dimension * count); for (int i = 0; i < count; ++i) { @@ -277,9 +243,8 @@ int w_Shader_sendMatrix(lua_State *L) // a dimension of mind. You're moving into a land of both shadow // and substance, of things and ideas. You've just crossed over // into... the Twilight Zone. - delete[] values; return luaL_error(L, "Invalid matrix size at argument %d: Expected size %dx%d, got %dx%d.", - 3+i, dimension, dimension, other_dimension, other_dimension); + 3+i, dimension, dimension, other_dimension, other_dimension); } if (table_of_tables) @@ -312,11 +277,7 @@ int w_Shader_sendMatrix(lua_State *L) } } - luax_catchexcept(L, - [&]() { shader->sendMatrix(name, dimension, values, count); }, - [&](bool) { delete[] values; } - ); - + luax_catchexcept(L, [&]() { shader->sendMatrix(name, dimension, values, count); }); return 0; }