Browse Source

GL: accept ArrayViews in *Framebuffer::mapForDraw() and invalidate().

Every time I think all std::initializer_list APIs already have an
ArrayView counterpart I discover a new one. (And yes, I did this for
Framebuffer, only to later realize that DefaultFramebuffer suffers from
the same.)
pull/601/head
Vladimír Vondruš 3 years ago
parent
commit
87d7bd8c6e
  1. 6
      doc/changelog.dox
  2. 22
      src/Magnum/GL/DefaultFramebuffer.cpp
  3. 23
      src/Magnum/GL/DefaultFramebuffer.h
  4. 23
      src/Magnum/GL/Framebuffer.cpp
  5. 28
      src/Magnum/GL/Framebuffer.h

6
doc/changelog.dox

@ -449,6 +449,12 @@ See also:
upload/download where needed. The compressed variant is still only GL 4.5+,
as that needs the @ref CompressedImageView APIs to be aware of compression
format properties, which isn't implemented yet.
- Added @ref GL::DefaultFramebuffer::mapForDraw(),
@ref GL::Framebuffer::mapForDraw(),
@ref GL::DefaultFramebuffer::invalidate() and
@ref GL::Framebuffer::invalidate() overloads taking a
@relativeref{Corrade,Containers::ArrayView} instead of a
@ref std::initializer_list
- Added @ref GL::Framebuffer::Status::IncompleteDimensions for ES2. This enum
isn't available on ES3 or desktop GL, but NVidia drivers are known to emit
it, which is why it got added.

22
src/Magnum/GL/DefaultFramebuffer.cpp

@ -60,23 +60,27 @@ DefaultFramebuffer& DefaultFramebuffer::clearColor(const Vector4ui& color) {
}
#endif
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(const Containers::ArrayView<const Containers::Pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
if(attachment.first > max) max = attachment.first;
if(attachment.first() > max) max = attachment.first();
/* Create linear array from associative */
/** @todo C++14: use VLA to avoid heap allocation */
static_assert(GL_NONE == 0, "Expecting zero GL_NONE for zero-initialization");
Containers::Array<GLenum> _attachments{ValueInit, max+1};
for(const auto& attachment: attachments)
_attachments[attachment.first] = GLenum(attachment.second);
_attachments[attachment.first()] = GLenum(attachment.second());
(this->*Context::current().state().framebuffer.drawBuffersImplementation)(max+1, _attachments);
return *this;
}
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list<Containers::Pair<UnsignedInt, DrawAttachment>> attachments) {
return mapForDraw(Containers::arrayView(attachments));
}
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(const DrawAttachment attachment) {
#ifndef MAGNUM_TARGET_GLES
(this->*Context::current().state().framebuffer.drawBufferImplementation)(GLenum(attachment));
@ -92,7 +96,7 @@ DefaultFramebuffer& DefaultFramebuffer::mapForRead(const ReadAttachment attachme
return *this;
}
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments) {
void DefaultFramebuffer::invalidate(Containers::ArrayView<const InvalidationAttachment> attachments) {
/** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i)
@ -100,10 +104,14 @@ void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment
(this->*Context::current().state().framebuffer.invalidateImplementation)(attachments.size(), _attachments);
}
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments) {
invalidate(Containers::arrayView(attachments));
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
void DefaultFramebuffer::invalidate(const Containers::ArrayView<const InvalidationAttachment> attachments, const Range2Di& rectangle) {
/** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i)
@ -111,6 +119,10 @@ void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment
(this->*Context::current().state().framebuffer.invalidateSubImplementation)(attachments.size(), _attachments, rectangle);
}
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
invalidate(Containers::arrayView(attachments), rectangle);
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT

23
src/Magnum/GL/DefaultFramebuffer.h

@ -31,6 +31,11 @@
#include "Magnum/GL/AbstractFramebuffer.h"
#ifdef MAGNUM_BUILD_DEPRECATED
/* For mapForDraw(), which used to take a std::pair */
#include <Corrade/Containers/Pair.h>
#endif
namespace Magnum { namespace GL {
/**
@ -366,6 +371,7 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* @brief Map shader outputs to buffer attachment
* @return Reference to self (for method chaining)
* @m_since_latest
*
* @p attachments is list of shader outputs mapped to buffer
* attachments. Shader outputs which are not listed are not used, you
@ -385,7 +391,10 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
DefaultFramebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
DefaultFramebuffer& mapForDraw(Containers::ArrayView<const Containers::Pair<UnsignedInt, DrawAttachment>> attachments);
/** @overload */
DefaultFramebuffer& mapForDraw(std::initializer_list<Containers::Pair<UnsignedInt, DrawAttachment>> attachments);
/**
* @brief Map shader output to buffer attachment
@ -429,6 +438,7 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/**
* @brief Invalidate framebuffer
* @param attachments Attachments to invalidate
* @m_since_latest
*
* If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3), extension @gl_extension{EXT,discard_framebuffer} in OpenGL ES
@ -443,6 +453,9 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(Containers::ArrayView<const InvalidationAttachment> attachments);
/** @overload */
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
#endif
@ -451,20 +464,24 @@ class MAGNUM_GL_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @brief Invalidate framebuffer rectangle
* @param attachments Attachments to invalidate
* @param rectangle Rectangle to invalidate
* @m_since_latest
*
* If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3) is not available, this function does nothing. If
* @gl_extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref invalidate(std::initializer_list<InvalidationAttachment>),
* @see @ref invalidate(Containers::ArrayView<const InvalidationAttachment>),
* @fn_gl2_keyword{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer},
* eventually @fn_gl_keyword{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref invalidate(std::initializer_list<InvalidationAttachment>)
* @requires_gles30 Use @ref invalidate(Containers::ArrayView<const InvalidationAttachment>)
* in OpenGL ES 2.0 instead.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(Containers::ArrayView<const InvalidationAttachment> attachments, const Range2Di& rectangle);
/** @overload */
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
#endif

23
src/Magnum/GL/Framebuffer.cpp

@ -27,6 +27,7 @@
#include "Framebuffer.h"
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/Pair.h>
#ifndef MAGNUM_TARGET_WEBGL
#include <Corrade/Containers/String.h>
#endif
@ -182,23 +183,27 @@ Framebuffer& Framebuffer::clearColor(const Int attachment, const Vector4ui& colo
}
#endif
Framebuffer& Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
Framebuffer& Framebuffer::mapForDraw(const Containers::ArrayView<const Containers::Pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
if(attachment.first > max) max = attachment.first;
if(attachment.first() > max) max = attachment.first();
/* Create linear array from associative */
/** @todo C++14: use VLA to avoid heap allocation */
static_assert(GL_NONE == 0, "Expecting zero GL_NONE for zero-initialization");
Containers::Array<GLenum> _attachments{ValueInit, max+1};
for(const auto& attachment: attachments)
_attachments[attachment.first] = GLenum(attachment.second);
_attachments[attachment.first()] = GLenum(attachment.second());
(this->*Context::current().state().framebuffer.drawBuffersImplementation)(max+1, _attachments);
return *this;
}
Framebuffer& Framebuffer::mapForDraw(std::initializer_list<Containers::Pair<UnsignedInt, DrawAttachment>> attachments) {
return mapForDraw(Containers::arrayView(attachments));
}
Framebuffer& Framebuffer::mapForDraw(const DrawAttachment attachment) {
#ifndef MAGNUM_TARGET_GLES
(this->*Context::current().state().framebuffer.drawBufferImplementation)(GLenum(attachment));
@ -214,7 +219,7 @@ Framebuffer& Framebuffer::mapForRead(const ColorAttachment attachment) {
return *this;
}
void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments) {
void Framebuffer::invalidate(const Containers::ArrayView<const InvalidationAttachment> attachments) {
/** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i)
@ -223,8 +228,12 @@ void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attac
(this->*Context::current().state().framebuffer.invalidateImplementation)(attachments.size(), _attachments);
}
void Framebuffer::invalidate(const std::initializer_list<InvalidationAttachment> attachments) {
invalidate(Containers::arrayView(attachments));
}
#ifndef MAGNUM_TARGET_GLES2
void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
void Framebuffer::invalidate(const Containers::ArrayView<const InvalidationAttachment> attachments, const Range2Di& rectangle) {
/** @todo C++14: use VLA to avoid heap allocation */
Containers::Array<GLenum> _attachments(attachments.size());
for(std::size_t i = 0; i != attachments.size(); ++i)
@ -232,6 +241,10 @@ void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attac
(this->*Context::current().state().framebuffer.invalidateSubImplementation)(attachments.size(), _attachments, rectangle);
}
void Framebuffer::invalidate(const std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle) {
invalidate(Containers::arrayView(attachments), rectangle);
}
#endif
#endif

28
src/Magnum/GL/Framebuffer.h

@ -41,6 +41,8 @@
/* For label() / setLabel(), which used to be a std::string. Not ideal for the
return type, but at least something. */
#include <Corrade/Containers/StringStl.h>
/* For mapForDraw(), which used to take a std::pair */
#include <Corrade/Containers/Pair.h>
#endif
namespace Magnum { namespace GL {
@ -526,6 +528,7 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO
/**
* @brief Map shader output to attachments
* @return Reference to self (for method chaining)
* @m_since_latest
*
* @p attachments is list of shader outputs mapped to framebuffer
* color attachment IDs. Shader outputs which are not listed are not
@ -546,7 +549,10 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO
* @requires_webgl20 Extension @webgl_extension{WEBGL,draw_buffers} in
* WebGL 1.0.
*/
Framebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
Framebuffer& mapForDraw(Containers::ArrayView<const Containers::Pair<UnsignedInt, DrawAttachment>> attachments);
/** @overload */
Framebuffer& mapForDraw(std::initializer_list<Containers::Pair<UnsignedInt, DrawAttachment>> attachments);
/**
* @brief Map shader output to an attachment
@ -591,6 +597,7 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO
/**
* @brief Invalidate framebuffer
* @param attachments Attachments to invalidate
* @m_since_latest
*
* If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3), extension @gl_extension{EXT,discard_framebuffer} in OpenGL ES
@ -605,6 +612,13 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(Containers::ArrayView<const InvalidationAttachment> attachments);
/**
* @overload
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
#endif
@ -613,20 +627,28 @@ class MAGNUM_GL_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractO
* @brief Invalidate framebuffer rectangle
* @param attachments Attachments to invalidate
* @param rectangle Rectangle to invalidate
* @m_since_latest
*
* If extension @gl_extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3) is not available, this function does nothing. If
* @gl_extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref invalidate(std::initializer_list<InvalidationAttachment>),
* @see @ref invalidate(Containers::ArrayView<const InvalidationAttachment>),
* @fn_gl2_keyword{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer},
* eventually @fn_gl_keyword{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref invalidate(std::initializer_list<InvalidationAttachment>)
* @requires_gles30 Use @ref invalidate(Containers::ArrayView<const InvalidationAttachment>)
* in OpenGL ES 2.0 instead.
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(Containers::ArrayView<const InvalidationAttachment> attachments, const Range2Di& rectangle);
/**
* @overload
* @requires_webgl20 Framebuffer invalidation is not available in WebGL
* 1.0.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
#endif

Loading…
Cancel
Save