From e71be176a973b56a579feafaa536da47635ea871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 24 Jul 2014 21:11:32 +0200 Subject: [PATCH] Allocation-free overloads for AbstractShaderProgram string functions. In nearly every case the attributes are bound and uniform locations queried with constant char arrays: bindAttributeLocation("position", Position::Location); colorUniform = uniformLocation("color"); Avoiding conversion to std::string and passing const char(&)[size] directly will avoid needless allocation (and later deallocation) for every call. --- src/Magnum/AbstractShaderProgram.cpp | 18 ++++++------ src/Magnum/AbstractShaderProgram.h | 41 +++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp index 4b836eacf..954dfbdd4 100644 --- a/src/Magnum/AbstractShaderProgram.cpp +++ b/src/Magnum/AbstractShaderProgram.cpp @@ -266,16 +266,16 @@ void AbstractShaderProgram::attachShaders(std::initializer_list name) { + glBindAttribLocation(_id, location, name); } #ifndef MAGNUM_TARGET_GLES -void AbstractShaderProgram::bindFragmentDataLocation(UnsignedInt location, const std::string& name) { - glBindFragDataLocation(_id, location, name.data()); +void AbstractShaderProgram::bindFragmentDataLocationInternal(const UnsignedInt location, const Containers::ArrayReference name) { + glBindFragDataLocation(_id, location, name); } -void AbstractShaderProgram::bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const std::string& name) { - glBindFragDataLocationIndexed(_id, location, index, name.data()); +void AbstractShaderProgram::bindFragmentDataLocationIndexedInternal(const UnsignedInt location, UnsignedInt index, const Containers::ArrayReference name) { + glBindFragDataLocationIndexed(_id, location, index, name); } #endif @@ -346,10 +346,10 @@ bool AbstractShaderProgram::link(std::initializer_list name) { + GLint location = glGetUniformLocation(_id, name); if(location == -1) - Warning() << "AbstractShaderProgram: location of uniform \'" + name + "\' cannot be retrieved!"; + Warning() << "AbstractShaderProgram: location of uniform \'" + std::string{name, name.size()} + "\' cannot be retrieved!"; return location; } diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index eb1888de3..e89e85523 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -644,7 +644,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. */ - void bindAttributeLocation(UnsignedInt location, const std::string& name); + void bindAttributeLocation(UnsignedInt location, const std::string& name) { + bindAttributeLocationInternal(location, {name.data(), name.size()}); + } + + /** @overload */ + template void bindAttributeLocation(UnsignedInt location, const char(&name)[size]) { + bindAttributeLocationInternal(location, name); + } #ifndef MAGNUM_TARGET_GLES /** @@ -665,7 +672,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * @requires_gl Multiple blend function inputs are not available in * OpenGL ES. */ - void bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const std::string& name); + void bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const std::string& name) { + bindFragmentDataLocationIndexedInternal(location, index, {name.data(), name.size()}); + } + + /** @overload */ + template void bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const char(&name)[size]) { + bindFragmentDataLocationIndexedInternal(location, index, name); + } /** * @brief Bind fragment data to given location and first color input index @@ -680,7 +694,15 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * and `gl_FragData[n]` provided by @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * in OpenGL ES 2.0. */ - void bindFragmentDataLocation(UnsignedInt location, const std::string& name); + void bindFragmentDataLocation(UnsignedInt location, const std::string& name) { + bindFragmentDataLocationInternal(location, {name.data(), name.size()}); + } + + /** @overload */ + template void bindFragmentDataLocation(UnsignedInt location, const char(&name)[size]) { + /* Not using const char* parameter, because this way it avoids most accidents with non-zero-terminated strings */ + bindFragmentDataLocationInternal(location, name); + } #endif /** @@ -703,7 +725,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { * @ref AbstractShaderProgram-uniform-location "class documentation" * for more information. */ - Int uniformLocation(const std::string& name); + Int uniformLocation(const std::string& name) { + return uniformLocationInternal({name.data(), name.size()}); + } + + /** @overload */ + template Int uniformLocation(const char(&name)[size]) { + return uniformLocationInternal(name); + } /** * @brief Set uniform value @@ -826,6 +855,10 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { private: AbstractShaderProgram& setLabelInternal(Containers::ArrayReference label); + void bindAttributeLocationInternal(UnsignedInt location, Containers::ArrayReference name); + void bindFragmentDataLocationIndexedInternal(UnsignedInt location, UnsignedInt index, Containers::ArrayReference name); + void bindFragmentDataLocationInternal(UnsignedInt location, Containers::ArrayReference name); + Int uniformLocationInternal(Containers::ArrayReference name); #ifndef MAGNUM_BUILD_DEPRECATED void use();