diff options
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r-- | source/blender/gpu/opengl/gl_context.cc | 2 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_framebuffer.cc | 59 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_framebuffer.hh | 6 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_state.cc | 24 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_state.hh | 12 |
5 files changed, 72 insertions, 31 deletions
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc index 380b396f0cd..11958ce0926 100644 --- a/source/blender/gpu/opengl/gl_context.cc +++ b/source/blender/gpu/opengl/gl_context.cc @@ -85,6 +85,8 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list } active_fb = back_left; + static_cast<GLStateManager *>(state_manager)->active_fb = static_cast<GLFrameBuffer *>( + back_left); } GLContext::~GLContext() diff --git a/source/blender/gpu/opengl/gl_framebuffer.cc b/source/blender/gpu/opengl/gl_framebuffer.cc index 7e50d37928e..d7dd5fa23a4 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.cc +++ b/source/blender/gpu/opengl/gl_framebuffer.cc @@ -27,6 +27,7 @@ #include "gl_backend.hh" #include "gl_framebuffer.hh" +#include "gl_state.hh" #include "gl_texture.hh" namespace blender::gpu { @@ -47,6 +48,7 @@ GLFrameBuffer::GLFrameBuffer( : FrameBuffer(name) { context_ = ctx; + state_manager_ = static_cast<GLStateManager *>(ctx->state_manager); immutable_ = true; fbo_id_ = fbo; gl_attachments_[0] = target; @@ -56,6 +58,11 @@ GLFrameBuffer::GLFrameBuffer( height_ = h; srgb_ = false; + viewport_[0] = scissor_[0] = 0; + viewport_[1] = scissor_[1] = 0; + viewport_[2] = scissor_[2] = w; + viewport_[3] = scissor_[3] = h; + #ifndef __APPLE__ if (fbo_id_ && (G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) { char sh_name[32]; @@ -82,6 +89,7 @@ GLFrameBuffer::~GLFrameBuffer() void GLFrameBuffer::init(void) { context_ = static_cast<GLContext *>(GPU_context_active_get()); + state_manager_ = static_cast<GLStateManager *>(context_->state_manager); glGenFramebuffers(1, &fbo_id_); #ifndef __APPLE__ @@ -227,6 +235,25 @@ void GLFrameBuffer::update_attachments(void) } } +void GLFrameBuffer::apply_state(void) +{ + if (dirty_state_ == false) { + return; + } + + glViewport(UNPACK4(viewport_)); + glScissor(UNPACK4(scissor_)); + + if (scissor_test_) { + glEnable(GL_SCISSOR_TEST); + } + else { + glDisable(GL_SCISSOR_TEST); + } + + dirty_state_ = false; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -235,18 +262,16 @@ void GLFrameBuffer::update_attachments(void) void GLFrameBuffer::bind(bool enabled_srgb) { - GPUContext *ctx = GPU_context_active_get(); - BLI_assert(ctx); - - if (context_ != NULL && context_ != ctx) { - BLI_assert(!"Trying to use the same framebuffer in multiple context"); - } - if (!immutable_ && fbo_id_ == 0) { this->init(); } - if (ctx->active_fb != this) { + if (context_ != GPU_context_active_get()) { + BLI_assert(!"Trying to use the same framebuffer in multiple context"); + return; + } + + if (context_->active_fb != this) { glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); /* Internal framebuffers have only one color output and needs to be set everytime. */ if (immutable_ && fbo_id_ == 0) { @@ -256,10 +281,14 @@ void GLFrameBuffer::bind(bool enabled_srgb) if (dirty_attachments_) { this->update_attachments(); + this->viewport_reset(); + this->scissor_reset(); } - if (ctx->active_fb != this) { - ctx->active_fb = this; + if (context_->active_fb != this) { + context_->active_fb = this; + state_manager_->active_fb = this; + dirty_state_ = true; if (enabled_srgb) { glEnable(GL_FRAMEBUFFER_SRGB); @@ -270,8 +299,6 @@ void GLFrameBuffer::bind(bool enabled_srgb) GPU_shader_set_framebuffer_srgb_target(enabled_srgb && srgb_); } - - GPU_viewport(0, 0, width_, height_); } /** \} */ @@ -285,6 +312,9 @@ void GLFrameBuffer::clear(eGPUFrameBufferBits buffers, float clear_depth, uint clear_stencil) { + BLI_assert(GPU_context_active_get() == context_); + BLI_assert(context_->active_fb == this); + /* Save and restore the state. */ eGPUWriteMask write_mask = GPU_write_mask_get(); uint stencil_mask = GPU_stencil_mask_get(); @@ -320,6 +350,9 @@ void GLFrameBuffer::clear(eGPUFrameBufferBits buffers, void GLFrameBuffer::clear_multi(const float (*clear_cols)[4]) { + BLI_assert(GPU_context_active_get() == context_); + BLI_assert(context_->active_fb == this); + /* Save and restore the state. */ eGPUWriteMask write_mask = GPU_write_mask_get(); GPU_color_mask(true, true, true, true); @@ -401,7 +434,7 @@ void GLFrameBuffer::blit_to( glDrawBuffer(dst->gl_attachments_[dst_slot]); } - GPU_context_active_get()->state_manager->apply_state(); + context_->state_manager->apply_state(); int w = src->width_; int h = src->height_; diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh index a83bc1f6cae..8d386116159 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.hh +++ b/source/blender/gpu/opengl/gl_framebuffer.hh @@ -33,6 +33,8 @@ namespace blender::gpu { +class GLStateManager; + /** * Implementation of FrameBuffer object using OpenGL. **/ @@ -42,6 +44,8 @@ class GLFrameBuffer : public FrameBuffer { GLuint fbo_id_ = 0; /** Context the handle is from. Framebuffers are not shared accros contexts. */ GLContext *context_ = NULL; + /** State Manager of the same contexts. */ + GLStateManager *state_manager_ = NULL; /** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */ GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT]; /** Internal framebuffers are immutable. */ @@ -92,6 +96,8 @@ class GLFrameBuffer : public FrameBuffer { int dst_offset_x, int dst_offset_y) override; + void apply_state(void); + private: void init(void); void update_attachments(void); diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index 7dc3e44c516..84824191a12 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -27,6 +27,7 @@ #include "glew-mx.h" #include "gl_context.hh" +#include "gl_framebuffer.hh" #include "gl_state.hh" using namespace blender::gpu; @@ -64,6 +65,13 @@ GLStateManager::GLStateManager(void) : GPUStateManager() set_mutable_state(mutable_state); } +void GLStateManager::apply_state(void) +{ + this->set_state(this->state); + this->set_mutable_state(this->mutable_state); + active_fb->apply_state(); +}; + void GLStateManager::set_state(const GPUState &state) { GPUState changed = state ^ current_; @@ -125,22 +133,6 @@ void GLStateManager::set_mutable_state(const GPUStateMutable &state) { GPUStateMutable changed = state ^ current_mutable_; - if ((changed.viewport_rect[0] != 0) || (changed.viewport_rect[1] != 0) || - (changed.viewport_rect[2] != 0) || (changed.viewport_rect[3] != 0)) { - glViewport(UNPACK4(state.viewport_rect)); - } - - if ((changed.scissor_rect[0] != 0) || (changed.scissor_rect[1] != 0) || - (changed.scissor_rect[2] != 0) || (changed.scissor_rect[3] != 0)) { - if ((state.scissor_rect[2] > 0)) { - glScissor(UNPACK4(state.scissor_rect)); - glEnable(GL_SCISSOR_TEST); - } - else { - glDisable(GL_SCISSOR_TEST); - } - } - /* TODO remove, should be uniform. */ if (changed.point_size != 0) { if (state.point_size > 0.0f) { diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh index 8e806cb3e7a..c25e384fcd7 100644 --- a/source/blender/gpu/opengl/gl_state.hh +++ b/source/blender/gpu/opengl/gl_state.hh @@ -31,11 +31,17 @@ namespace blender { namespace gpu { +class GLFrameBuffer; + /** * State manager keeping track of the draw state and applying it before drawing. * Opengl Implementation. **/ class GLStateManager : public GPUStateManager { + public: + /** Anothter reference to tje active framebuffer. */ + GLFrameBuffer *active_fb; + private: /** Current state of the GL implementation. Avoids resetting the whole state for every change. */ GPUState current_; @@ -46,8 +52,7 @@ class GLStateManager : public GPUStateManager { public: GLStateManager(); - void set_state(const GPUState &state) override; - void set_mutable_state(const GPUStateMutable &state) override; + void apply_state(void) override; private: static void set_write_mask(const eGPUWriteMask value); @@ -62,6 +67,9 @@ class GLStateManager : public GPUStateManager { static void set_shadow_bias(const bool enable); static void set_blend(const eGPUBlend value); + void set_state(const GPUState &state); + void set_mutable_state(const GPUStateMutable &state); + MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager") }; |