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
This commit is contained in:
Clément Foucault 2020-09-12 17:29:37 +02:00
parent 6bc0a8424e
commit bf3f4da947
Notes: blender-bot 2023-02-14 06:17:17 +01:00
Referenced by issue #80297, 2.91 texture alpha is not transparent
8 changed files with 41 additions and 6 deletions

View File

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

View File

@ -20,6 +20,7 @@ set(INC
../io
../../blenkernel
../../blenlib
../../gpu
../../makesdna
../../makesrna
../../windowmanager

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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