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-16 21:56:39 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-08-18 22:30:10 +0300
commitf30df15edc0b5bfce98809cfa8c2ca96cfe03e97 (patch)
tree3b5fb309ed8a39e64a576cc6631d2866ca5318ac /source/blender/gpu/intern
parent298329554a5a0ae40bc4a64ca9c1490d22edc947 (diff)
GPUState: Make use of GPUStateStack class
This isolate most GL calls to the GL backend. Still a few remains.
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_context.cc1
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh3
-rw-r--r--source/blender/gpu/intern/gpu_state.cc258
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh2
4 files changed, 150 insertions, 114 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index e04631910c1..da12a58ba87 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -70,6 +70,7 @@ GPUContext::GPUContext()
GPUContext::~GPUContext()
{
GPU_matrix_state_discard(matrix_state);
+ delete state_stack;
}
bool GPUContext::is_active_on_thread(void)
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index 3f9fca16ff7..04785187e8b 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -29,6 +29,8 @@
#include "GPU_context.h"
+#include "gpu_state_private.hh"
+
#include <mutex>
#include <pthread.h>
#include <string.h>
@@ -44,6 +46,7 @@ struct GPUContext {
GPUShader *shader = NULL;
GPUFrameBuffer *current_fbo = NULL;
GPUMatrixState *matrix_state = NULL;
+ blender::gpu::GPUStateStack *state_stack = NULL;
protected:
/** Thread on which this context is active. */
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index 4c3b2cc119e..6d3d74e60f3 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -25,6 +25,7 @@
# define PIXELSIZE (1.0f)
#endif
+#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BKE_global.h"
@@ -33,6 +34,8 @@
#include "GPU_glew.h"
#include "GPU_state.h"
+#include "gpu_context_private.hh"
+
#include "gpu_state_private.hh"
/* TODO remove */
@@ -40,194 +43,198 @@
using namespace blender::gpu;
+#define SET_STATE(_prefix, _state, _value) \
+ do { \
+ GPUStateStack *stack = GPU_context_active_get()->state_stack; \
+ auto &state_object = stack->_prefix##stack_top_get(); \
+ state_object._state = _value; \
+ /* TODO remove this and only push state at draw time. */ \
+ stack->set_##_prefix##state(state_object); \
+ } while (0)
+
+#define SET_IMMUTABLE_STATE(_state, _value) SET_STATE(, _state, _value)
+#define SET_MUTABLE_STATE(_state, _value) SET_STATE(mutable_, _state, _value)
+
+/* -------------------------------------------------------------------- */
+/** \name Immutable state Setters
+ * \{ */
+
void GPU_blend(eGPUBlend blend)
{
- GLStateStack::set_blend(blend);
+ SET_IMMUTABLE_STATE(blend, blend);
}
void GPU_face_culling(eGPUFaceCullTest culling)
{
- if (culling == GPU_CULL_NONE) {
- glDisable(GL_CULL_FACE);
- }
- else {
- glEnable(GL_CULL_FACE);
- glCullFace((culling == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK);
- }
+ SET_IMMUTABLE_STATE(culling_test, culling);
}
void GPU_front_facing(bool invert)
{
- glFrontFace((invert) ? GL_CW : GL_CCW);
+ SET_IMMUTABLE_STATE(invert_facing, invert);
}
void GPU_provoking_vertex(eGPUProvokingVertex vert)
{
- glProvokingVertex((vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
- GL_LAST_VERTEX_CONVENTION);
-}
-
-void GPU_depth_range(float near, float far)
-{
- /* glDepthRangef is only for OpenGL 4.1 or higher */
- glDepthRange(near, far);
+ SET_IMMUTABLE_STATE(provoking_vert, vert);
}
+/* TODO explicit depth test. */
void GPU_depth_test(bool enable)
{
- if (enable) {
- glEnable(GL_DEPTH_TEST);
- }
- else {
- glDisable(GL_DEPTH_TEST);
- }
-}
-
-bool GPU_depth_test_enabled()
-{
- return glIsEnabled(GL_DEPTH_TEST);
+ SET_IMMUTABLE_STATE(depth_test, (enable) ? GPU_DEPTH_LESS : GPU_DEPTH_NONE);
}
void GPU_line_smooth(bool enable)
{
- if (enable && ((G.debug & G_DEBUG_GPU) == 0)) {
- glEnable(GL_LINE_SMOOTH);
- }
- else {
- glDisable(GL_LINE_SMOOTH);
- }
+ SET_IMMUTABLE_STATE(line_smooth, enable);
}
-void GPU_line_width(float width)
+void GPU_polygon_smooth(bool enable)
{
- float max_size = GPU_max_line_width();
- float final_size = width * PIXELSIZE;
- /* Fix opengl errors on certain platform / drivers. */
- CLAMP(final_size, 1.0f, max_size);
- glLineWidth(final_size);
+ SET_IMMUTABLE_STATE(polygon_smooth, enable);
}
-void GPU_point_size(float size)
+void GPU_logic_op_xor_set(bool enable)
{
- glPointSize(size * PIXELSIZE);
+ SET_IMMUTABLE_STATE(logic_op_xor, enable);
}
-void GPU_polygon_smooth(bool enable)
+void GPU_color_mask(bool r, bool g, bool b, bool a)
{
- if (enable && ((G.debug & G_DEBUG_GPU) == 0)) {
- glEnable(GL_POLYGON_SMOOTH);
- }
- else {
- glDisable(GL_POLYGON_SMOOTH);
- }
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->stack_top_get();
+ eGPUWriteMask write_mask = state.write_mask;
+ SET_FLAG_FROM_TEST(write_mask, r, GPU_WRITE_RED);
+ SET_FLAG_FROM_TEST(write_mask, g, GPU_WRITE_GREEN);
+ SET_FLAG_FROM_TEST(write_mask, b, GPU_WRITE_BLUE);
+ SET_FLAG_FROM_TEST(write_mask, a, GPU_WRITE_ALPHA);
+ state.write_mask = write_mask;
+ /* TODO remove this and only push state at draw time. */
+ stack->set_state(state);
}
-/* Programmable point size
- * - shaders set their own point size when enabled
- * - use glPointSize when disabled */
-void GPU_program_point_size(bool enable)
+void GPU_depth_mask(bool depth)
{
- if (enable) {
- glEnable(GL_PROGRAM_POINT_SIZE);
- }
- else {
- glDisable(GL_PROGRAM_POINT_SIZE);
- }
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->stack_top_get();
+ eGPUWriteMask write_mask = state.write_mask;
+ SET_FLAG_FROM_TEST(write_mask, depth, GPU_WRITE_DEPTH);
+ state.write_mask = write_mask;
+ /* TODO remove this and only push state at draw time. */
+ stack->set_state(state);
}
-void GPU_scissor_test(bool enable)
+void GPU_clip_distances(int distances_enabled)
{
- if (enable) {
- glEnable(GL_SCISSOR_TEST);
- }
- else {
- glDisable(GL_SCISSOR_TEST);
- }
+ SET_IMMUTABLE_STATE(clip_distances, distances_enabled);
}
-void GPU_scissor(int x, int y, int width, int height)
-{
- glScissor(x, y, width, height);
-}
+/** \} */
-void GPU_viewport(int x, int y, int width, int height)
-{
- glViewport(x, y, width, height);
-}
+/* -------------------------------------------------------------------- */
+/** \name Mutable State Setters
+ * \{ */
-void GPU_scissor_get(int coords[4])
+void GPU_depth_range(float near, float far)
{
- glGetIntegerv(GL_SCISSOR_BOX, coords);
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->mutable_stack_top_get();
+ copy_v2_fl2(state.depth_range, near, far);
+ /* TODO remove this and only push state at draw time. */
+ stack->set_mutable_state(state);
}
-void GPU_viewport_size_get_f(float coords[4])
+void GPU_line_width(float width)
{
- glGetFloatv(GL_VIEWPORT, coords);
+ SET_MUTABLE_STATE(line_width, width * PIXELSIZE);
}
-void GPU_viewport_size_get_i(int coords[4])
+void GPU_point_size(float size)
{
- glGetIntegerv(GL_VIEWPORT, coords);
+ SET_MUTABLE_STATE(point_size, size * PIXELSIZE);
}
-void GPU_flush(void)
+/* Programmable point size
+ * - shaders set their own point size when enabled
+ * - use glPointSize when disabled */
+/* TODO remove and use program point size everywhere */
+void GPU_program_point_size(bool enable)
{
- glFlush();
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->mutable_stack_top_get();
+ /* Set point size sign negative to disable. */
+ state.point_size = fabsf(state.point_size) * (enable ? 1 : -1);
+ /* TODO remove this and only push state at draw time. */
+ stack->set_mutable_state(state);
}
-void GPU_finish(void)
+void GPU_scissor_test(bool enable)
{
- glFinish();
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->mutable_stack_top_get();
+ /* Set point size sign negative to disable. */
+ state.scissor_rect[2] = abs(state.scissor_rect[2]) * (enable ? 1 : -1);
+ /* TODO remove this and only push state at draw time. */
+ stack->set_mutable_state(state);
}
-void GPU_unpack_row_length_set(uint len)
+void GPU_scissor(int x, int y, int width, int height)
{
- glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->mutable_stack_top_get();
+ int scissor_rect[4] = {x, y, width, height};
+ copy_v4_v4_int(state.scissor_rect, scissor_rect);
+ /* TODO remove this and only push state at draw time. */
+ stack->set_mutable_state(state);
}
-void GPU_logic_op_xor_set(bool enable)
+void GPU_viewport(int x, int y, int width, int height)
{
- if (enable) {
- glLogicOp(GL_XOR);
- glEnable(GL_COLOR_LOGIC_OP);
- }
- else {
- glDisable(GL_COLOR_LOGIC_OP);
- }
+ GPUStateStack *stack = GPU_context_active_get()->state_stack;
+ auto &state = stack->mutable_stack_top_get();
+ int viewport_rect[4] = {x, y, width, height};
+ copy_v4_v4_int(state.viewport_rect, viewport_rect);
+ /* TODO remove this and only push state at draw time. */
+ stack->set_mutable_state(state);
}
-void GPU_color_mask(bool r, bool g, bool b, bool a)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name State Getters
+ * \{ */
+
+bool GPU_depth_test_enabled()
{
- glColorMask(r, g, b, a);
+ GPUState &state = GPU_context_active_get()->state_stack->stack_top_get();
+ return state.depth_test != GPU_DEPTH_NONE;
}
-void GPU_depth_mask(bool depth)
+void GPU_scissor_get(int coords[4])
{
- glDepthMask(depth);
+ GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get();
+ copy_v4_v4_int(coords, state.scissor_rect);
}
-bool GPU_depth_mask_get(void)
+void GPU_viewport_size_get_f(float coords[4])
{
- GLint mask;
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask);
- return mask == GL_TRUE;
+ GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get();
+ for (int i = 0; i < 4; i++) {
+ coords[i] = state.viewport_rect[i];
+ }
}
-void GPU_stencil_mask(uint stencil)
+void GPU_viewport_size_get_i(int coords[4])
{
- glStencilMask(stencil);
+ GPUStateMutable &state = GPU_context_active_get()->state_stack->mutable_stack_top_get();
+ copy_v4_v4_int(coords, state.viewport_rect);
}
-void GPU_clip_distances(int distances_new)
+bool GPU_depth_mask_get(void)
{
- static int distances_enabled = 0;
- for (int i = 0; i < distances_new; i++) {
- glEnable(GL_CLIP_DISTANCE0 + i);
- }
- for (int i = distances_new; i < distances_enabled; i++) {
- glDisable(GL_CLIP_DISTANCE0 + i);
- }
- distances_enabled = distances_new;
+ GPUState &state = GPU_context_active_get()->state_stack->stack_top_get();
+ return (state.write_mask & GPU_WRITE_DEPTH) != 0;
}
bool GPU_mipmap_enabled(void)
@@ -236,8 +243,10 @@ bool GPU_mipmap_enabled(void)
return true;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/** \name Draw State (DRW_state)
+/** \name GPUStateStack
* \{ */
void GPUStateStack::push_stack(void)
@@ -265,6 +274,27 @@ void GPUStateStack::pop_mutable_stack(void)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Context Utils
+ * \{ */
+
+void GPU_flush(void)
+{
+ glFlush();
+}
+
+void GPU_finish(void)
+{
+ glFinish();
+}
+
+void GPU_unpack_row_length_set(uint len)
+{
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name GPU Push/Pop State
* \{ */
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index 0ac538d117c..31840724ec0 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -137,6 +137,8 @@ class GPUStateStack {
int mutable_stack_top = 0;
public:
+ virtual ~GPUStateStack(){};
+
virtual void set_state(GPUState &state) = 0;
virtual void set_mutable_state(GPUStateMutable &state) = 0;