Browse Source

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.
pull/68/head
Vladimír Vondruš 12 years ago
parent
commit
e71be176a9
  1. 18
      src/Magnum/AbstractShaderProgram.cpp
  2. 41
      src/Magnum/AbstractShaderProgram.h

18
src/Magnum/AbstractShaderProgram.cpp

@ -266,16 +266,16 @@ void AbstractShaderProgram::attachShaders(std::initializer_list<std::reference_w
for(Shader& s: shaders) attachShader(s);
}
void AbstractShaderProgram::bindAttributeLocation(UnsignedInt location, const std::string& name) {
glBindAttribLocation(_id, location, name.data());
void AbstractShaderProgram::bindAttributeLocationInternal(const UnsignedInt location, const Containers::ArrayReference<const char> 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<const char> 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<const char> name) {
glBindFragDataLocationIndexed(_id, location, index, name);
}
#endif
@ -346,10 +346,10 @@ bool AbstractShaderProgram::link(std::initializer_list<std::reference_wrapper<Ab
return allSuccess;
}
Int AbstractShaderProgram::uniformLocation(const std::string& name) {
GLint location = glGetUniformLocation(_id, name.data());
Int AbstractShaderProgram::uniformLocationInternal(const Containers::ArrayReference<const char> 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;
}

41
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<std::size_t size> 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<std::size_t size> 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<std::size_t size> 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<std::size_t size> 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<const char> label);
void bindAttributeLocationInternal(UnsignedInt location, Containers::ArrayReference<const char> name);
void bindFragmentDataLocationIndexedInternal(UnsignedInt location, UnsignedInt index, Containers::ArrayReference<const char> name);
void bindFragmentDataLocationInternal(UnsignedInt location, Containers::ArrayReference<const char> name);
Int uniformLocationInternal(Containers::ArrayReference<const char> name);
#ifndef MAGNUM_BUILD_DEPRECATED
void use();

Loading…
Cancel
Save