Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-08-29 16:17:13 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-30 14:11:03 +0300
commit8527d84d3588563123bfad7ccbdeeff62ee90bdb (patch)
tree51ccbaa3c129c62a54af5aed43b55b9c89b901e6 /source/blender/gpu/opengl
parent4f395c84fe9f05b59b81be36b464521bcf92331e (diff)
GPUState: Move Scissor and Viewport state to framebuffer
This way it is way clearer what each viewport state is. There is no more save and reset. The scissor test is also saved per framebuffer. The only rule to remember is that the viewport state (size and origin) is reset for both the viewport and scissor when a texture is attached or detached from an attachment slot.
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r--source/blender/gpu/opengl/gl_context.cc2
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.cc59
-rw-r--r--source/blender/gpu/opengl/gl_framebuffer.hh6
-rw-r--r--source/blender/gpu/opengl/gl_state.cc24
-rw-r--r--source/blender/gpu/opengl/gl_state.hh12
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")
};