diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_state.cc')
-rw-r--r-- | source/blender/gpu/intern/gpu_state.cc | 109 |
1 files changed, 87 insertions, 22 deletions
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc index be523020e8a..407a8dd6e2b 100644 --- a/source/blender/gpu/intern/gpu_state.cc +++ b/source/blender/gpu/intern/gpu_state.cc @@ -30,7 +30,6 @@ #include "BKE_global.h" -#include "GPU_glew.h" #include "GPU_state.h" #include "gpu_context_private.hh" @@ -41,7 +40,7 @@ using namespace blender::gpu; #define SET_STATE(_prefix, _state, _value) \ do { \ - GPUStateManager *stack = Context::get()->state_manager; \ + StateManager *stack = Context::get()->state_manager; \ auto &state_object = stack->_prefix##state; \ state_object._state = (_value); \ } while (0) @@ -105,7 +104,7 @@ void GPU_write_mask(eGPUWriteMask mask) void GPU_color_mask(bool r, bool g, bool b, bool a) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->state; uint32_t write_mask = state.write_mask; SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED); @@ -117,7 +116,7 @@ void GPU_color_mask(bool r, bool g, bool b, bool a) void GPU_depth_mask(bool depth) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->state; uint32_t write_mask = state.write_mask; SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH); @@ -142,7 +141,7 @@ void GPU_state_set(eGPUWriteMask write_mask, eGPUStencilOp stencil_op, eGPUProvokingVertex provoking_vert) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->state; state.write_mask = (uint32_t)write_mask; state.blend = (uint32_t)blend; @@ -161,19 +160,20 @@ void GPU_state_set(eGPUWriteMask write_mask, void GPU_depth_range(float near, float far) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->mutable_state; copy_v2_fl2(state.depth_range, near, far); } void GPU_line_width(float width) { - SET_MUTABLE_STATE(line_width, width * PIXELSIZE); + width = max_ff(1.0f, width * PIXELSIZE); + SET_MUTABLE_STATE(line_width, width); } void GPU_point_size(float size) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->mutable_state; /* Keep the sign of point_size since it represents the enable state. */ state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f); @@ -185,7 +185,7 @@ void GPU_point_size(float size) /* TODO remove and use program point size everywhere */ void GPU_program_point_size(bool enable) { - GPUStateManager *stack = Context::get()->state_manager; + StateManager *stack = Context::get()->state_manager; auto &state = stack->mutable_state; /* Set point size sign negative to disable. */ state.point_size = fabsf(state.point_size) * (enable ? 1 : -1); @@ -259,6 +259,13 @@ eGPUStencilTest GPU_stencil_test_get() return (eGPUStencilTest)state.stencil_test; } +/* NOTE: Already premultiplied by U.pixelsize. */ +float GPU_line_width_get() +{ + GPUStateMutable &state = Context::get()->state_manager->mutable_state; + return state.line_width; +} + void GPU_scissor_get(int coords[4]) { Context::get()->active_fb->scissor_get(coords); @@ -278,15 +285,15 @@ void GPU_viewport_size_get_i(int coords[4]) Context::get()->active_fb->viewport_get(coords); } -bool GPU_depth_mask_get(void) +bool GPU_depth_mask_get() { GPUState &state = Context::get()->state_manager->state; return (state.write_mask & GPU_WRITE_DEPTH) != 0; } -bool GPU_mipmap_enabled(void) +bool GPU_mipmap_enabled() { - /* TODO(fclem) this used to be a userdef option. */ + /* TODO(fclem): this used to be a userdef option. */ return true; } @@ -296,28 +303,85 @@ bool GPU_mipmap_enabled(void) /** \name Context Utils * \{ */ -void GPU_flush(void) +void GPU_flush() { Context::get()->flush(); } -void GPU_finish(void) +void GPU_finish() { Context::get()->finish(); } +void GPU_apply_state() +{ + Context::get()->state_manager->apply_state(); +} + /** \} */ /* -------------------------------------------------------------------- */ -/** \name Default OpenGL State +/** \name BGL workaround * - * 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. + * 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. * \{ */ -GPUStateManager::GPUStateManager(void) +void GPU_bgl_start() +{ + Context *ctx = Context::get(); + if (!(ctx && ctx->state_manager)) { + return; + } + 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; + } +} + +/* Just turn off the bgl safeguard system. Can be called even without GPU_bgl_start. */ +void GPU_bgl_end() +{ + Context *ctx = Context::get(); + if (!(ctx && ctx->state_manager)) { + return; + } + StateManager &state_manager = *ctx->state_manager; + if (state_manager.use_bgl == true) { + state_manager.use_bgl = false; + /* Resync state tracking. */ + state_manager.force_state(); + } +} + +bool GPU_bgl_get() +{ + return Context::get()->state_manager->use_bgl; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Synchronization Utils + * \{ */ + +void GPU_memory_barrier(eGPUBarrier barrier) +{ + Context::get()->state_manager->issue_barrier(barrier); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Default State + * \{ */ + +StateManager::StateManager() { /* Set default state. */ state.write_mask = GPU_WRITE_COLOR; @@ -330,12 +394,13 @@ GPUStateManager::GPUStateManager(void) state.logic_op_xor = false; state.invert_facing = false; state.shadow_bias = false; - state.polygon_smooth = false; state.clip_distances = 0; + state.polygon_smooth = false; + state.line_smooth = false; mutable_state.depth_range[0] = 0.0f; mutable_state.depth_range[1] = 1.0f; - mutable_state.point_size = 1.0f; + mutable_state.point_size = -1.0f; /* Negative is not using point size. */ mutable_state.line_width = 1.0f; mutable_state.stencil_write_mask = 0x00; mutable_state.stencil_compare_mask = 0x00; |