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

41
src/Magnum/AbstractShaderProgram.h

@ -644,7 +644,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* @ref AbstractShaderProgram-attribute-location "class documentation" * @ref AbstractShaderProgram-attribute-location "class documentation"
* for more information. * 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 #ifndef MAGNUM_TARGET_GLES
/** /**
@ -665,7 +672,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* @requires_gl Multiple blend function inputs are not available in * @requires_gl Multiple blend function inputs are not available in
* OpenGL ES. * 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 * @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} * and `gl_FragData[n]` provided by @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
* in OpenGL ES 2.0. * 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 #endif
/** /**
@ -703,7 +725,14 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* @ref AbstractShaderProgram-uniform-location "class documentation" * @ref AbstractShaderProgram-uniform-location "class documentation"
* for more information. * 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 * @brief Set uniform value
@ -826,6 +855,10 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
private: private:
AbstractShaderProgram& setLabelInternal(Containers::ArrayReference<const char> label); 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 #ifndef MAGNUM_BUILD_DEPRECATED
void use(); void use();

Loading…
Cancel
Save