Browse Source

Ability to reset internal state tracker.

pull/54/head
Vladimír Vondruš 12 years ago
parent
commit
4e50aeee31
  1. 2
      src/Magnum/AbstractFramebuffer.cpp
  2. 4
      src/Magnum/AbstractShaderProgram.cpp
  3. 1
      src/Magnum/AbstractTexture.cpp
  4. 1
      src/Magnum/Buffer.cpp
  5. 24
      src/Magnum/Context.cpp
  6. 43
      src/Magnum/Context.h
  7. 1
      src/Magnum/Framebuffer.cpp
  8. 6
      src/Magnum/Implementation/BufferState.cpp
  9. 2
      src/Magnum/Implementation/BufferState.h
  10. 7
      src/Magnum/Implementation/FramebufferState.cpp
  11. 2
      src/Magnum/Implementation/FramebufferState.h
  12. 6
      src/Magnum/Implementation/MeshState.cpp
  13. 2
      src/Magnum/Implementation/MeshState.h
  14. 6
      src/Magnum/Implementation/ShaderProgramState.cpp
  15. 2
      src/Magnum/Implementation/ShaderProgramState.h
  16. 3
      src/Magnum/Implementation/State.h
  17. 6
      src/Magnum/Implementation/TextureState.cpp
  18. 2
      src/Magnum/Implementation/TextureState.h
  19. 1
      src/Magnum/Mesh.cpp

2
src/Magnum/AbstractFramebuffer.cpp

@ -158,6 +158,8 @@ AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle)
void AbstractFramebuffer::setViewportInternal() { void AbstractFramebuffer::setViewportInternal() {
Implementation::FramebufferState* state = Context::current()->state().framebuffer; Implementation::FramebufferState* state = Context::current()->state().framebuffer;
/* We are using empty viewport to indicate disengaged state */
CORRADE_INTERNAL_ASSERT(_viewport != Range2Di{});
CORRADE_INTERNAL_ASSERT(state->drawBinding == _id); CORRADE_INTERNAL_ASSERT(state->drawBinding == _id);
/* Already up-to-date, nothing to do */ /* Already up-to-date, nothing to do */

4
src/Magnum/AbstractShaderProgram.cpp

@ -196,7 +196,9 @@ Int AbstractShaderProgram::maxTexelOffset() {
} }
#endif #endif
AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {} AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
AbstractShaderProgram::AbstractShaderProgram(AbstractShaderProgram&& other) noexcept: _id(other._id) { AbstractShaderProgram::AbstractShaderProgram(AbstractShaderProgram&& other) noexcept: _id(other._id) {
other._id = 0; other._id = 0;

1
src/Magnum/AbstractTexture.cpp

@ -171,6 +171,7 @@ void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std:
AbstractTexture::AbstractTexture(GLenum target): _target(target) { AbstractTexture::AbstractTexture(GLenum target): _target(target) {
glGenTextures(1, &_id); glGenTextures(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
} }
AbstractTexture::~AbstractTexture() { AbstractTexture::~AbstractTexture() {

1
src/Magnum/Buffer.cpp

@ -114,6 +114,7 @@ Buffer::Buffer(Buffer::Target targetHint): _targetHint(targetHint)
#endif #endif
{ {
glGenBuffers(1, &_id); glGenBuffers(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
} }
Buffer::~Buffer() { Buffer::~Buffer() {

24
src/Magnum/Context.cpp

@ -45,6 +45,11 @@
#include "Magnum/Renderer.h" #include "Magnum/Renderer.h"
#include "Implementation/State.h" #include "Implementation/State.h"
#include "Implementation/BufferState.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/MeshState.h"
#include "Implementation/ShaderProgramState.h"
#include "Implementation/TextureState.h"
namespace Magnum { namespace Magnum {
@ -526,6 +531,25 @@ Version Context::supportedVersion(std::initializer_list<Version> versions) const
#endif #endif
} }
void Context::resetState(const States states) {
if(states & State::Buffers)
_state->buffer->reset();
if(states & State::Framebuffers)
_state->framebuffer->reset();
if(states & State::Meshes)
_state->mesh->reset();
/* Nothing to reset for renderer yet */
if(states & State::Shaders) {
/* Nothing to reset for shaders */
_state->shaderProgram->reset();
}
if(states & State::Textures)
_state->texture->reset();
}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, const Context::Flag value) { Debug operator<<(Debug debug, const Context::Flag value) {
switch(value) { switch(value) {

43
src/Magnum/Context.h

@ -137,6 +137,38 @@ class MAGNUM_EXPORT Context {
#endif #endif
}; };
/**
* @brief State to reset
*
* @see @ref States, @ref resetState()
*/
enum class State: UnsignedInt {
/** Reset tracked buffer-related bindings and state */
Buffers = 1 << 0,
/** Reset tracked framebuffer-related bindings and state */
Framebuffers = 1 << 1,
/** Reset tracked mesh-related bindings */
Meshes = 1 << 2,
/** Reset tracked renderer-related state */
Renderer = 1 << 3,
/** Reset tracked shader-related bindings */
Shaders = 1 << 4,
/** Reset tracked texture-related bindings and state */
Textures = 1 << 5
};
/**
* @brief States to reset
*
* @see @ref resetState()
*/
typedef Containers::EnumSet<State, UnsignedInt> States;
/** /**
* @brief Context flags * @brief Context flags
* *
@ -382,6 +414,17 @@ class MAGNUM_EXPORT Context {
return isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index] && !isVersionSupported(_extensionRequiredVersion[extension._index]); return isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index] && !isVersionSupported(_extensionRequiredVersion[extension._index]);
} }
/**
* @brief Reset internal state tracker
* @param states Tracked states to reset. Default is all state.
*
* The engine internally tracks object bindings and other state to
* avoid redundant OpenGL calls. In some cases (e.g. when non-Magnum
* code makes GL calls) the internal tracker no longer reflects actual
* state and needs to be reset to avoid strange issues.
*/
void resetState(States states = ~States{});
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
Implementation::State& state() { return *_state; } Implementation::State& state() { return *_state; }
#endif #endif

1
src/Magnum/Framebuffer.cpp

@ -82,6 +82,7 @@ Framebuffer::Framebuffer(const Range2Di& viewport) {
_viewport = viewport; _viewport = viewport;
glGenFramebuffers(1, &_id); glGenFramebuffers(1, &_id);
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
} }
Framebuffer::~Framebuffer() { Framebuffer::~Framebuffer() {

6
src/Magnum/Implementation/BufferState.cpp

@ -30,6 +30,8 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
const Buffer::Target BufferState::targetForIndex[] = { const Buffer::Target BufferState::targetForIndex[] = {
@ -136,4 +138,8 @@ BufferState::BufferState(Context& context, std::vector<std::string>& extensions)
#endif #endif
} }
void BufferState::reset() {
std::fill_n(bindings, TargetCount, State::DisengagedBinding);
}
}} }}

2
src/Magnum/Implementation/BufferState.h

@ -46,6 +46,8 @@ struct BufferState {
explicit BufferState(Context& context, std::vector<std::string>& extensions); explicit BufferState(Context& context, std::vector<std::string>& extensions);
void reset();
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
void(*copyImplementation)(Buffer&, Buffer&, GLintptr, GLintptr, GLsizeiptr); void(*copyImplementation)(Buffer&, Buffer&, GLintptr, GLintptr, GLsizeiptr);
#endif #endif

7
src/Magnum/Implementation/FramebufferState.cpp

@ -29,6 +29,8 @@
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "Magnum/Renderbuffer.h" #include "Magnum/Renderbuffer.h"
#include "State.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding(0), drawBinding(0), renderbufferBinding(0), maxDrawBuffers(0), maxColorAttachments(0), maxRenderbufferSize(0), maxSamples(0) FramebufferState::FramebufferState(Context& context, std::vector<std::string>& extensions): readBinding(0), drawBinding(0), renderbufferBinding(0), maxDrawBuffers(0), maxColorAttachments(0), maxRenderbufferSize(0), maxSamples(0)
@ -138,4 +140,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
} }
} }
void FramebufferState::reset() {
readBinding = drawBinding = renderbufferBinding = State::DisengagedBinding;
viewport = {};
}
}} }}

2
src/Magnum/Implementation/FramebufferState.h

@ -35,6 +35,8 @@ namespace Magnum { namespace Implementation {
struct FramebufferState { struct FramebufferState {
explicit FramebufferState(Context& context, std::vector<std::string>& extensions); explicit FramebufferState(Context& context, std::vector<std::string>& extensions);
void reset();
GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget); GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget);
void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*); void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*);
void(AbstractFramebuffer::*drawBufferImplementation)(GLenum); void(AbstractFramebuffer::*drawBufferImplementation)(GLenum);

6
src/Magnum/Implementation/MeshState.cpp

@ -28,6 +28,8 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
MeshState::MeshState(Context& context, std::vector<std::string>& extensions): currentVAO(0) MeshState::MeshState(Context& context, std::vector<std::string>& extensions): currentVAO(0)
@ -138,4 +140,8 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
#endif #endif
} }
void MeshState::reset() {
currentVAO = State::DisengagedBinding;
}
}} }}

2
src/Magnum/Implementation/MeshState.h

@ -35,6 +35,8 @@ namespace Magnum { namespace Implementation {
struct MeshState { struct MeshState {
explicit MeshState(Context& context, std::vector<std::string>& extensions); explicit MeshState(Context& context, std::vector<std::string>& extensions);
void reset();
void(Mesh::*createImplementation)(); void(Mesh::*createImplementation)();
void(Mesh::*destroyImplementation)(); void(Mesh::*destroyImplementation)();
void(Mesh::*attributePointerImplementation)(const Mesh::Attribute&); void(Mesh::*attributePointerImplementation)(const Mesh::Attribute&);

6
src/Magnum/Implementation/ShaderProgramState.cpp

@ -29,6 +29,8 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string>& extensions): current(0), maxVertexAttributes(0) ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string>& extensions): current(0), maxVertexAttributes(0)
@ -185,4 +187,8 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
} }
} }
void ShaderProgramState::reset() {
current = State::DisengagedBinding;
}
}} }}

2
src/Magnum/Implementation/ShaderProgramState.h

@ -36,6 +36,8 @@ namespace Magnum { namespace Implementation {
struct ShaderProgramState { struct ShaderProgramState {
explicit ShaderProgramState(Context& context, std::vector<std::string>& extensions); explicit ShaderProgramState(Context& context, std::vector<std::string>& extensions);
void reset();
void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*); void(AbstractShaderProgram::*uniform1fvImplementation)(GLint, GLsizei, const GLfloat*);
void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*); void(AbstractShaderProgram::*uniform2fvImplementation)(GLint, GLsizei, const Math::Vector<2, GLfloat>*);
void(AbstractShaderProgram::*uniform3fvImplementation)(GLint, GLsizei, const Math::Vector<3, GLfloat>*); void(AbstractShaderProgram::*uniform3fvImplementation)(GLint, GLsizei, const Math::Vector<3, GLfloat>*);

3
src/Magnum/Implementation/State.h

@ -26,6 +26,7 @@
*/ */
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
@ -44,6 +45,8 @@ struct State {
~State(); ~State();
enum: GLuint { DisengagedBinding = ~0u };
BufferState* buffer; BufferState* buffer;
DebugState* debug; DebugState* debug;
FramebufferState* framebuffer; FramebufferState* framebuffer;

6
src/Magnum/Implementation/TextureState.cpp

@ -34,6 +34,8 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "State.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
TextureState::TextureState(Context& context, std::vector<std::string>& extensions): maxSize{}, max3DSize{}, maxCubeMapSize{}, TextureState::TextureState(Context& context, std::vector<std::string>& extensions): maxSize{}, max3DSize{}, maxCubeMapSize{},
@ -228,4 +230,8 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
TextureState::~TextureState() = default; TextureState::~TextureState() = default;
void TextureState::reset() {
std::fill_n(bindings.begin(), bindings.size(), std::pair<GLenum, GLuint>{{}, State::DisengagedBinding});
}
}} }}

2
src/Magnum/Implementation/TextureState.h

@ -37,6 +37,8 @@ struct TextureState {
explicit TextureState(Context& context, std::vector<std::string>& extensions); explicit TextureState(Context& context, std::vector<std::string>& extensions);
~TextureState(); ~TextureState();
void reset();
void(*unbindImplementation)(GLint); void(*unbindImplementation)(GLint);
void(*bindMultiImplementation)(GLint, std::initializer_list<AbstractTexture*>); void(*bindMultiImplementation)(GLint, std::initializer_list<AbstractTexture*>);
void(AbstractTexture::*bindImplementation)(GLint); void(AbstractTexture::*bindImplementation)(GLint);

1
src/Magnum/Mesh.cpp

@ -307,6 +307,7 @@ void Mesh::createImplementationVAO() {
//glGenVertexArraysOES(1, &_id); //glGenVertexArraysOES(1, &_id);
CORRADE_INTERNAL_ASSERT(false); CORRADE_INTERNAL_ASSERT(false);
#endif #endif
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
} }
void Mesh::destroyImplementationDefault() {} void Mesh::destroyImplementationDefault() {}

Loading…
Cancel
Save