[Bf-blender-cvs] [c7653fad678] temp-vr-draw-thread: Manage GPU_matrix stacks per GPUContext

Julian Eisel noreply at git.blender.org
Sat Aug 3 00:53:23 CEST 2019


Commit: c7653fad678a32663bc4b153ada343f52ca76fe5
Author: Julian Eisel
Date:   Fri Aug 2 18:04:54 2019 +0200
Branches: temp-vr-draw-thread
https://developer.blender.org/rBc7653fad678a32663bc4b153ada343f52ca76fe5

Manage GPU_matrix stacks per GPUContext

Previous global GPU_matrix stacks weren't safe for access from multiple
threads. With this, GPU_matrix stacks are concurrent in combination
with GPUContext.
Needed for VR session drawing on a separate thread.

Reviewers: fclem, brecht

Differential Revision: https://developer.blender.org/D5405

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

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/intern/gpu_context.cpp
M	source/blender/gpu/intern/gpu_context_private.h
M	source/blender/gpu/intern/gpu_matrix.c
A	source/blender/gpu/intern/gpu_matrix_private.h

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index c620644a5f8..fb7d3c1ace8 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -116,6 +116,7 @@ set(SRC
   intern/gpu_batch_private.h
   intern/gpu_codegen.h
   intern/gpu_context_private.h
+  intern/gpu_matrix_private.h
   intern/gpu_primitive_private.h
   intern/gpu_private.h
   intern/gpu_select_private.h
diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp
index a0e03e61d5d..12a5748b198 100644
--- a/source/blender/gpu/intern/gpu_context.cpp
+++ b/source/blender/gpu/intern/gpu_context.cpp
@@ -36,6 +36,7 @@
 
 #include "gpu_batch_private.h"
 #include "gpu_context_private.h"
+#include "gpu_matrix_private.h"
 
 #include <vector>
 #include <string.h>
@@ -71,6 +72,7 @@ struct GPUContext {
   std::unordered_set<GPUFrameBuffer *>
       framebuffers; /* Framebuffers that have FBO from this context */
 #endif
+  struct GPUMatrixState *matrix_state;
   std::vector<GLuint> orphaned_vertarray_ids;
   std::vector<GLuint> orphaned_framebuffer_ids;
   std::mutex orphans_mutex; /* todo: try spinlock instead */
@@ -144,6 +146,7 @@ GPUContext *GPU_context_create(GLuint default_framebuffer)
   GPUContext *ctx = new GPUContext;
   glGenVertexArrays(1, &ctx->default_vao);
   ctx->default_framebuffer = default_framebuffer;
+  ctx->matrix_state = GPU_matrix_state_create();
   GPU_context_active_set(ctx);
   return ctx;
 }
@@ -164,6 +167,7 @@ void GPU_context_discard(GPUContext *ctx)
     /* this removes the array entry */
     GPU_batch_vao_cache_clear(*ctx->batches.begin());
   }
+  GPU_matrix_state_discard(ctx->matrix_state);
   glDeleteVertexArrays(1, &ctx->default_vao);
   delete ctx;
   active_ctx = NULL;
@@ -338,3 +342,9 @@ GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx)
 {
   return ctx->current_fbo;
 }
+
+struct GPUMatrixState *gpu_context_active_matrix_state_get()
+{
+  BLI_assert(active_ctx);
+  return active_ctx->matrix_state;
+}
diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h
index 6825b67d2c8..09248e45502 100644
--- a/source/blender/gpu/intern/gpu_context_private.h
+++ b/source/blender/gpu/intern/gpu_context_private.h
@@ -59,6 +59,8 @@ void gpu_context_remove_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb);
 void gpu_context_active_framebuffer_set(GPUContext *ctx, struct GPUFrameBuffer *fb);
 struct GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx);
 
+struct GPUMatrixState *gpu_context_active_matrix_state_get();
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index 58ca800a92c..fb0dffb58d1 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -23,6 +23,9 @@
 
 #include "GPU_shader_interface.h"
 
+#include "gpu_context_private.h"
+#include "gpu_matrix_private.h"
+
 #define SUPPRESS_GENERIC_MATRIX_API
 #define USE_GPU_PY_MATRIX_API /* only so values are declared */
 #include "GPU_matrix.h"
@@ -32,6 +35,8 @@
 #include "BLI_math_rotation.h"
 #include "BLI_math_vector.h"
 
+#include "MEM_guardedalloc.h"
+
 #define DEBUG_MATRIX_BIND 0
 
 #define MATRIX_STACK_DEPTH 32
@@ -44,7 +49,7 @@ typedef struct MatrixStack {
   uint top;
 } MatrixStack;
 
-typedef struct {
+typedef struct GPUMatrixState {
   MatrixStack model_view_stack;
   MatrixStack projection_stack;
 
@@ -56,8 +61,16 @@ typedef struct {
    * TODO: separate Model from View transform? Batches/objects have model,
    * camera/eye has view & projection
    */
-} MatrixState;
+} GPUMatrixState;
+
+#define ModelViewStack gpu_context_active_matrix_state_get()->model_view_stack
+#define ModelView ModelViewStack.stack[ModelViewStack.top]
 
+#define ProjectionStack gpu_context_active_matrix_state_get()->projection_stack
+#define Projection ProjectionStack.stack[ProjectionStack.top]
+
+GPUMatrixState *GPU_matrix_state_create(void)
+{
 #define MATRIX_4X4_IDENTITY \
   { \
     {1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, \
@@ -66,27 +79,36 @@ typedef struct {
     } \
   }
 
-static MatrixState state = {
-    .model_view_stack = {{MATRIX_4X4_IDENTITY}, 0},
-    .projection_stack = {{MATRIX_4X4_IDENTITY}, 0},
-    .dirty = true,
-};
+  GPUMatrixState *state = MEM_mallocN(sizeof(*state), __func__);
+  const MatrixStack identity_stack = {{MATRIX_4X4_IDENTITY}, 0};
+
+  state->model_view_stack = state->projection_stack = identity_stack;
+  state->dirty = true;
 
 #undef MATRIX_4X4_IDENTITY
 
-#define ModelViewStack state.model_view_stack
-#define ModelView ModelViewStack.stack[ModelViewStack.top]
+  return state;
+}
 
-#define ProjectionStack state.projection_stack
-#define Projection ProjectionStack.stack[ProjectionStack.top]
+void GPU_matrix_state_discard(GPUMatrixState *state)
+{
+  MEM_freeN(state);
+}
+
+static void gpu_matrix_state_active_set_dirty(bool value)
+{
+  GPUMatrixState *state = gpu_context_active_matrix_state_get();
+  state->dirty = value;
+}
 
 void GPU_matrix_reset(void)
 {
-  state.model_view_stack.top = 0;
-  state.projection_stack.top = 0;
+  GPUMatrixState *state = gpu_context_active_matrix_state_get();
+  state->model_view_stack.top = 0;
+  state->projection_stack.top = 0;
   unit_m4(ModelView);
   unit_m4(Projection);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 #ifdef WITH_GPU_SAFETY
@@ -123,7 +145,7 @@ void GPU_matrix_pop(void)
 {
   BLI_assert(ModelViewStack.top > 0);
   ModelViewStack.top--;
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_push_projection(void)
@@ -137,34 +159,34 @@ void GPU_matrix_pop_projection(void)
 {
   BLI_assert(ProjectionStack.top > 0);
   ProjectionStack.top--;
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_set(const float m[4][4])
 {
   copy_m4_m4(ModelView, m);
   CHECKMAT(ModelView3D);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_identity_projection_set(void)
 {
   unit_m4(Projection);
   CHECKMAT(Projection3D);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_projection_set(const float m[4][4])
 {
   copy_m4_m4(Projection, m);
   CHECKMAT(Projection3D);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_identity_set(void)
 {
   unit_m4(ModelView);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_translate_2f(float x, float y)
@@ -194,7 +216,7 @@ void GPU_matrix_translate_3f(float x, float y, float z)
   m[3][2] = z;
   GPU_matrix_mul(m);
 #endif
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_translate_3fv(const float vec[3])
@@ -243,7 +265,7 @@ void GPU_matrix_mul(const float m[4][4])
 {
   mul_m4_m4_post(ModelView, m);
   CHECKMAT(ModelView);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_rotate_2d(float deg)
@@ -272,7 +294,7 @@ void GPU_matrix_rotate_axis(float deg, char axis)
   /* rotate_m4 works in place */
   rotate_m4(ModelView, axis, DEG2RADF(deg));
   CHECKMAT(ModelView);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 static void mat4_ortho_set(
@@ -298,7 +320,7 @@ static void mat4_ortho_set(
   m[2][3] = 0.0f;
   m[3][3] = 1.0f;
 
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 static void mat4_frustum_set(
@@ -324,7 +346,7 @@ static void mat4_frustum_set(
   m[2][3] = -1.0f;
   m[3][3] = 0.0f;
 
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 static void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3])
@@ -389,14 +411,14 @@ static void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3
   m[2][3] = 0.0f;
   m[3][3] = 1.0f;
 
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_ortho_set(float left, float right, float bottom, float top, float near, float far)
 {
   mat4_ortho_set(Projection, left, right, bottom, top, near, far);
   CHECKMAT(Projection);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top)
@@ -404,7 +426,7 @@ void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top)
   Mat4 m;
   mat4_ortho_set(m, left, right, bottom, top, -1.0f, 1.0f);
   CHECKMAT(Projection2D);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_frustum_set(
@@ -412,7 +434,7 @@ void GPU_matrix_frustum_set(
 {
   mat4_frustum_set(Projection, left, right, bottom, top, near, far);
   CHECKMAT(Projection);
-  state.dirty = true;
+  gpu_matrix_state_active_set_dirty(true);
 }
 
 void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far)
@@ -678,12 +700,13 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface)
     glUniformMatrix4fv(P_inv->location, 1, GL_FALSE, (const float *)m);
   }
 
-  state.dirty = false;
+  gpu_matrix_state_active_set_dirty(false);
 }
 
 bool GPU_matrix_dirty_get(void)
 {
-  return state.dirty;
+  GPUMatrixState *state = gpu_context_active_matrix_state_get();
+  return state->dirty;
 }
 
 /* -------------------------------------------------------------------- */
@@ -695,12 +718,14 @@ BLI_STATIC_ASSERT(GPU_PY_MATRIX_STACK_LEN + 1 == MATRIX_STACK_DEPTH, "define mis
 
 int GPU_matrix_stack_level_get_model_view(void)
 {
-  return (int)state.model_view_stack.top;
+  GPUMatrixState *state = gpu_context_active_matrix_state_get();
+  return (int)state->model_view_stack.top;
 }
 
 int GPU_matrix_stack_level_get_projection(void)
 {
-  return (int)state.projection_stack.top;
+  GPUMatrixState *state = gpu_context_active_matrix_state_get();
+  return (int)state->projection_stack.top;
 }
 
 /** \} */
diff --git a/source/blender/gpu/intern/gpu_matrix_private.h b/source/blender/gpu/intern/gpu_matrix_private.h
new file mode 100644
index 00000000000..862ef065481
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_matrix_private.h
@@ -0,0 +1,35 @@
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list