[Bf-blender-cvs] [f30df15edc0] master: GPUState: Make use of GPUStateStack class

Clément Foucault noreply at git.blender.org
Tue Aug 18 21:31:01 CEST 2020


Commit: f30df15edc0b5bfce98809cfa8c2ca96cfe03e97
Author: Clément Foucault
Date:   Sun Aug 16 20:56:39 2020 +0200
Branches: master
https://developer.blender.org/rBf30df15edc0b5bfce98809cfa8c2ca96cfe03e97

GPUState: Make use of GPUStateStack class

This isolate most GL calls to the GL backend. Still a few remains.

===================================================================

M	source/blender/gpu/GPU_state.h
M	source/blender/gpu/intern/gpu_context.cc
M	source/blender/gpu/intern/gpu_context_private.hh
M	source/blender/gpu/intern/gpu_state.cc
M	source/blender/gpu/intern/gpu_state_private.hh
M	source/blender/gpu/opengl/gl_context.cc
M	source/blender/gpu/opengl/gl_state.cc
M	source/blender/gpu/opengl/gl_state.hh

===================================================================

diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 0aeb4df8b77..39b52567a46 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -20,6 +20,8 @@
 
 #pragma once
 
+#include "BLI_utildefines.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -33,6 +35,8 @@ typedef enum eGPUWriteMask {
   GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA),
 } eGPUWriteMask;
 
+ENUM_OPERATORS(eGPUWriteMask)
+
 /**
  * Defines the fixed pipeline blending equation.
  * SRC is the output color from the shader.
@@ -126,7 +130,6 @@ void GPU_viewport_size_get_i(int coords[4]);
 void GPU_color_mask(bool r, bool g, bool b, bool a);
 void GPU_depth_mask(bool depth);
 bool GPU_depth_mask_get(void);
-void GPU_stencil_mask(uint stencil);
 void GPU_unpack_row_length_set(uint len);
 void GPU_clip_distances(int enabled_len);
 bool GPU_mipmap_enabled(void);
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_to

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list