[Bf-blender-cvs] [f12b0373f32] master: BGL: Workaround broken bgl usage caused by GPU refactor

Clément Foucault noreply at git.blender.org
Thu Oct 8 16:37:37 CEST 2020


Commit: f12b0373f322b710b9fa5cebb67bdf363ff90e9f
Author: Clément Foucault
Date:   Thu Oct 8 16:19:42 2020 +0200
Branches: master
https://developer.blender.org/rBf12b0373f322b710b9fa5cebb67bdf363ff90e9f

BGL: Workaround broken bgl usage caused by GPU refactor

This directly adress the issues caused by rB536c2e0ec916.

Since the state tracking is done at a lower level, using the bgl
functions needs to be safegarded by the state manager.
The current workaround is to bypass `apply_state` when inside a
callback that used a `bgl` function.

Related to T80730.

This fix T81003.

Also this fix the default blend equation for callbacks.
Fixes T80169 T81289.

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

M	source/blender/editors/space_api/spacetypes.c
M	source/blender/gpu/GPU_state.h
M	source/blender/gpu/intern/gpu_state.cc
M	source/blender/gpu/intern/gpu_state_private.hh
M	source/blender/gpu/opengl/gl_debug.cc
M	source/blender/gpu/opengl/gl_state.cc
M	source/blender/python/generic/bgl.c

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

diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 2a18ffafc6c..b89c8cb2193 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -281,7 +281,7 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
   }
   if (has_drawn_something) {
     /* This is needed until we get rid of BGL which can change the states we are tracking. */
-    GPU_force_state();
+    GPU_bgl_end();
   }
 }
 
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 04cf7bc54ba..471edfb7b8f 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -161,7 +161,10 @@ float GPU_line_width_get(void);
 void GPU_flush(void);
 void GPU_finish(void);
 void GPU_apply_state(void);
-void GPU_force_state(void);
+
+void GPU_bgl_start(void);
+void GPU_bgl_end(void);
+bool GPU_bgl_get(void);
 
 void GPU_memory_barrier(eGPUBarrier barrier);
 
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index 44ad9cc9a84..44cc11155bb 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -317,10 +317,39 @@ void GPU_apply_state(void)
   Context::get()->state_manager->apply_state();
 }
 
-/* Will set all the states regardless of the current ones. */
-void GPU_force_state(void)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name BGL workaround
+ *
+ * bgl makes direct GL calls that makes our state tracking out of date.
+ * This flag make it so that the pyGPU calls will not override the state set by
+ * bgl functions.
+ * \{ */
+
+void GPU_bgl_start(void)
+{
+  StateManager &state_manager = *(Context::get()->state_manager);
+  if (state_manager.use_bgl == false) {
+    /* Expected by many addons (see T80169, T81289).
+     * This will reset the blend function. */
+    GPU_blend(GPU_BLEND_NONE);
+    state_manager.apply_state();
+    state_manager.use_bgl = true;
+  }
+}
+
+void GPU_bgl_end(void)
+{
+  StateManager &state_manager = *(Context::get()->state_manager);
+  state_manager.use_bgl = false;
+  /* Resync state tracking. */
+  state_manager.force_state();
+}
+
+bool GPU_bgl_get(void)
 {
-  Context::get()->state_manager->force_state();
+  return Context::get()->state_manager->use_bgl;
 }
 
 /** \} */
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index d93556a1058..db1747127d4 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -153,6 +153,7 @@ class StateManager {
  public:
   GPUState state;
   GPUStateMutable mutable_state;
+  bool use_bgl = false;
 
  public:
   StateManager();
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index 797f9ff404c..b2b05124463 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -200,7 +200,7 @@ void check_gl_error(const char *info)
 
 void check_gl_resources(const char *info)
 {
-  if (!(G.debug & G_DEBUG_GPU)) {
+  if (!(G.debug & G_DEBUG_GPU) || GPU_bgl_get()) {
     return;
   }
 
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index cd24fa0e0e4..27c9b501add 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -73,13 +73,17 @@ GLStateManager::GLStateManager(void) : StateManager()
 
 void GLStateManager::apply_state(void)
 {
-  this->set_state(this->state);
-  this->set_mutable_state(this->mutable_state);
-  this->texture_bind_apply();
-  this->image_bind_apply();
+  if (!this->use_bgl) {
+    this->set_state(this->state);
+    this->set_mutable_state(this->mutable_state);
+    this->texture_bind_apply();
+    this->image_bind_apply();
+  }
+  /* This is needed by gpu_py_offscreen. */
   active_fb->apply_state();
 };
 
+/* Will set all the states regardless of the current ones. */
 void GLStateManager::force_state(void)
 {
   /* Little exception for clip distances since they need to keep the old count correct. */
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 8a5c4f4a11b..e9a58288c5e 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -29,6 +29,8 @@
 #include "BLI_utildefines.h"
 #include "MEM_guardedalloc.h"
 
+#include "GPU_state.h"
+
 #include "../generic/py_capi_utils.h"
 
 #include "glew-mx.h"
@@ -1109,6 +1111,7 @@ static PyObject *Buffer_repr(Buffer *self)
     if (!PyArg_ParseTuple(args, arg_str arg_list, arg_ref arg_list)) { \
       return NULL; \
     } \
+    GPU_bgl_start(); \
     ret_set_##ret gl##funcname(arg_var arg_list); \
     ret_ret_##ret; \
   }



More information about the Bf-blender-cvs mailing list