Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern/gpu_state.cc')
-rw-r--r--source/blender/gpu/intern/gpu_state.cc109
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;