diff --git a/src/Implementation/FramebufferState.h b/src/Implementation/FramebufferState.h index f6c0b5a19..93b83f1ad 100644 --- a/src/Implementation/FramebufferState.h +++ b/src/Implementation/FramebufferState.h @@ -21,9 +21,9 @@ namespace Magnum { namespace Implementation { struct FramebufferState { - inline FramebufferState(): readBinding(0), drawBinding(0) {} + inline FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} - GLuint readBinding, drawBinding; + GLuint readBinding, drawBinding, renderbufferBinding; Vector2i viewportPosition, viewportSize; }; diff --git a/src/Renderbuffer.cpp b/src/Renderbuffer.cpp index 6e3cb17ee..100ac550e 100644 --- a/src/Renderbuffer.cpp +++ b/src/Renderbuffer.cpp @@ -15,6 +15,33 @@ #include "Renderbuffer.h" +#include "Context.h" + +#include "Implementation/State.h" +#include "Implementation/FramebufferState.h" + namespace Magnum { +Renderbuffer::~Renderbuffer() { + /* If bound, remove itself from state */ + GLuint& binding = Context::current()->state()->framebuffer->renderbufferBinding; + if(binding == _id) binding = 0; + + glDeleteRenderbuffers(1, &_id); +} + +void Renderbuffer::setStorage(Renderbuffer::InternalFormat internalFormat, const Vector2i& size) { + bind(); + glRenderbufferStorage(GL_RENDERBUFFER, GLenum(internalFormat), size.x(), size.y()); +} + +void Renderbuffer::bind() { + GLuint& binding = Context::current()->state()->framebuffer->renderbufferBinding; + + if(binding == _id) return; + + binding = _id; + glBindRenderbuffer(GL_RENDERBUFFER, _id); +} + } diff --git a/src/Renderbuffer.h b/src/Renderbuffer.h index f96b1de2e..d61c260a1 100644 --- a/src/Renderbuffer.h +++ b/src/Renderbuffer.h @@ -31,9 +31,15 @@ namespace Magnum { Attachable to framebuffer as render target, see Framebuffer documentation for more information. + +@section Renderbuffer-performance-optimization Performance optimizations + +The engine tracks currently bound renderbuffer to avoid unnecessary calls to +@fn_gl{BindRenderbuffer} in setStorage(). + @requires_gl30 %Extension @extension{EXT,framebuffer_object} */ -class Renderbuffer { +class MAGNUM_EXPORT Renderbuffer { Renderbuffer(const Renderbuffer& other) = delete; Renderbuffer(Renderbuffer&& other) = delete; Renderbuffer& operator=(const Renderbuffer& other) = delete; @@ -513,7 +519,7 @@ class Renderbuffer { * @see @fn_gl{GenRenderbuffers} */ inline explicit Renderbuffer() { - glGenRenderbuffers(1, &renderbuffer); + glGenRenderbuffers(1, &_id); } /** @@ -522,36 +528,24 @@ class Renderbuffer { * Deletes associated OpenGL renderbuffer. * @see @fn_gl{DeleteRenderbuffers} */ - inline ~Renderbuffer() { - glDeleteRenderbuffers(1, &renderbuffer); - } + ~Renderbuffer(); /** @brief OpenGL internal renderbuffer ID */ - inline GLuint id() const { return renderbuffer; } - - /** - * @brief Bind renderbuffer - * - * @see @fn_gl{BindRenderbuffer} - */ - inline void bind() { - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - } + inline GLuint id() const { return _id; } /** * @brief Set renderbuffer storage * @param internalFormat Internal format * @param size Renderbuffer size * - * @see bind(), @fn_gl{RenderbufferStorage} + * @see @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage} */ - inline void setStorage(InternalFormat internalFormat, const Vector2i& size) { - bind(); - glRenderbufferStorage(GL_RENDERBUFFER, GLenum(internalFormat), size.x(), size.y()); - } + void setStorage(InternalFormat internalFormat, const Vector2i& size); private: - GLuint renderbuffer; + void MAGNUM_LOCAL bind(); + + GLuint _id; }; }