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.
This commit is contained in:
Clément Foucault 2020-10-08 16:19:42 +02:00
parent 5f364216ac
commit f12b0373f3
Notes: blender-bot 2023-02-14 18:48:55 +01:00
Referenced by commit f23bf4cb10, Revert "BGL: Workaround broken bgl usage caused by GPU refactor"
Referenced by issue #81784, 2D Gizmo glitch when using glEnable/glDisable (Blender 2.91)
Referenced by issue #81289, Python gpu bgl image drawing alpha problem
Referenced by issue #81003, First image drawn with the Python gpu module may be black
Referenced by issue #80169, Node wrangler highlighting artifacts
Referenced by issue blender/blender-addons#80730, BGL deprecation
7 changed files with 50 additions and 10 deletions

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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)
{
Context::get()->state_manager->force_state();
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)
{
return Context::get()->state_manager->use_bgl;
}
/** \} */

View File

@ -153,6 +153,7 @@ class StateManager {
public:
GPUState state;
GPUStateMutable mutable_state;
bool use_bgl = false;
public:
StateManager();

View File

@ -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;
}

View File

@ -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. */

View File

@ -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; \
}