[Bf-blender-cvs] [bf3f4da9472] master: GPU: Fix wrong state before python callbacks

Clément Foucault noreply at git.blender.org
Sat Sep 12 17:35:42 CEST 2020


Commit: bf3f4da9472516be12dcc69740fa69b6d72f1274
Author: Clément Foucault
Date:   Sat Sep 12 17:29:37 2020 +0200
Branches: master
https://developer.blender.org/rBbf3f4da9472516be12dcc69740fa69b6d72f1274

GPU: Fix wrong state before python callbacks

This was caused by a missing state apply.

We force the GPUState to be set after the callbacks to avoid
desync between our state tracker and the real gl state.

This fixes some issues but a better general fix for all BGL would
be better.

This fix T80297 2.91 texture alpha is not transparent

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

M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/space_api/CMakeLists.txt
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_state.cc
M	source/blender/gpu/opengl/gl_state.hh

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

diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 203f8af130d..834505ca349 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1365,6 +1365,8 @@ void DRW_draw_callbacks_pre_scene(void)
 
   if (DST.draw_ctx.evil_C) {
     ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_PRE_VIEW);
+    /* Callback can be nasty and do whatever they want with the state.
+     * Don't trust them! */
     DRW_state_reset();
   }
 }
@@ -1400,6 +1402,9 @@ void DRW_draw_callbacks_post_scene(void)
     drw_debug_draw();
 
     GPU_depth_test(GPU_DEPTH_NONE);
+    /* Apply state for callbacks. */
+    GPU_apply_state();
+
     ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW);
 
     /* Callback can be nasty and do whatever they want with the state.
diff --git a/source/blender/editors/space_api/CMakeLists.txt b/source/blender/editors/space_api/CMakeLists.txt
index d948d84f1c3..573afb76f0e 100644
--- a/source/blender/editors/space_api/CMakeLists.txt
+++ b/source/blender/editors/space_api/CMakeLists.txt
@@ -20,6 +20,7 @@ set(INC
   ../io
   ../../blenkernel
   ../../blenlib
+  ../../gpu
   ../../makesdna
   ../../makesrna
   ../../windowmanager
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 29ad314cd65..2a18ffafc6c 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -33,6 +33,8 @@
 #include "BKE_context.h"
 #include "BKE_screen.h"
 
+#include "GPU_state.h"
+
 #include "UI_interface.h"
 #include "UI_view2d.h"
 
@@ -269,12 +271,18 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
 void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
 {
   RegionDrawCB *rdc;
+  bool has_drawn_something = false;
 
   for (rdc = region->type->drawcalls.first; rdc; rdc = rdc->next) {
     if (rdc->type == type) {
       rdc->draw(C, region, rdc->customdata);
+      has_drawn_something = true;
     }
   }
+  if (has_drawn_something) {
+    /* This is needed until we get rid of BGL which can change the states we are tracking. */
+    GPU_force_state();
+  }
 }
 
 /* ********************* space template *********************** */
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index aa32c6c75ba..a857736acd5 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -159,6 +159,8 @@ eGPUStencilTest GPU_stencil_test_get(void);
 
 void GPU_flush(void);
 void GPU_finish(void);
+void GPU_apply_state(void);
+void GPU_force_state(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 a3d07b1e1db..b63abb3d57f 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -305,6 +305,17 @@ void GPU_finish(void)
   Context::get()->finish();
 }
 
+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)
+{
+  Context::get()->state_manager->force_state();
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -319,12 +330,7 @@ void GPU_memory_barrier(eGPUBarrier barrier)
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Default OpenGL State
- *
- * This is called on startup, for opengl offscreen render.
- * Generally we should always return to this state when
- * temporarily modifying the state for drawing, though that are (undocumented)
- * exceptions that we should try to get rid of.
+/** \name Default State
  * \{ */
 
 StateManager::StateManager(void)
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index d85375a85bb..b8d247ec175 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -159,6 +159,7 @@ class StateManager {
   virtual ~StateManager(){};
 
   virtual void apply_state(void) = 0;
+  virtual void force_state(void) = 0;
 
   virtual void issue_barrier(eGPUBarrier barrier_bits) = 0;
 
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 3c577bf1ccd..cd24fa0e0e4 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -80,6 +80,17 @@ void GLStateManager::apply_state(void)
   active_fb->apply_state();
 };
 
+void GLStateManager::force_state(void)
+{
+  /* Little exception for clip distances since they need to keep the old count correct. */
+  uint32_t clip_distances = current_.clip_distances;
+  current_ = ~this->state;
+  current_.clip_distances = clip_distances;
+  current_mutable_ = ~this->mutable_state;
+  this->set_state(this->state);
+  this->set_mutable_state(this->mutable_state);
+};
+
 void GLStateManager::set_state(const GPUState &state)
 {
   GPUState changed = state ^ current_;
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index b98c4b300f3..cab654006c6 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -72,6 +72,7 @@ class GLStateManager : public StateManager {
   GLStateManager();
 
   void apply_state(void) override;
+  void force_state(void) override;
 
   void issue_barrier(eGPUBarrier barrier_bits) override;



More information about the Bf-blender-cvs mailing list