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')
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h6
-rw-r--r--source/blender/blenkernel/BKE_nla.h1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c16
-rw-r--r--source/blender/blenkernel/intern/collection.c22
-rw-r--r--source/blender/blenkernel/intern/collision.c26
-rw-r--r--source/blender/blenkernel/intern/lib_override.c47
-rw-r--r--source/blender/blenkernel/intern/nla.c31
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c20
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h8
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h5
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc37
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc29
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc11
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.cc10
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.h4
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c286
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c14
-rw-r--r--source/blender/draw/intern/draw_manager.c24
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c20
-rw-r--r--source/blender/draw/intern/draw_view.c2
-rw-r--r--source/blender/editors/curve/editcurve_paint.c4
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c4
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c4
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c4
-rw-r--r--source/blender/editors/include/ED_screen.h8
-rw-r--r--source/blender/editors/interface/interface_intern.h4
-rw-r--r--source/blender/editors/interface/interface_panel.c166
-rw-r--r--source/blender/editors/interface/interface_widgets.c5
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c4
-rw-r--r--source/blender/editors/mesh/editmesh_preselect_edgering.c4
-rw-r--r--source/blender/editors/mesh/editmesh_preselect_elem.c4
-rw-r--r--source/blender/editors/object/object_add.c4
-rw-r--r--source/blender/editors/screen/area.c124
-rw-r--r--source/blender/editors/screen/screen_context.c38
-rw-r--r--source/blender/editors/screen/screen_draw.c6
-rw-r--r--source/blender/editors/screen/screen_edit.c71
-rw-r--r--source/blender/editors/screen/screen_geometry.c9
-rw-r--r--source/blender/editors/screen/screen_ops.c32
-rw-r--r--source/blender/editors/screen/workspace_edit.c6
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c40
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c170
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c6
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c4
-rw-r--r--source/blender/editors/space_image/image_draw.c2
-rw-r--r--source/blender/editors/space_image/space_image.c6
-rw-r--r--source/blender/editors/space_nla/nla_edit.c6
-rw-r--r--source/blender/editors/space_node/node_draw.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c66
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h4
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c68
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c18
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c18
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c2
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c3
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c4
-rw-r--r--source/blender/editors/transform/transform_constraints.c14
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c4
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c4
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c4
-rw-r--r--source/blender/gpu/CMakeLists.txt4
-rw-r--r--source/blender/gpu/GPU_context.h1
-rw-r--r--source/blender/gpu/GPU_immediate.h3
-rw-r--r--source/blender/gpu/GPU_shader.h40
-rw-r--r--source/blender/gpu/GPU_shader_interface.h117
-rw-r--r--source/blender/gpu/GPU_state.h10
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding.cc13
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding_private.h6
-rw-r--r--source/blender/gpu/intern/gpu_batch_private.hh1
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc84
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc17
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c14
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c22
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc66
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc532
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh225
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh6
-rw-r--r--source/blender/gpu/intern/gpu_state.cc9
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc48
-rw-r--r--source/blender/gpu/opengl/gl_batch.hh16
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc6
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc297
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.hh60
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.cc14
-rw-r--r--source/blender/gpu/opengl/gl_vertex_array.hh4
-rw-r--r--source/blender/makesdna/DNA_ID.h4
-rw-r--r--source/blender/makesrna/intern/rna_scene.c7
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c8
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c14
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c4
-rw-r--r--source/blender/python/generic/bgl.c6
-rw-r--r--source/blender/python/generic/idprop_py_api.c12
-rw-r--r--source/blender/python/generic/imbuf_py_api.c8
-rw-r--r--source/blender/python/generic/py_capi_utils.c20
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c8
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_buffer.c2
-rw-r--r--source/blender/python/gpu/gpu_py_vertex_format.c4
-rw-r--r--source/blender/python/intern/bpy_app.c2
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c2
-rw-r--r--source/blender/python/intern/bpy_app_icons.c8
-rw-r--r--source/blender/python/intern/bpy_app_opensubdiv.c2
-rw-r--r--source/blender/python/intern/bpy_app_timers.c4
-rw-r--r--source/blender/python/intern/bpy_app_translations.c2
-rw-r--r--source/blender/python/intern/bpy_driver.c4
-rw-r--r--source/blender/python/intern/bpy_interface.c10
-rw-r--r--source/blender/python/intern/bpy_library_load.c6
-rw-r--r--source/blender/python/intern/bpy_msgbus.c2
-rw-r--r--source/blender/python/intern/bpy_props.c10
-rw-r--r--source/blender/python/intern/bpy_rna.c59
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c4
-rw-r--r--source/blender/python/intern/bpy_rna_array.c14
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c2
-rw-r--r--source/blender/python/intern/bpy_rna_driver.c2
-rw-r--r--source/blender/python/intern/bpy_rna_gizmo.c12
-rw-r--r--source/blender/python/mathutils/mathutils.c8
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c4
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c5
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c4
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c4
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c4
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.c2
-rw-r--r--source/blender/windowmanager/WM_types.h8
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c12
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c4
139 files changed, 1906 insertions, 1681 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 7b10ed4d43c..9a5700d2fbd 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -81,6 +81,7 @@ bool BKE_lib_override_library_resync(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct ID *id_root);
+void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root);
struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
struct IDOverrideLibrary *override, const char *rna_path);
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 267be4f44fd..87b55c581a2 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -72,9 +72,9 @@ struct Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
const struct CustomData_MeshMasks *dataMask);
struct Mesh *mesh_create_eval_final(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- const struct CustomData_MeshMasks *dataMask);
+ struct Scene *scene,
+ struct Object *ob,
+ const struct CustomData_MeshMasks *dataMask);
struct Mesh *mesh_create_eval_final_index_render(struct Depsgraph *depsgraph,
struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 8b3231e5302..06e9e58d6d7 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -102,6 +102,7 @@ void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
bool BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
+void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip);
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 4f587abd9f0..263f63cb6da 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1991,9 +1991,9 @@ Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
}
Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- const CustomData_MeshMasks *dataMask)
+ Scene *scene,
+ Object *ob,
+ const CustomData_MeshMasks *dataMask)
{
Mesh *final;
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5b5e32f1d81..8fe57f1bfa0 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -2192,7 +2192,15 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
if (is_inplace_tweak) {
/* edit active action in-place according to its active strip, so copy the data */
memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
+ /* Prevents nla eval from considering active strip's adj strips.
+ * For user, this means entering tweak mode on a strip ignores evaluating adjacent strips
+ * in the same track. */
dummy_strip->next = dummy_strip->prev = NULL;
+
+ /* If tweaked strip is syncing action length, then evaluate using action length. */
+ if (dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
+ BKE_nlastrip_recalculate_bounds_sync_action(dummy_strip);
+ }
}
else {
/* set settings of dummy NLA strip from AnimData settings */
@@ -2237,9 +2245,11 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* If computing the context for keyframing, store data there instead of the list. */
else {
/* The extend mode here effectively controls
- * whether it is possible to key-frame beyond the ends. */
- dummy_strip->extendmode = is_inplace_tweak ? NLASTRIP_EXTEND_NOTHING :
- NLASTRIP_EXTEND_HOLD;
+ * whether it is possible to key-frame beyond the ends.*/
+ dummy_strip->extendmode = (is_inplace_tweak &&
+ !(dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
+ NLASTRIP_EXTEND_NOTHING :
+ NLASTRIP_EXTEND_HOLD;
r_context->eval_strip = nes = nlastrips_ctime_get_strip(
NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 0d65ee5faa3..88037a8dad0 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -408,18 +408,28 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
if (do_objects) {
+ /* We need to first duplicate the objects in a separate loop, to support the master collection
+ * case, where both old and new collections are the same.
+ * Otherwise, depending on naming scheme and sorting, we may end up duplicating the new objects
+ * we just added, in some infinite loop. */
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection_old->gobject) {
+ Object *ob_old = cob->ob;
+
+ if (ob_old->id.newid == NULL) {
+ BKE_object_duplicate(
+ bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ }
+ }
+
/* We can loop on collection_old's objects, but have to consider it mutable because with master
* collections collection_old and collection_new are the same data here. */
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection_old->gobject) {
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
- if (ob_new == NULL) {
- ob_new = BKE_object_duplicate(
- bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
- }
-
- if (ob_new == ob_old) {
+ /* New object can be NULL in master collection case, since new and old objects are in same
+ * collection. */
+ if (ELEM(ob_new, ob_old, NULL)) {
continue;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 05c521e3b94..115980d577e 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -647,9 +647,9 @@ DO_INLINE void collision_interpolateOnTriangle(float to[3],
VECADDMUL(to, v3, w3);
}
-static void cloth_selfcollision_impulse_vert(const float clamp_sq,
- const float impulse[3],
- struct ClothVertex *vert)
+static void cloth_collision_impulse_vert(const float clamp_sq,
+ const float impulse[3],
+ struct ClothVertex *vert)
{
float impulse_len_sq = len_squared_v3(impulse);
@@ -681,7 +681,7 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
{
int result = 0;
Cloth *cloth = clmd->clothObject;
- const float clamp_sq = square_f(clmd->coll_parms->self_clamp * dt);
+ const float clamp_sq = square_f(clmd->coll_parms->clamp * dt);
const float time_multiplier = 1.0f / (clmd->sim_parms->dt * clmd->sim_parms->timescale);
const float epsilon2 = BLI_bvhtree_get_epsilon(collmd->bvhtree);
const float min_distance = (clmd->coll_parms->epsilon + epsilon2) * (8.0f / 9.0f);
@@ -828,10 +828,10 @@ static int cloth_collision_response_static(ClothModifierData *clmd,
}
if (result) {
- cloth_selfcollision_impulse_vert(clamp_sq, i1, &cloth->verts[collpair->ap1]);
- cloth_selfcollision_impulse_vert(clamp_sq, i2, &cloth->verts[collpair->ap2]);
+ cloth_collision_impulse_vert(clamp_sq, i1, &cloth->verts[collpair->ap1]);
+ cloth_collision_impulse_vert(clamp_sq, i2, &cloth->verts[collpair->ap2]);
if (!is_hair) {
- cloth_selfcollision_impulse_vert(clamp_sq, i3, &cloth->verts[collpair->ap3]);
+ cloth_collision_impulse_vert(clamp_sq, i3, &cloth->verts[collpair->ap3]);
}
}
}
@@ -987,13 +987,13 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd,
}
if (result) {
- cloth_selfcollision_impulse_vert(clamp_sq, ia[0], &cloth->verts[collpair->ap1]);
- cloth_selfcollision_impulse_vert(clamp_sq, ia[1], &cloth->verts[collpair->ap2]);
- cloth_selfcollision_impulse_vert(clamp_sq, ia[2], &cloth->verts[collpair->ap3]);
+ cloth_collision_impulse_vert(clamp_sq, ia[0], &cloth->verts[collpair->ap1]);
+ cloth_collision_impulse_vert(clamp_sq, ia[1], &cloth->verts[collpair->ap2]);
+ cloth_collision_impulse_vert(clamp_sq, ia[2], &cloth->verts[collpair->ap3]);
- cloth_selfcollision_impulse_vert(clamp_sq, ib[0], &cloth->verts[collpair->bp1]);
- cloth_selfcollision_impulse_vert(clamp_sq, ib[1], &cloth->verts[collpair->bp2]);
- cloth_selfcollision_impulse_vert(clamp_sq, ib[2], &cloth->verts[collpair->bp3]);
+ cloth_collision_impulse_vert(clamp_sq, ib[0], &cloth->verts[collpair->bp1]);
+ cloth_collision_impulse_vert(clamp_sq, ib[1], &cloth->verts[collpair->bp2]);
+ cloth_collision_impulse_vert(clamp_sq, ib[2], &cloth->verts[collpair->bp3]);
}
}
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 6b808d8132c..cca312270bc 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -448,7 +448,8 @@ void BKE_lib_override_library_override_group_tag(Main *bmain,
BKE_main_relations_create(bmain, 0);
}
- /* We tag all liboverride data-blocks from the same library as reference one, being used by the root ID. */
+ /* We tag all liboverride data-blocks from the same library as reference one,
+ * being used by the root ID. */
lib_override_hierarchy_recursive_tag(
bmain, id_root, tag, id_root->override_library->reference->lib);
@@ -783,6 +784,50 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
return success;
}
+/**
+ * Advanced 'smart' function to delete library overrides (including their existing override
+ * hierarchy) and remap their usages to their linked reference IDs.
+ *
+ * \note All IDs tagged with `LIB_TAG_DOIT` will be deleted.
+ *
+ * \param id_root The root liboverride ID to resync from.
+ */
+void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
+{
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
+
+ /* Tag all collections and objects, as well as other IDs using them. */
+ id_root->tag |= LIB_TAG_DOIT;
+
+ /* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, and tag
+ * linked reference ones to be overridden again. */
+ BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true);
+
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (id->tag & LIB_TAG_DOIT) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+ ID *id_override_reference = id->override_library->reference;
+
+ /* Remap the whole local IDs to use the linked data. */
+ BKE_libblock_remap(bmain, id, id_override_reference, ID_REMAP_SKIP_INDIRECT_USAGE);
+ }
+ }
+ }
+ FOREACH_MAIN_ID_END;
+
+ /* Delete the override IDs. */
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (id->tag & LIB_TAG_DOIT) {
+ BKE_id_delete(bmain, id);
+ }
+ }
+ FOREACH_MAIN_ID_END;
+
+ /* Should not actually be needed here... */
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+}
+
BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure(
IDOverrideLibrary *override)
{
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 1ba82b352d1..e5527ed987a 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1361,6 +1361,25 @@ static void nlastrip_fix_resize_overlaps(NlaStrip *strip)
}
}
+/** Recalculate the start and end frames for the strip to match the bounds of its action such that
+ * the overall NLA animation result is unchanged. */
+void BKE_nlastrip_recalculate_bounds_sync_action(NlaStrip *strip)
+{
+ float prev_actstart;
+
+ if (strip == NULL || strip->type != NLASTRIP_TYPE_CLIP) {
+ return;
+ }
+
+ prev_actstart = strip->actstart;
+
+ calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
+
+ /* Set start such that key's do not visually move, to preserve the overall animation result. */
+ strip->start += (strip->actstart - prev_actstart) * strip->scale;
+
+ BKE_nlastrip_recalculate_bounds(strip);
+}
/* Recalculate the start and end frames for the current strip, after changing
* the extents of the action or the mapping (repeats or scale factor) info
*/
@@ -2133,11 +2152,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
/* must be action-clip only (transitions don't have scale) */
if ((strip->type == NLASTRIP_TYPE_CLIP) && (strip->act)) {
- /* recalculate the length of the action */
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
-
- /* adjust the strip extents in response to this */
- BKE_nlastrip_recalculate_bounds(strip);
+ BKE_nlastrip_recalculate_bounds_sync_action(strip);
}
}
@@ -2151,11 +2166,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
/* sync strip extents if this strip uses the same action */
if ((adt->actstrip) && (adt->actstrip->act == strip->act) &&
(strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) {
- /* recalculate the length of the action */
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
-
- /* adjust the strip extents in response to this */
- BKE_nlastrip_recalculate_bounds(strip);
+ BKE_nlastrip_recalculate_bounds_sync_action(strip);
}
/* clear tweakuser flag */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index c6daecbcee6..aba9b255f40 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2437,16 +2437,16 @@ static void transform_image(int x,
}
static void do_transform_effect(const SeqRenderData *context,
- Sequence *seq,
- float UNUSED(cfra),
- float UNUSED(facf0),
- float UNUSED(facf1),
- ImBuf *ibuf1,
- ImBuf *UNUSED(ibuf2),
- ImBuf *UNUSED(ibuf3),
- int start_line,
- int total_lines,
- ImBuf *out)
+ Sequence *seq,
+ float UNUSED(cfra),
+ float UNUSED(facf0),
+ float UNUSED(facf1),
+ ImBuf *ibuf1,
+ ImBuf *UNUSED(ibuf2),
+ ImBuf *UNUSED(ibuf3),
+ int start_line,
+ int total_lines,
+ ImBuf *out)
{
Scene *scene = context->scene;
TransformVars *transform = (TransformVars *)seq->effectdata;
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index 8f33e9f480d..0ded511b8f8 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -127,6 +127,12 @@ void DEG_graph_id_tag_update(struct Main *bmain,
struct ID *id,
int flag);
+/* Tag all dependency graphs when time has changed. */
+void DEG_time_tag_update(struct Main *bmain);
+
+/* Tag a dependency graph when time has changed. */
+void DEG_graph_time_tag_update(struct Depsgraph *depsgraph);
+
/* Mark a particular datablock type as having changing. This does
* not cause any updates but is used by external render engines to detect if for
* example a datablock was removed. */
@@ -155,8 +161,6 @@ void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime);
/* Data changed recalculation entry point. */
void DEG_evaluate_on_refresh(Depsgraph *graph);
-bool DEG_needs_eval(Depsgraph *graph);
-
/* Editors Integration -------------------------- */
/* Mechanism to allow editors to be informed of depsgraph updates,
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 4a9c840dd9f..c0feab2262a 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -63,7 +63,6 @@ namespace deg {
Depsgraph::Depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode)
: time_source(nullptr),
need_update(true),
- need_update_time(false),
bmain(bmain),
scene(scene),
view_layer(view_layer),
@@ -103,6 +102,11 @@ TimeSourceNode *Depsgraph::find_time_source() const
return time_source;
}
+void Depsgraph::tag_time_source()
+{
+ time_source->tag_update(this, DEG_UPDATE_SOURCE_TIME);
+}
+
IDNode *Depsgraph::find_id_node(const ID *id) const
{
return id_hash.lookup_default(id, nullptr);
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index ea579a4958e..e03846f81e2 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -68,6 +68,7 @@ struct Depsgraph {
TimeSourceNode *add_time_source();
TimeSourceNode *find_time_source() const;
+ void tag_time_source();
IDNode *find_id_node(const ID *id) const;
IDNode *add_id_node(ID *id, ID *id_cow_hint = nullptr);
@@ -121,10 +122,6 @@ struct Depsgraph {
/* Nodes which have been tagged as "directly modified". */
Set<OperationNode *> entry_tags;
- /* Special entry tag for time source. Allows to tag invisible dependency graphs for update when
- * scene frame changes, so then when dependency graph becomes visible it is on a proper state. */
- bool need_update_time;
-
/* Convenience Data ................... */
/* XXX: should be collected after building (if actually needed?) */
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index 0c116f5863c..1ad3fdbc9da 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -47,38 +47,37 @@
namespace deg = blender::deg;
-/* Evaluate all nodes tagged for updating. */
-void DEG_evaluate_on_refresh(Depsgraph *graph)
+static void deg_flush_updates_and_refresh(deg::Depsgraph *deg_graph)
{
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- deg_graph->ctime = BKE_scene_frame_get(deg_graph->scene);
- /* Update time in scene. */
+ /* Update the time on the cow scene. */
if (deg_graph->scene_cow) {
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
}
+
deg::deg_graph_flush_updates(deg_graph);
deg::deg_evaluate_on_refresh(deg_graph);
- deg_graph->need_update_time = false;
}
-/* Frame-change happened for root scene that graph belongs to. */
-void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime)
+/* Evaluate all nodes tagged for updating. */
+void DEG_evaluate_on_refresh(Depsgraph *graph)
{
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- deg_graph->ctime = ctime;
- deg_graph->need_update_time = true;
- deg::deg_graph_flush_updates(deg_graph);
- /* Update time in scene. */
- if (deg_graph->scene_cow) {
- BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
+ const Scene *scene = DEG_get_input_scene(graph);
+ const float ctime = BKE_scene_frame_get(scene);
+
+ if (ctime != deg_graph->ctime) {
+ deg_graph->tag_time_source();
+ deg_graph->ctime = ctime;
}
- /* Perform recalculation updates. */
- deg::deg_evaluate_on_refresh(deg_graph);
- deg_graph->need_update_time = false;
+
+ deg_flush_updates_and_refresh(deg_graph);
}
-bool DEG_needs_eval(Depsgraph *graph)
+/* Frame-change happened for root scene that graph belongs to. */
+void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime)
{
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- return !deg_graph->entry_tags.is_empty() || deg_graph->need_update_time;
+ deg_graph->tag_time_source();
+ deg_graph->ctime = ctime;
+ deg_flush_updates_and_refresh(deg_graph);
}
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 4a2d47f9379..868f88d8fcd 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -66,6 +66,7 @@
#include "intern/node/deg_node_factory.h"
#include "intern/node/deg_node_id.h"
#include "intern/node/deg_node_operation.h"
+#include "intern/node/deg_node_time.h"
namespace deg = blender::deg;
@@ -230,9 +231,6 @@ void depsgraph_tag_to_component_opcode(const ID *id,
case ID_RECALC_SOURCE:
*component_type = NodeType::PARAMETERS;
break;
- case ID_RECALC_TIME:
- BLI_assert(!"Should be handled outside of this function");
- break;
case ID_RECALC_ALL:
case ID_RECALC_PSYS_ALL:
BLI_assert(!"Should not happen");
@@ -372,12 +370,6 @@ void graph_id_tag_update_single_flag(Main *bmain,
}
return;
}
- if (tag == ID_RECALC_TIME) {
- if (graph != nullptr) {
- graph->need_update_time = true;
- }
- return;
- }
/* Get description of what is to be tagged. */
NodeType component_type;
OperationCode operation_code;
@@ -462,8 +454,8 @@ const char *update_source_as_string(eUpdateSource source)
int deg_recalc_flags_for_legacy_zero()
{
- return ID_RECALC_ALL & ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE |
- ID_RECALC_TIME | ID_RECALC_EDITORS);
+ return ID_RECALC_ALL &
+ ~(ID_RECALC_PSYS_ALL | ID_RECALC_ANIMATION | ID_RECALC_SOURCE | ID_RECALC_EDITORS);
}
int deg_recalc_flags_effective(Depsgraph *graph, int flags)
@@ -734,8 +726,6 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "AUDIO";
case ID_RECALC_PARAMETERS:
return "PARAMETERS";
- case ID_RECALC_TIME:
- return "TIME";
case ID_RECALC_SOURCE:
return "SOURCE";
case ID_RECALC_ALL:
@@ -772,6 +762,19 @@ void DEG_graph_id_tag_update(struct Main *bmain,
deg::graph_id_tag_update(bmain, graph, id, flag, deg::DEG_UPDATE_SOURCE_USER_EDIT);
}
+void DEG_time_tag_update(struct Main *bmain)
+{
+ for (deg::Depsgraph *depsgraph : deg::get_all_registered_graphs(bmain)) {
+ DEG_graph_time_tag_update(reinterpret_cast<::Depsgraph *>(depsgraph));
+ }
+}
+
+void DEG_graph_time_tag_update(struct Depsgraph *depsgraph)
+{
+ deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
+ deg_graph->tag_time_source();
+}
+
/* Mark a particular datablock type as having changing. */
void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
{
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index dea23c9f96d..5ccdcbec858 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -357,14 +357,9 @@ void deg_graph_flush_updates(Depsgraph *graph)
BLI_assert(graph != nullptr);
Main *bmain = graph->bmain;
+ graph->time_source->flush_update_tag(graph);
+
/* Nothing to update, early out. */
- if (graph->need_update_time) {
- const Scene *scene_orig = graph->scene;
- const float ctime = BKE_scene_frame_get(scene_orig);
- TimeSourceNode *time_source = graph->find_time_source();
- graph->ctime = ctime;
- time_source->tag_update(graph, DEG_UPDATE_SOURCE_TIME);
- }
if (graph->entry_tags.is_empty()) {
return;
}
@@ -412,6 +407,8 @@ void deg_graph_clear_tags(Depsgraph *graph)
}
/* Clear any entry tags which haven't been flushed. */
graph->entry_tags.clear();
+
+ graph->time_source->tagged_for_update = false;
}
} // namespace deg
diff --git a/source/blender/depsgraph/intern/node/deg_node_time.cc b/source/blender/depsgraph/intern/node/deg_node_time.cc
index af931fbae34..4f7f70fef33 100644
--- a/source/blender/depsgraph/intern/node/deg_node_time.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_time.cc
@@ -31,8 +31,16 @@
namespace blender {
namespace deg {
-void TimeSourceNode::tag_update(Depsgraph *graph, eUpdateSource /*source*/)
+void TimeSourceNode::tag_update(Depsgraph * /*graph*/, eUpdateSource /*source*/)
{
+ tagged_for_update = true;
+}
+
+void TimeSourceNode::flush_update_tag(Depsgraph *graph)
+{
+ if (!tagged_for_update) {
+ return;
+ }
for (Relation *rel : outlinks) {
Node *node = rel->to;
node->tag_update(graph, DEG_UPDATE_SOURCE_TIME);
diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h
index fe17684abb0..79ad92f336f 100644
--- a/source/blender/depsgraph/intern/node/deg_node_time.h
+++ b/source/blender/depsgraph/intern/node/deg_node_time.h
@@ -30,10 +30,14 @@ namespace deg {
/* Time Source Node. */
struct TimeSourceNode : public Node {
+ bool tagged_for_update = false;
+
// TODO: evaluate() operation needed
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override;
+ void flush_update_tag(Depsgraph *graph);
+
DEG_DEPSNODE_DECLARE;
};
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 934b47d583e..fe48ce00b86 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -99,8 +99,6 @@ typedef struct MeshRenderData {
float obmat[4][4];
const ToolSettings *toolsettings;
- /* HACK not supposed to be there but it's needed. */
- struct MeshBatchCache *cache;
/** Edit Mesh */
BMEditMesh *edit_bmesh;
BMesh *bm;
@@ -751,8 +749,13 @@ typedef void(ExtractLVertMeshFn)(const MeshRenderData *mr,
/** \name Mesh Elements Extract Struct
* \{ */
-typedef void *(ExtractInitFn)(const MeshRenderData *mr, void *buffer);
-typedef void(ExtractFinishFn)(const MeshRenderData *mr, void *buffer, void *data);
+typedef void *(ExtractInitFn)(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buffer);
+typedef void(ExtractFinishFn)(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buffer,
+ void *data);
typedef struct MeshExtract {
/** Executed on main thread and return user data for iteration functions. */
@@ -796,7 +799,9 @@ typedef struct MeshExtract_Tri_Data {
int *tri_mat_end;
} MeshExtract_Tri_Data;
-static void *extract_tris_init(const MeshRenderData *mr, void *UNUSED(ibo))
+static void *extract_tris_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo))
{
MeshExtract_Tri_Data *data = MEM_callocN(sizeof(*data), __func__);
@@ -882,14 +887,17 @@ static void extract_tris_iter_looptri_mesh(const MeshRenderData *mr,
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
}
-static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data)
+static void extract_tris_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *ibo,
+ void *_data)
{
MeshExtract_Tri_Data *data = _data;
GPU_indexbuf_build_in_place(&data->elb, ibo);
/* HACK: Create ibo sub-ranges and assign them to each #GPUBatch. */
/* The `surface_per_mat` tests are there when object shading type is set to Wire or Bounds. In
* these cases there isn't a surface per material. */
- if (mr->use_final_mesh && mr->cache->surface_per_mat && mr->cache->surface_per_mat[0]) {
+ if (mr->use_final_mesh && cache->surface_per_mat && cache->surface_per_mat[0]) {
for (int i = 0; i < mr->mat_len; i++) {
/* Multiply by 3 because these are triangle indices. */
const int mat_start = data->tri_mat_start[i];
@@ -898,7 +906,7 @@ static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data
const int len = (mat_end - mat_start) * 3;
GPUIndexBuf *sub_ibo = GPU_indexbuf_create_subrange(ibo, start, len);
/* WARNING: We modify the #GPUBatch here! */
- GPU_batch_elembuf_set(mr->cache->surface_per_mat[i], sub_ibo, true);
+ GPU_batch_elembuf_set(cache->surface_per_mat[i], sub_ibo, true);
}
}
MEM_freeN(data->tri_mat_start);
@@ -921,7 +929,9 @@ static const MeshExtract extract_tris = {
/** \name Extract Edges Indices
* \{ */
-static void *extract_lines_init(const MeshRenderData *mr, void *UNUSED(buf))
+static void *extract_lines_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
{
GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__);
/* Put loose edges at the end. */
@@ -1039,7 +1049,10 @@ static void extract_lines_iter_ledge_mesh(const MeshRenderData *mr,
EXTRACT_LEDGE_FOREACH_MESH_END;
}
-static void extract_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb)
+static void extract_lines_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *elb)
{
GPU_indexbuf_build_in_place(elb, ibo);
MEM_freeN(elb);
@@ -1061,21 +1074,24 @@ static const MeshExtract extract_lines = {
/** \name Extract Loose Edges Sub Buffer
* \{ */
-static void extract_lines_loose_subbuffer(const MeshRenderData *mr)
+static void extract_lines_loose_subbuffer(const MeshRenderData *mr, struct MeshBatchCache *cache)
{
- BLI_assert(mr->cache->final.ibo.lines);
+ BLI_assert(cache->final.ibo.lines);
/* Multiply by 2 because these are edges indices. */
const int start = mr->edge_len * 2;
const int len = mr->edge_loose_len * 2;
GPU_indexbuf_create_subrange_in_place(
- mr->cache->final.ibo.lines_loose, mr->cache->final.ibo.lines, start, len);
- mr->cache->no_loose_wire = (len == 0);
+ cache->final.ibo.lines_loose, cache->final.ibo.lines, start, len);
+ cache->no_loose_wire = (len == 0);
}
-static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr, void *ibo, void *elb)
+static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *ibo,
+ void *elb)
{
GPU_indexbuf_build_in_place(elb, ibo);
- extract_lines_loose_subbuffer(mr);
+ extract_lines_loose_subbuffer(mr, cache);
MEM_freeN(elb);
}
@@ -1096,7 +1112,9 @@ static const MeshExtract extract_lines_with_lines_loose = {
/** \name Extract Point Indices
* \{ */
-static void *extract_points_init(const MeshRenderData *mr, void *UNUSED(buf))
+static void *extract_points_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
{
GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->vert_len, mr->loop_len + mr->loop_loose_len);
@@ -1200,7 +1218,10 @@ static void extract_points_iter_lvert_mesh(const MeshRenderData *mr,
EXTRACT_LVERT_FOREACH_MESH_END;
}
-static void extract_points_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb)
+static void extract_points_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *elb)
{
GPU_indexbuf_build_in_place(elb, ibo);
MEM_freeN(elb);
@@ -1225,7 +1246,9 @@ static const MeshExtract extract_points = {
/** \name Extract Facedots Indices
* \{ */
-static void *extract_fdots_init(const MeshRenderData *mr, void *UNUSED(buf))
+static void *extract_fdots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
{
GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__);
GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->poly_len, mr->poly_len);
@@ -1280,7 +1303,10 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_fdots_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb)
+static void extract_fdots_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *elb)
{
GPU_indexbuf_build_in_place(elb, ibo);
MEM_freeN(elb);
@@ -1307,7 +1333,9 @@ typedef struct MeshExtract_LinePaintMask_Data {
BLI_bitmap select_map[0];
} MeshExtract_LinePaintMask_Data;
-static void *extract_lines_paint_mask_init(const MeshRenderData *mr, void *UNUSED(buf))
+static void *extract_lines_paint_mask_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
{
size_t bitmap_size = BLI_BITMAP_SIZE(mr->edge_len);
MeshExtract_LinePaintMask_Data *data = MEM_callocN(sizeof(*data) + bitmap_size, __func__);
@@ -1354,6 +1382,7 @@ static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr,
EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
}
static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
void *ibo,
void *_data)
{
@@ -1387,7 +1416,9 @@ typedef struct MeshExtract_LineAdjacency_Data {
uint vert_to_loop[0];
} MeshExtract_LineAdjacency_Data;
-static void *extract_lines_adjacency_init(const MeshRenderData *mr, void *UNUSED(buf))
+static void *extract_lines_adjacency_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf))
{
/* Similar to poly_to_tri_count().
* There is always (loop + triangle - 1) edges inside a polygon.
@@ -1483,7 +1514,10 @@ static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr,
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
}
-static void extract_lines_adjacency_finish(const MeshRenderData *mr, void *ibo, void *_data)
+static void extract_lines_adjacency_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *cache,
+ void *ibo,
+ void *_data)
{
MeshExtract_LineAdjacency_Data *data = _data;
/* Create edges for remaining non manifold edges. */
@@ -1506,7 +1540,7 @@ static void extract_lines_adjacency_finish(const MeshRenderData *mr, void *ibo,
BLI_edgehashIterator_free(ehi);
BLI_edgehash_free(data->eh, NULL);
- mr->cache->is_manifold = data->is_manifold;
+ cache->is_manifold = data->is_manifold;
GPU_indexbuf_build_in_place(&data->elb, ibo);
MEM_freeN(data);
@@ -1534,7 +1568,9 @@ typedef struct MeshExtract_EditUvElem_Data {
bool sync_selection;
} MeshExtract_EditUvElem_Data;
-static void *extract_edituv_tris_init(const MeshRenderData *mr, void *UNUSED(ibo))
+static void *extract_edituv_tris_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo))
{
MeshExtract_EditUvElem_Data *data = MEM_callocN(sizeof(*data), __func__);
GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, mr->tri_len, mr->loop_len);
@@ -1583,7 +1619,10 @@ static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END;
}
-static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data)
+static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *data)
{
MeshExtract_EditUvElem_Data *extract_data = data;
GPU_indexbuf_build_in_place(&extract_data->elb, ibo);
@@ -1605,7 +1644,9 @@ static const MeshExtract extract_edituv_tris = {
/** \name Extract Edit UV Line Indices around faces
* \{ */
-static void *extract_edituv_lines_init(const MeshRenderData *mr, void *UNUSED(ibo))
+static void *extract_edituv_lines_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo))
{
MeshExtract_EditUvElem_Data *data = MEM_callocN(sizeof(*data), __func__);
GPU_indexbuf_init(&data->elb, GPU_PRIM_LINES, mr->loop_len, mr->loop_len);
@@ -1655,7 +1696,10 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
}
-static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data)
+static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *data)
{
MeshExtract_EditUvElem_Data *extract_data = data;
GPU_indexbuf_build_in_place(&extract_data->elb, ibo);
@@ -1677,7 +1721,9 @@ static const MeshExtract extract_edituv_lines = {
/** \name Extract Edit UV Points Indices
* \{ */
-static void *extract_edituv_points_init(const MeshRenderData *mr, void *UNUSED(ibo))
+static void *extract_edituv_points_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo))
{
MeshExtract_EditUvElem_Data *data = MEM_callocN(sizeof(*data), __func__);
GPU_indexbuf_init(&data->elb, GPU_PRIM_POINTS, mr->loop_len, mr->loop_len);
@@ -1724,7 +1770,10 @@ static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
}
-static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data)
+static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *data)
{
MeshExtract_EditUvElem_Data *extract_data = data;
GPU_indexbuf_build_in_place(&extract_data->elb, ibo);
@@ -1746,7 +1795,9 @@ static const MeshExtract extract_edituv_points = {
/** \name Extract Edit UV Facedots Indices
* \{ */
-static void *extract_edituv_fdots_init(const MeshRenderData *mr, void *UNUSED(ibo))
+static void *extract_edituv_fdots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(ibo))
{
MeshExtract_EditUvElem_Data *data = MEM_callocN(sizeof(*data), __func__);
GPU_indexbuf_init(&data->elb, GPU_PRIM_POINTS, mr->poly_len, mr->poly_len);
@@ -1813,7 +1864,10 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *_data)
+static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *ibo,
+ void *_data)
{
MeshExtract_EditUvElem_Data *data = _data;
GPU_indexbuf_build_in_place(&data->elb, ibo);
@@ -1845,7 +1899,9 @@ typedef struct MeshExtract_PosNor_Data {
GPUPackedNormal packed_nor[];
} MeshExtract_PosNor_Data;
-static void *extract_pos_nor_init(const MeshRenderData *mr, void *buf)
+static void *extract_pos_nor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -1991,7 +2047,10 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr,
EXTRACT_LVERT_FOREACH_MESH_END;
}
-static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(vbo), void *data)
+static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(vbo),
+ void *data)
{
MEM_freeN(data);
}
@@ -2018,7 +2077,9 @@ typedef struct gpuHQNor {
short x, y, z, w;
} gpuHQNor;
-static void *extract_lnor_hq_init(const MeshRenderData *mr, void *buf)
+static void *extract_lnor_hq_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -2104,7 +2165,9 @@ static const MeshExtract extract_lnor_hq = {
/** \name Extract Loop Normal
* \{ */
-static void *extract_lnor_init(const MeshRenderData *mr, void *buf)
+static void *extract_lnor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -2195,16 +2258,15 @@ static const MeshExtract extract_lnor = {
/** \name Extract UV layers
* \{ */
-static void *extract_uv_init(const MeshRenderData *mr, void *buf)
+static void *extract_uv_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
{
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
- uint32_t uv_layers = mr->cache->cd_used.uv;
-
+ uint32_t uv_layers = cache->cd_used.uv;
/* HACK to fix T68857 */
- if (mr->extract_type == MR_EXTRACT_BMESH && mr->cache->cd_used.edit_uv == 1) {
+ if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) {
int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
if (layer != -1) {
uv_layers |= (1 << layer);
@@ -2292,7 +2354,10 @@ static const MeshExtract extract_uv = {
/** \name Extract Tangent layers
* \{ */
-static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool do_hq)
+static void extract_tan_ex(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ GPUVertBuf *vbo,
+ const bool do_hq)
{
GPUVertCompType comp_type = do_hq ? GPU_COMP_I16 : GPU_COMP_I10;
GPUVertFetchMode fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
@@ -2302,10 +2367,10 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
- uint32_t tan_layers = mr->cache->cd_used.tan;
+ uint32_t tan_layers = cache->cd_used.tan;
float(*orco)[3] = CustomData_get_layer(cd_vdata, CD_ORCO);
bool orco_allocated = false;
- const bool use_orco_tan = mr->cache->cd_used.tan_orco != 0;
+ const bool use_orco_tan = cache->cd_used.tan_orco != 0;
int tan_len = 0;
char tangent_names[MAX_MTFACE][MAX_CUSTOMDATA_LAYER_NAME];
@@ -2461,9 +2526,9 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
CustomData_free(&loop_data, mr->loop_len);
}
-static void *extract_tan_init(const MeshRenderData *mr, void *buf)
+static void *extract_tan_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
{
- extract_tan_ex(mr, buf, false);
+ extract_tan_ex(mr, cache, buf, false);
return NULL;
}
@@ -2479,9 +2544,9 @@ static const MeshExtract extract_tan = {
/** \name Extract HQ Tangent layers
* \{ */
-static void *extract_tan_hq_init(const MeshRenderData *mr, void *buf)
+static void *extract_tan_hq_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
{
- extract_tan_ex(mr, buf, true);
+ extract_tan_ex(mr, cache, buf, true);
return NULL;
}
@@ -2497,15 +2562,15 @@ static const MeshExtract extract_tan_hq = {
/** \name Extract VCol
* \{ */
-static void *extract_vcol_init(const MeshRenderData *mr, void *buf)
+static void *extract_vcol_init(const MeshRenderData *mr, struct MeshBatchCache *cache, void *buf)
{
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
- uint32_t vcol_layers = mr->cache->cd_used.vcol;
- uint32_t svcol_layers = mr->cache->cd_used.sculpt_vcol;
+ uint32_t vcol_layers = cache->cd_used.vcol;
+ uint32_t svcol_layers = cache->cd_used.sculpt_vcol;
for (int i = 0; i < MAX_MCOL; i++) {
if (vcol_layers & (1 << i)) {
@@ -2652,7 +2717,9 @@ typedef struct MeshExtract_Orco_Data {
float (*orco)[3];
} MeshExtract_Orco_Data;
-static void *extract_orco_init(const MeshRenderData *mr, void *buf)
+static void *extract_orco_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -2705,7 +2772,10 @@ static void extract_orco_iter_poly_mesh(const MeshRenderData *mr,
EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END;
}
-static void extract_orco_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(buf), void *data)
+static void extract_orco_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *data)
{
MEM_freeN(data);
}
@@ -2749,7 +2819,9 @@ static float loop_edge_factor_get(const float f_no[3],
return d;
}
-static void *extract_edge_fac_init(const MeshRenderData *mr, void *buf)
+static void *extract_edge_fac_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -2874,7 +2946,10 @@ static void extract_edge_fac_iter_ledge_mesh(const MeshRenderData *mr,
EXTRACT_LEDGE_FOREACH_MESH_END;
}
-static void extract_edge_fac_finish(const MeshRenderData *mr, void *buf, void *_data)
+static void extract_edge_fac_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *_data)
{
MeshExtract_EdgeFac_Data *data = _data;
@@ -2981,7 +3056,9 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
return input;
}
-static void *extract_weights_init(const MeshRenderData *mr, void *buf)
+static void *extract_weights_init(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -2993,7 +3070,7 @@ static void *extract_weights_init(const MeshRenderData *mr, void *buf)
MeshExtract_Weight_Data *data = MEM_callocN(sizeof(*data), __func__);
data->vbo_data = (float *)vbo->data;
- data->wstate = &mr->cache->weight_state;
+ data->wstate = &cache->weight_state;
if (data->wstate->defgroup_active == -1) {
/* Nothing to show. */
@@ -3056,7 +3133,10 @@ static void extract_weights_iter_poly_mesh(const MeshRenderData *mr,
}
}
-static void extract_weights_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(buf), void *data)
+static void extract_weights_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
+ void *UNUSED(buf),
+ void *data)
{
MEM_freeN(data);
}
@@ -3214,7 +3294,9 @@ static void mesh_render_data_vert_flag(const MeshRenderData *mr, BMVert *eve, Ed
}
}
-static void *extract_edit_data_init(const MeshRenderData *mr, void *buf)
+static void *extract_edit_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -3365,7 +3447,9 @@ typedef struct MeshExtract_EditUVData_Data {
int cd_ofs;
} MeshExtract_EditUVData_Data;
-static void *extract_edituv_data_init(const MeshRenderData *mr, void *buf)
+static void *extract_edituv_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -3442,6 +3526,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_edituv_data_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *data)
{
@@ -3463,7 +3548,9 @@ static const MeshExtract extract_edituv_data = {
/** \name Extract Edit UV area stretch
* \{ */
-static void *extract_stretch_area_init(const MeshRenderData *mr, void *buf)
+static void *extract_stretch_area_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -3492,7 +3579,10 @@ BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_t
return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
}
-static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *UNUSED(data))
+static void mesh_stretch_area_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
+ void *buf,
+ void *UNUSED(data))
{
float tot_area = 0.0f, tot_uv_area = 0.0f;
float *area_ratio = MEM_mallocN(sizeof(float) * mr->poly_len, __func__);
@@ -3528,8 +3618,8 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void *
BLI_assert(0);
}
- mr->cache->tot_area = tot_area;
- mr->cache->tot_uv_area = tot_uv_area;
+ cache->tot_area = tot_area;
+ cache->tot_uv_area = tot_uv_area;
/* Convert in place to avoid an extra allocation */
uint16_t *poly_stretch = (uint16_t *)area_ratio;
@@ -3634,7 +3724,9 @@ static void edituv_get_stretch_angle(float auv[2][2],
#endif
}
-static void *extract_stretch_angle_init(const MeshRenderData *mr, void *buf)
+static void *extract_stretch_angle_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -3755,6 +3847,7 @@ static void extract_stretch_angle_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_stretch_angle_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *data)
{
@@ -3776,7 +3869,9 @@ static const MeshExtract extract_stretch_angle = {
/** \name Extract Edit Mesh Analysis Colors
* \{ */
-static void *extract_mesh_analysis_init(const MeshRenderData *mr, void *buf)
+static void *extract_mesh_analysis_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4337,7 +4432,10 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
MEM_freeN(vert_angles);
}
-static void extract_mesh_analysis_finish(const MeshRenderData *mr, void *buf, void *UNUSED(data))
+static void extract_mesh_analysis_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(data))
{
BLI_assert(mr->edit_bmesh);
@@ -4378,7 +4476,9 @@ static const MeshExtract extract_mesh_analysis = {
/** \name Extract Facedots positions
* \{ */
-static void *extract_fdots_pos_init(const MeshRenderData *mr, void *buf)
+static void *extract_fdots_pos_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4464,7 +4564,9 @@ static const MeshExtract extract_fdots_pos = {
#define NOR_AND_FLAG_ACTIVE -1
#define NOR_AND_FLAG_HIDDEN -2
-static void *extract_fdots_nor_init(const MeshRenderData *mr, void *buf)
+static void *extract_fdots_nor_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4477,7 +4579,10 @@ static void *extract_fdots_nor_init(const MeshRenderData *mr, void *buf)
return NULL;
}
-static void extract_fdots_nor_finish(const MeshRenderData *mr, void *buf, void *UNUSED(data))
+static void extract_fdots_nor_finish(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf,
+ void *UNUSED(data))
{
static float invalid_normal[3] = {0.0f, 0.0f, 0.0f};
GPUVertBuf *vbo = buf;
@@ -4542,7 +4647,9 @@ typedef struct MeshExtract_FdotUV_Data {
int cd_ofs;
} MeshExtract_FdotUV_Data;
-static void *extract_fdots_uv_init(const MeshRenderData *mr, void *buf)
+static void *extract_fdots_uv_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4611,6 +4718,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_fdots_uv_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *data)
{
@@ -4636,7 +4744,9 @@ typedef struct MeshExtract_EditUVFdotData_Data {
int cd_ofs;
} MeshExtract_EditUVFdotData_Data;
-static void *extract_fdots_edituv_data_init(const MeshRenderData *mr, void *buf)
+static void *extract_fdots_edituv_data_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4684,6 +4794,7 @@ static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
}
static void extract_fdots_edituv_data_finish(const MeshRenderData *UNUSED(mr),
+ struct MeshBatchCache *UNUSED(cache),
void *UNUSED(buf),
void *data)
{
@@ -4709,7 +4820,9 @@ typedef struct SkinRootData {
float local_pos[3];
} SkinRootData;
-static void *extract_skin_roots_init(const MeshRenderData *mr, void *buf)
+static void *extract_skin_roots_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
/* Exclusively for edit mode. */
BLI_assert(mr->bm);
@@ -4758,7 +4871,9 @@ static const MeshExtract extract_skin_roots = {
/** \name Extract Selection Index
* \{ */
-static void *extract_select_idx_init(const MeshRenderData *mr, void *buf)
+static void *extract_select_idx_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -4950,7 +5065,9 @@ static const MeshExtract extract_vert_idx = {
.use_threading = true,
};
-static void *extract_select_fdot_idx_init(const MeshRenderData *mr, void *buf)
+static void *extract_select_fdot_idx_init(const MeshRenderData *mr,
+ struct MeshBatchCache *UNUSED(cache),
+ void *buf)
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@@ -5019,6 +5136,7 @@ typedef enum ExtractTaskDataType {
typedef struct ExtractTaskData {
void *next, *prev;
const MeshRenderData *mr;
+ struct MeshBatchCache *cache;
const MeshExtract *extract;
ExtractTaskDataType tasktype;
eMRIterType iter_type;
@@ -5030,6 +5148,7 @@ typedef struct ExtractTaskData {
} ExtractTaskData;
static ExtractTaskData *extract_task_data_create_mesh_extract(const MeshRenderData *mr,
+ struct MeshBatchCache *cache,
const MeshExtract *extract,
void *buf,
int32_t *task_counter)
@@ -5039,6 +5158,7 @@ static ExtractTaskData *extract_task_data_create_mesh_extract(const MeshRenderDa
taskdata->prev = NULL;
taskdata->tasktype = EXTRACT_MESH_EXTRACT;
taskdata->mr = mr;
+ taskdata->cache = cache;
taskdata->extract = extract;
taskdata->buf = buf;
@@ -5056,11 +5176,13 @@ static ExtractTaskData *extract_task_data_create_mesh_extract(const MeshRenderDa
return taskdata;
}
-static ExtractTaskData *extract_task_data_create_lines_loose(const MeshRenderData *mr)
+static ExtractTaskData *extract_task_data_create_lines_loose(const MeshRenderData *mr,
+ struct MeshBatchCache *cache)
{
ExtractTaskData *taskdata = MEM_callocN(sizeof(*taskdata), __func__);
taskdata->tasktype = EXTRACT_LINES_LOOSE;
taskdata->mr = mr;
+ taskdata->cache = cache;
return taskdata;
}
@@ -5152,7 +5274,7 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr,
static void extract_init(ExtractTaskData *data)
{
if (data->tasktype == EXTRACT_MESH_EXTRACT) {
- data->user_data->user_data = data->extract->init(data->mr, data->buf);
+ data->user_data->user_data = data->extract->init(data->mr, data->cache, data->buf);
}
}
@@ -5170,11 +5292,11 @@ static void extract_run(void *__restrict taskdata)
/* If this is the last task, we do the finish function. */
int remainin_tasks = atomic_sub_and_fetch_int32(data->task_counter, 1);
if (remainin_tasks == 0 && data->extract->finish != NULL) {
- data->extract->finish(data->mr, data->buf, data->user_data->user_data);
+ data->extract->finish(data->mr, data->cache, data->buf, data->user_data->user_data);
}
}
else if (data->tasktype == EXTRACT_LINES_LOOSE) {
- extract_lines_loose_subbuffer(data->mr);
+ extract_lines_loose_subbuffer(data->mr, data->cache);
}
}
@@ -5341,6 +5463,7 @@ static void extract_task_create(struct TaskGraph *task_graph,
ListBase *user_data_init_task_datas,
const Scene *scene,
const MeshRenderData *mr,
+ MeshBatchCache *cache,
const MeshExtract *extract,
void *buf,
int32_t *task_counter)
@@ -5356,7 +5479,7 @@ static void extract_task_create(struct TaskGraph *task_graph,
/* Divide extraction of the VBO/IBO into sensible chunks of works. */
ExtractTaskData *taskdata = extract_task_data_create_mesh_extract(
- mr, extract, buf, task_counter);
+ mr, cache, extract, buf, task_counter);
/* Simple heuristic. */
const int chunk_size = 8192;
@@ -5517,7 +5640,6 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
ts,
iter_flag,
data_flag);
- mr->cache = cache; /* HACK */
mr->use_hide = use_hide;
mr->use_subsurf_fdots = use_subsurf_fdots;
mr->use_final_mesh = do_final;
@@ -5549,6 +5671,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
&user_data_init_task_data->task_datas, \
scene, \
mr, \
+ cache, \
&extract_##name, \
mbc.buf.name, \
&task_counters[counter_used++]); \
@@ -5592,13 +5715,14 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
&user_data_init_task_data->task_datas,
scene,
mr,
+ cache,
lines_extractor,
mbc.ibo.lines,
&task_counters[counter_used++]);
}
else {
if (do_lines_loose_subbuffer) {
- ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr);
+ ExtractTaskData *taskdata = extract_task_data_create_lines_loose(mr, cache);
BLI_addtail(&single_threaded_task_data->task_datas, taskdata);
}
}
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 73e0ff7ef83..b93c782a5b9 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -307,7 +307,7 @@ static int curve_render_data_normal_len_get(const CurveRenderData *rdata)
return rdata->normal.len;
}
-static void curve_cd_calc_used_gpu_layers(int *cd_layers,
+static void curve_cd_calc_used_gpu_layers(CustomDataMask *cd_layers,
struct GPUMaterial **gpumat_array,
int gpumat_array_len)
{
@@ -334,16 +334,16 @@ static void curve_cd_calc_used_gpu_layers(int *cd_layers,
switch (type) {
case CD_MTFACE:
- *cd_layers |= CD_MLOOPUV;
+ *cd_layers |= CD_MASK_MLOOPUV;
break;
case CD_TANGENT:
- *cd_layers |= CD_TANGENT;
+ *cd_layers |= CD_MASK_TANGENT;
break;
case CD_MCOL:
/* Curve object don't have Color data. */
break;
case CD_ORCO:
- *cd_layers |= CD_ORCO;
+ *cd_layers |= CD_MASK_ORCO;
break;
}
}
@@ -397,7 +397,7 @@ typedef struct CurveBatchCache {
GPUIndexBuf **surf_per_mat_tris;
GPUBatch **surf_per_mat;
int mat_len;
- int cd_used, cd_needed;
+ CustomDataMask cd_used, cd_needed;
/* settings to determine if cache is invalid */
bool is_dirty;
@@ -998,10 +998,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
if (cache->mat_len > 1) {
DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]);
}
- if (cache->cd_used & CD_MLOOPUV) {
+ if (cache->cd_used & CD_MASK_MLOOPUV) {
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_uv);
}
- if (cache->cd_used & CD_TANGENT) {
+ if (cache->cd_used & CD_MASK_TANGENT) {
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_tan);
}
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_pos_nor);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index d90d7d36ebc..e17ec4f707e 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1314,15 +1314,15 @@ void DRW_draw_callbacks_post_scene(void)
/* annotations - temporary drawing buffer (3d space) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (do_annotations) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, region, true);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
drw_debug_draw();
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
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.
@@ -1331,11 +1331,11 @@ void DRW_draw_callbacks_post_scene(void)
/* needed so gizmo isn't obscured */
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
DRW_draw_gizmo_3d();
}
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
drw_engines_draw_text();
DRW_draw_region_info();
@@ -1343,7 +1343,7 @@ void DRW_draw_callbacks_post_scene(void)
/* annotations - temporary drawing buffer (screenspace) */
/* XXX: Or should we use a proper draw/overlay engine for this case? */
if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
/* XXX: as scene->gpd is not copied for COW yet */
ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, region, false);
}
@@ -1351,18 +1351,18 @@ void DRW_draw_callbacks_post_scene(void)
if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
/* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
* 'DRW_draw_region_info' sets the projection in pixel-space. */
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
DRW_draw_gizmo_2d();
}
if (G.debug_value > 20 && G.debug_value < 30) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
/* local coordinate visible rect inside region, to accommodate overlapping ui */
const rcti *rect = ED_region_visible_rect(DST.draw_ctx.region);
DRW_stats_draw(rect);
}
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
}
@@ -1703,7 +1703,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
GPU_viewport_free(DST.viewport);
DRW_state_reset();
- glDisable(GL_DEPTH_TEST);
+ GPU_depth_test(GPU_DEPTH_NONE);
/* Restore Drawing area. */
GPU_framebuffer_restore();
@@ -2438,7 +2438,7 @@ void DRW_draw_depth_object(
GPU_framebuffer_bind(fbl->depth_only_fb);
GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
const float(*world_clip_planes)[4] = NULL;
if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
@@ -2485,7 +2485,7 @@ void DRW_draw_depth_object(
}
GPU_matrix_set(rv3d->viewmat);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_framebuffer_restore();
DRW_opengl_context_disable();
}
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 44e2eec04d9..9902d3b0aeb 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -301,11 +301,8 @@ void DRW_state_reset(void)
/* Should stay constant during the whole rendering. */
GPU_point_size(5);
GPU_line_smooth(false);
- /* Bypass U.pixelsize factor. */
- glLineWidth(1.0f);
-
- /* Reset blending function */
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ /* Bypass U.pixelsize factor by using a factor of 0.0f. Will be clamped to 1.0f. */
+ GPU_line_width(0.0f);
}
/** \} */
@@ -762,13 +759,8 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
/* Front face is not a resource but it is inside the resource handle. */
bool neg_scale = DRW_handle_negative_scale_get(handle);
if (neg_scale != state->neg_scale) {
- if (DST.view_active->is_inverted) {
- glFrontFace(neg_scale ? GL_CCW : GL_CW);
- }
- else {
- glFrontFace(neg_scale ? GL_CW : GL_CCW);
- }
state->neg_scale = neg_scale;
+ GPU_front_facing(neg_scale != DST.view_active->is_inverted);
}
int chunk = DRW_handle_chunk_get(handle);
@@ -898,7 +890,7 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState
/* Reset state */
if (state->neg_scale) {
- glFrontFace(DST.view_active->is_inverted ? GL_CW : GL_CCW);
+ GPU_front_facing(DST.view_active->is_inverted);
}
if (state->obmats_loc != -1) {
GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
@@ -1110,7 +1102,7 @@ static void drw_draw_pass_ex(DRWPass *pass,
drw_state_validate();
if (DST.view_active->is_inverted) {
- glFrontFace(GL_CW);
+ GPU_front_facing(true);
}
DRW_stats_query_start(pass->name);
@@ -1147,7 +1139,7 @@ static void drw_draw_pass_ex(DRWPass *pass,
/* Reset default. */
if (DST.view_active->is_inverted) {
- glFrontFace(GL_CCW);
+ GPU_front_facing(false);
}
DRW_stats_query_end();
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 0dc35d44788..d01e1a51080 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -105,7 +105,7 @@ void DRW_draw_cursor(void)
GPU_color_mask(true, true, true, true);
GPU_depth_mask(false);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
if (is_cursor_visible(draw_ctx, scene, view_layer)) {
int co[2];
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 2dac273501d..889041daacf 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -419,7 +419,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
GPU_line_width(3.0f);
@@ -441,7 +441,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
immEnd();
/* Reset defaults */
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index 033673a99a8..2896aa25930 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -84,13 +84,13 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info,
* since it causes issues leaving the GL state modified. */
#if 0
GPU_face_culling(GPU_CULL_BACK);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
#endif
GPU_batch_draw(batch);
#if 0
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_face_culling(GPU_CULL_NONE);
#endif
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index 654d1b87918..b6cbbe7712b 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -556,7 +556,7 @@ static void annotation_draw_strokes(const bGPDframe *gpf,
const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
if (no_xray) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
@@ -574,7 +574,7 @@ static void annotation_draw_strokes(const bGPDframe *gpf,
}
if (no_xray) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_polygon_offset(0.0f, 0.0f);
}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 9d11c1c2a25..93767127cc7 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -348,7 +348,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
const int no_xray = (tgpw->dflag & GP_DRAWDATA_NO_XRAY);
if (no_xray) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
@@ -393,7 +393,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw)
}
}
if (no_xray) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_polygon_offset(0.0f, 0.0f);
}
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index ad46dada0c9..dd7ca5c65a4 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -81,18 +81,12 @@ void ED_region_tag_refresh_ui(struct ARegion *region);
void ED_region_tag_redraw_editor_overlays(struct ARegion *region);
void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *region);
-void ED_region_panels_ex(const struct bContext *C,
- struct ARegion *region,
- const char *contexts[],
- int contextnr,
- const bool vertical);
+void ED_region_panels_ex(const struct bContext *C, struct ARegion *region, const char *contexts[]);
void ED_region_panels(const struct bContext *C, struct ARegion *region);
void ED_region_panels_layout_ex(const struct bContext *C,
struct ARegion *region,
struct ListBase *paneltypes,
const char *contexts[],
- int contextnr,
- const bool vertical,
const char *category_override);
void ED_region_panels_layout(const struct bContext *C, struct ARegion *region);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index eb1bd1ba42e..87be3745f87 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -794,8 +794,8 @@ extern int ui_handler_panel_region(struct bContext *C,
const struct wmEvent *event,
struct ARegion *region,
const uiBut *active_but);
-extern void ui_draw_aligned_panel(struct uiStyle *style,
- uiBlock *block,
+extern void ui_draw_aligned_panel(const struct uiStyle *style,
+ const uiBlock *block,
const rcti *rect,
const bool show_pin,
const bool show_background);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 4982a27316c..da7b1da9270 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -134,7 +134,9 @@ static void panel_title_color_get(bool show_background, uchar color[4])
}
}
-static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, bool *no_animation)
+static bool panel_active_animation_changed(ListBase *lb,
+ Panel **r_panel_animation,
+ bool *r_no_animation)
{
LISTBASE_FOREACH (Panel *, panel, lb) {
/* Detect panel active flag changes. */
@@ -148,7 +150,7 @@ static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, b
}
if ((panel->runtime_flag & PNL_ACTIVE) && !(panel->flag & PNL_CLOSED)) {
- if (panel_active_animation_changed(&panel->children, pa_animation, no_animation)) {
+ if (panel_active_animation_changed(&panel->children, r_panel_animation, r_no_animation)) {
return true;
}
}
@@ -157,15 +159,15 @@ static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, b
if (panel->activedata) {
uiHandlePanelData *data = panel->activedata;
if (data->state == PANEL_STATE_ANIMATION) {
- *pa_animation = panel;
+ *r_panel_animation = panel;
}
else {
/* Don't animate while handling other interaction. */
- *no_animation = true;
+ *r_no_animation = true;
}
}
- if ((panel->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) {
- *pa_animation = panel;
+ if ((panel->runtime_flag & PNL_ANIM_ALIGN) && !(*r_panel_animation)) {
+ *r_panel_animation = panel;
}
}
@@ -604,7 +606,7 @@ static void panels_collapse_all(const bContext *C, ARegion *region, const Panel
if (!pt->context[0] || !from_pt->context[0] || STREQ(pt->context, from_pt->context)) {
if ((panel->flag & PNL_PIN) || !category || !pt->category[0] ||
STREQ(pt->category, category)) {
- panel->flag &= ~PNL_CLOSED;
+ panel->flag |= PNL_CLOSED;
}
}
}
@@ -842,54 +844,43 @@ void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y)
}
}
-static void ui_draw_aligned_panel_header(
- uiStyle *style, uiBlock *block, const rcti *rect, char dir, const bool show_background)
+static void ui_draw_aligned_panel_header(const uiStyle *style,
+ const uiBlock *block,
+ const rcti *rect,
+ const bool show_background)
{
- Panel *panel = block->panel;
- rcti hrect;
- int pnl_icons;
- const char *activename = panel->drawname;
+ const Panel *panel = block->panel;
const bool is_subpanel = (panel->type && panel->type->parent);
- uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
- uchar col_title[4];
+ const uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
/* + 0.001f to avoid flirting with float inaccuracy */
- pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
+ int pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
/* draw text label */
+ uchar col_title[4];
panel_title_color_get(show_background, col_title);
col_title[3] = 255;
- hrect = *rect;
- if (dir == 'h') {
- hrect.xmin = rect->xmin + pnl_icons;
- hrect.ymin -= 2.0f / block->aspect;
- UI_fontstyle_draw(fontstyle,
- &hrect,
- activename,
- col_title,
- &(struct uiFontStyleDraw_Params){
- .align = UI_STYLE_TEXT_LEFT,
- });
- }
- else {
- /* ignore 'pnl_icons', otherwise the text gets offset horizontally
- * + 0.001f to avoid flirting with float inaccuracy
- */
- hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
- UI_fontstyle_draw_rotated(fontstyle, &hrect, activename, col_title);
- }
+ rcti hrect = *rect;
+ hrect.xmin = rect->xmin + pnl_icons;
+ hrect.ymin -= 2.0f / block->aspect;
+ UI_fontstyle_draw(fontstyle,
+ &hrect,
+ panel->drawname,
+ col_title,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_LEFT,
+ });
}
/* panel integrated in buttonswindow, tool/property lists etc */
-void ui_draw_aligned_panel(uiStyle *style,
- uiBlock *block,
+void ui_draw_aligned_panel(const uiStyle *style,
+ const uiBlock *block,
const rcti *rect,
const bool show_pin,
const bool show_background)
{
- Panel *panel = block->panel;
- rctf itemrect;
+ const Panel *panel = block->panel;
float color[4];
const bool is_subpanel = (panel->type && panel->type->parent);
const bool show_drag = (!is_subpanel &&
@@ -1005,11 +996,12 @@ void ui_draw_aligned_panel(uiStyle *style,
if (is_subpanel) {
titlerect.xmin += (0.7f * UI_UNIT_X) / block->aspect + 0.001f;
}
- ui_draw_aligned_panel_header(style, block, &titlerect, 'h', show_background);
+ ui_draw_aligned_panel_header(style, block, &titlerect, show_background);
if (show_drag) {
/* itemrect smaller */
const float scale = 0.7;
+ rctf itemrect;
itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X);
itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
itemrect.ymin = headrect.ymin;
@@ -1090,20 +1082,16 @@ void ui_draw_aligned_panel(uiStyle *style,
immUnbindProgram();
}
- uchar col_title[4];
- panel_title_color_get(show_background, col_title);
-
/* draw collapse icon */
-
- /* itemrect smaller */
- itemrect.xmin = titlerect.xmin;
- itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect);
- itemrect.ymin = titlerect.ymin;
- itemrect.ymax = titlerect.ymax;
-
- BLI_rctf_scale(&itemrect, 0.25f);
-
{
+ rctf itemrect = {.xmin = titlerect.xmin,
+ .xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect),
+ .ymin = titlerect.ymin,
+ .ymax = titlerect.ymax};
+ BLI_rctf_scale(&itemrect, 0.25f);
+
+ uchar col_title[4];
+ panel_title_color_get(show_background, col_title);
float tria_color[4];
rgb_uchar_to_float(tria_color, col_title);
tria_color[3] = 1.0f;
@@ -1240,11 +1228,10 @@ static void align_sub_panels(Panel *panel)
/* returns 1 when it did something */
static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
{
- PanelSort *ps, *panelsort, *psnext;
- int a, tot = 0;
- bool done;
+ int i;
/* count active, not tabbed panels */
+ int tot = 0;
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if (panel->runtime_flag & PNL_ACTIVE) {
tot++;
@@ -1256,9 +1243,9 @@ static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
}
/* sort panels */
- panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort");
+ PanelSort *panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort");
- ps = panelsort;
+ PanelSort *ps = panelsort;
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if (panel->runtime_flag & PNL_ACTIVE) {
ps->panel = MEM_dupallocN(panel);
@@ -1271,8 +1258,8 @@ static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
/* while we are dragging, we sort on location and update sortorder */
qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel);
- for (ps = panelsort, a = 0; a < tot; a++, ps++) {
- ps->orig->sortorder = a;
+ for (ps = panelsort, i = 0; i < tot; i++, ps++) {
+ ps->orig->sortorder = i;
}
}
else {
@@ -1287,8 +1274,8 @@ static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
ps->panel->ofsy = -get_panel_size_y(ps->panel);
ps->panel->ofsx += ps->panel->runtime.region_ofsx;
- for (a = 0; a < tot - 1; a++, ps++) {
- psnext = ps + 1;
+ for (i = 0; i < tot - 1; i++, ps++) {
+ PanelSort *psnext = ps + 1;
bool use_box = ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX;
bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX;
@@ -1307,16 +1294,16 @@ static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
}
/* we interpolate */
- done = false;
+ bool changed = false;
ps = panelsort;
- for (a = 0; a < tot; a++, ps++) {
+ for (i = 0; i < tot; i++, ps++) {
if ((ps->panel->flag & PNL_SELECT) == 0) {
if ((ps->orig->ofsx != ps->panel->ofsx) || (ps->orig->ofsy != ps->panel->ofsy)) {
ps->orig->ofsx = round_fl_to_int(fac * (float)ps->panel->ofsx +
(1.0f - fac) * (float)ps->orig->ofsx);
ps->orig->ofsy = round_fl_to_int(fac * (float)ps->panel->ofsy +
(1.0f - fac) * (float)ps->orig->ofsy);
- done = true;
+ changed = true;
}
}
}
@@ -1331,12 +1318,12 @@ static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag)
}
/* free panelsort array */
- for (ps = panelsort, a = 0; a < tot; a++, ps++) {
+ for (ps = panelsort, i = 0; i < tot; i++, ps++) {
MEM_freeN(ps->panel);
}
MEM_freeN(panelsort);
- return done;
+ return changed;
}
static void ui_panels_size(ARegion *region, int *r_x, int *r_y)
@@ -1370,9 +1357,8 @@ static void ui_do_animate(bContext *C, Panel *panel)
{
uiHandlePanelData *data = panel->activedata;
ARegion *region = CTX_wm_region(C);
- float fac;
- fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
+ float fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
fac = min_ff(sqrtf(fac), 1.0f);
/* for max 1 second, interpolate positions */
@@ -1422,7 +1408,6 @@ void UI_panels_begin(const bContext *UNUSED(C), ARegion *region)
void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
{
ScrArea *area = CTX_wm_area(C);
- Panel *panel, *panel_first;
/* offset contents */
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
@@ -1432,6 +1417,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
}
/* re-align, possibly with animation */
+ Panel *panel;
if (panels_need_realign(area, region, &panel)) {
if (panel) {
panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
@@ -1442,7 +1428,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
}
/* tag first panel */
- panel_first = NULL;
+ Panel *panel_first = NULL;
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
if (block->active && block->panel) {
if (!panel_first || block->panel->sortorder < panel_first->sortorder) {
@@ -1512,8 +1498,8 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
float dy = (float)(y - data->starty);
/* Adjust for region zoom. */
- dx *= (float)BLI_rctf_size_x(&region->v2d.cur) / (float)BLI_rcti_size_x(&region->winrct);
- dy *= (float)BLI_rctf_size_y(&region->v2d.cur) / (float)BLI_rcti_size_y(&region->winrct);
+ dx *= BLI_rctf_size_x(&region->v2d.cur) / (float)BLI_rcti_size_x(&region->winrct);
+ dy *= BLI_rctf_size_y(&region->v2d.cur) / (float)BLI_rcti_size_y(&region->winrct);
if (data->state == PANEL_STATE_DRAG_SCALE) {
panel->sizex = MAX2(data->startsizex + dx, UI_PANEL_MINX);
@@ -1577,23 +1563,21 @@ static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *use
MEM_freeN(dragcol_data);
}
-static void ui_panel_drag_collapse(bContext *C,
- uiPanelDragCollapseHandle *dragcol_data,
+static void ui_panel_drag_collapse(const bContext *C,
+ const uiPanelDragCollapseHandle *dragcol_data,
const int xy_dst[2])
{
ARegion *region = CTX_wm_region(C);
- Panel *panel;
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)};
float xy_b_block[2] = {UNPACK2(xy_dst)};
- rctf rect = block->rect;
- int oldflag;
+ Panel *panel = block->panel;
- if ((panel = block->panel) == 0 || (panel->type && (panel->type->flag & PNL_NO_HEADER))) {
+ if (panel == NULL || (panel->type && (panel->type->flag & PNL_NO_HEADER))) {
continue;
}
- oldflag = panel->flag;
+ int oldflag = panel->flag;
/* lock axis */
xy_b_block[0] = dragcol_data->xy_init[0];
@@ -1603,6 +1587,7 @@ static void ui_panel_drag_collapse(bContext *C,
ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]);
/* set up rect to match header size */
+ rctf rect = block->rect;
rect.ymin = rect.ymax;
rect.ymax = rect.ymin + PNL_HEADER;
@@ -1934,10 +1919,9 @@ static void ui_panel_category_draw_tab(bool filled,
const uchar col[3])
{
float vec[4][2] = {{0.195, 0.02}, {0.55, 0.169}, {0.831, 0.45}, {0.98, 0.805}};
- int a;
/* mult */
- for (a = 0; a < 4; a++) {
+ for (int a = 0; a < 4; a++) {
mul_v2_fl(vec[a], rad);
}
@@ -1962,7 +1946,7 @@ static void ui_panel_category_draw_tab(bool filled,
if (use_highlight) {
if (roundboxtype & UI_CNR_TOP_RIGHT) {
imm_buf_append(vbuf, cbuf, maxx, maxy - rad, col, &buf_index);
- for (a = 0; a < 4; a++) {
+ for (int a = 0; a < 4; a++) {
imm_buf_append(vbuf, cbuf, maxx - vec[a][1], maxy - rad + vec[a][0], col, &buf_index);
}
imm_buf_append(vbuf, cbuf, maxx - rad, maxy, col, &buf_index);
@@ -1974,7 +1958,7 @@ static void ui_panel_category_draw_tab(bool filled,
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
imm_buf_append(vbuf, cbuf, minx + rad, maxy, col, &buf_index);
- for (a = 0; a < 4; a++) {
+ for (int a = 0; a < 4; a++) {
imm_buf_append(vbuf, cbuf, minx + rad - vec[a][0], maxy - vec[a][1], col, &buf_index);
}
imm_buf_append(vbuf, cbuf, minx, maxy - rad, col, &buf_index);
@@ -1992,7 +1976,7 @@ static void ui_panel_category_draw_tab(bool filled,
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
imm_buf_append(vbuf, cbuf, minx, miny + rad, col, &buf_index);
- for (a = 0; a < 4; a++) {
+ for (int a = 0; a < 4; a++) {
imm_buf_append(vbuf, cbuf, minx + vec[a][1], miny + rad - vec[a][0], col, &buf_index);
}
imm_buf_append(vbuf, cbuf, minx + rad, miny, col, &buf_index);
@@ -2004,7 +1988,7 @@ static void ui_panel_category_draw_tab(bool filled,
/* corner right-bottom */
if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
imm_buf_append(vbuf, cbuf, maxx - rad, miny, col, &buf_index);
- for (a = 0; a < 4; a++) {
+ for (int a = 0; a < 4; a++) {
imm_buf_append(vbuf, cbuf, maxx - rad + vec[a][0], miny + vec[a][1], col, &buf_index);
}
imm_buf_append(vbuf, cbuf, maxx, miny + rad, col, &buf_index);
@@ -2386,11 +2370,9 @@ int ui_handler_panel_region(bContext *C,
ARegion *region,
const uiBut *active_but)
{
- Panel *panel;
- int retval, mx, my;
- bool has_category_tabs = UI_panel_category_is_visible(region);
+ const bool has_category_tabs = UI_panel_category_is_visible(region);
- retval = WM_UI_HANDLER_CONTINUE;
+ int retval = WM_UI_HANDLER_CONTINUE;
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
return retval;
@@ -2431,12 +2413,12 @@ int ui_handler_panel_region(bContext *C,
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
uiPanelMouseState mouse_state;
- mx = event->x;
- my = event->y;
+ int mx = event->x;
+ int my = event->y;
ui_window_to_block(region, block, &mx, &my);
/* checks for mouse position inside */
- panel = block->panel;
+ Panel *panel = block->panel;
if (!panel) {
continue;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index c1801290152..bf64672fd81 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1096,7 +1096,8 @@ static void widgetbase_outline(uiWidgetBase *wtb, uint pos)
float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
- widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
+ widget_draw_vertex_buffer(
+ pos, 0, GPU_PRIM_TRI_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
}
static void widgetbase_set_uniform_alpha_discard(uiWidgetBase *wtb,
@@ -2758,7 +2759,7 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
- widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, totvert * 2);
+ widget_draw_vertex_buffer(pos, 0, GPU_PRIM_TRI_STRIP, triangle_strip, NULL, totvert * 2);
}
immUnbindProgram();
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index dbaa335a9bf..8acbb328ab0 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -750,7 +750,7 @@ void ED_mask_draw_region(
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_R16F, false, buffer, 1.0f, 1.0f, NULL);
+ immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GPU_R16F, false, buffer, 1.0f, 1.0f, NULL);
GPU_matrix_pop();
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 94cd7650abe..6facee77c1e 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1051,7 +1051,7 @@ static void knife_init_colors(KnifeColors *colors)
static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
{
const KnifeTool_OpData *kcd = arg;
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_matrix_push_projection();
GPU_polygon_offset(1.0f, 1.0f);
@@ -1222,7 +1222,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
GPU_matrix_pop_projection();
/* Reset default */
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
/**
diff --git a/source/blender/editors/mesh/editmesh_preselect_edgering.c b/source/blender/editors/mesh/editmesh_preselect_edgering.c
index d9bd63ef35f..aa1df3d76fc 100644
--- a/source/blender/editors/mesh/editmesh_preselect_edgering.c
+++ b/source/blender/editors/mesh/editmesh_preselect_edgering.c
@@ -159,7 +159,7 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
return;
}
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_matrix_push();
GPU_matrix_mul(matrix);
@@ -197,7 +197,7 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl
GPU_matrix_pop();
/* Reset default */
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
static void view3d_preselect_mesh_edgering_update_verts_from_edge(
diff --git a/source/blender/editors/mesh/editmesh_preselect_elem.c b/source/blender/editors/mesh/editmesh_preselect_elem.c
index d53a1e2b55c..dfd646c767f 100644
--- a/source/blender/editors/mesh/editmesh_preselect_elem.c
+++ b/source/blender/editors/mesh/editmesh_preselect_elem.c
@@ -133,7 +133,7 @@ void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matr
return;
}
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_matrix_push();
GPU_matrix_mul(matrix);
@@ -204,7 +204,7 @@ void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matr
GPU_matrix_pop();
/* Reset default */
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
static void view3d_preselect_mesh_elem_update_from_vert(struct EditMesh_PreSelElem *psel,
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 139900d0a4d..a59d8136f47 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1450,6 +1450,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -2783,6 +2784,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -3003,6 +3005,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
@@ -3094,6 +3097,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
ED_outliner_select_sync_from_object_tag(C);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index c9b20e49329..22b39d631c7 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -302,8 +302,6 @@ static void area_azone_tag_update(ScrArea *area)
static void region_draw_azones(ScrArea *area, ARegion *region)
{
- AZone *az;
-
if (!area) {
return;
}
@@ -314,7 +312,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region)
GPU_matrix_push();
GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin);
- for (az = area->actionzones.first; az; az = az->next) {
+ LISTBASE_FOREACH (AZone *, az, &area->actionzones) {
/* test if action zone is over this region */
rcti azrct;
BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2);
@@ -705,10 +703,8 @@ void ED_region_tag_redraw_partial(ARegion *region, const rcti *rct, bool rebuild
void ED_area_tag_redraw(ScrArea *area)
{
- ARegion *region;
-
if (area) {
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
ED_region_tag_redraw(region);
}
}
@@ -716,10 +712,8 @@ void ED_area_tag_redraw(ScrArea *area)
void ED_area_tag_redraw_no_rebuild(ScrArea *area)
{
- ARegion *region;
-
if (area) {
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
ED_region_tag_redraw_no_rebuild(region);
}
}
@@ -727,10 +721,8 @@ void ED_area_tag_redraw_no_rebuild(ScrArea *area)
void ED_area_tag_redraw_regiontype(ScrArea *area, int regiontype)
{
- ARegion *region;
-
if (area) {
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == regiontype) {
ED_region_tag_redraw(region);
}
@@ -750,14 +742,12 @@ void ED_area_tag_refresh(ScrArea *area)
/* use NULL to disable it */
void ED_area_status_text(ScrArea *area, const char *str)
{
- ARegion *region;
-
/* happens when running transform operators in background mode */
if (area == NULL) {
return;
}
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_HEADER) {
if (str) {
if (region->headerstr == NULL) {
@@ -942,7 +932,6 @@ static void region_azone_edge(AZone *az, ARegion *region)
/* region already made zero sized, in shape of edge */
static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region)
{
- AZone *azt;
int tot = 0, add;
/* Edge offset multiplied by the */
@@ -950,7 +939,7 @@ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region)
const float tab_size_x = 0.7f * U.widget_unit;
const float tab_size_y = 0.4f * U.widget_unit;
- for (azt = area->actionzones.first; azt; azt = azt->next) {
+ LISTBASE_FOREACH (AZone *, azt, &area->actionzones) {
if (azt->edge == az->edge) {
tot++;
}
@@ -1850,7 +1839,6 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
WorkSpace *workspace = WM_window_get_active_workspace(win);
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- ARegion *region;
rcti rect, overlap_rect;
rcti window_rect;
@@ -1867,7 +1855,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
area->type = BKE_spacetype_from_id(area->spacetype);
}
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype);
}
@@ -1891,7 +1879,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
area_azone_init(win, screen, area);
/* region windows, default and own handlers */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region_subwindow(region);
if (region->visible) {
@@ -2010,7 +1998,6 @@ void ED_region_toggle_hidden(bContext *C, ARegion *region)
void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free)
{
SpaceType *st;
- ARegion *region;
const char spacetype = area_dst->spacetype;
const short flag_copy = HEADER_NO_PULLDOWN;
@@ -2030,13 +2017,13 @@ void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free)
/* regions */
if (do_free) {
st = BKE_spacetype_from_id(spacetype);
- for (region = area_dst->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area_dst->regionbase) {
BKE_area_region_free(st, region);
}
BLI_freelistN(&area_dst->regionbase);
}
st = BKE_spacetype_from_id(area_src->spacetype);
- for (region = area_src->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area_src->regionbase) {
ARegion *newar = BKE_area_region_copy(st, region);
BLI_addtail(&area_dst->regionbase, newar);
}
@@ -2324,7 +2311,6 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
if (area->spacetype != type) {
SpaceType *st;
SpaceLink *slold = area->spacedata.first;
- SpaceLink *sl;
/* store area->type->exit callback */
void *area_exit = area->type ? area->type->exit : NULL;
/* When the user switches between space-types from the type-selector,
@@ -2368,8 +2354,10 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
* (e.g. with properties editor) until space-data is properly created */
/* check previously stored space */
- for (sl = area->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == type) {
+ SpaceLink *sl = NULL;
+ LISTBASE_FOREACH (SpaceLink *, sl_iter, &area->spacedata) {
+ if (sl_iter->spacetype == type) {
+ sl = sl_iter;
break;
}
}
@@ -2573,14 +2561,12 @@ BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
* correct old \a uiBlock, and NULL otherwise.
*/
static void ed_panel_draw(const bContext *C,
- ScrArea *area,
ARegion *region,
ListBase *lb,
PanelType *pt,
Panel *panel,
int w,
int em,
- bool vertical,
char *unique_panel_str)
{
const uiStyle *style = UI_style_get_dpi();
@@ -2602,7 +2588,7 @@ static void ed_panel_draw(const bContext *C,
int xco, yco, h = 0;
int headerend = w - UI_UNIT_X;
- if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER)) {
/* for preset menu */
panel->layout = UI_block_layout(block,
UI_LAYOUT_HORIZONTAL,
@@ -2621,7 +2607,7 @@ static void ed_panel_draw(const bContext *C,
panel->layout = NULL;
}
- if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
+ if (pt->draw_header && !(pt->flag & PNL_NO_HEADER)) {
int labelx, labely;
UI_panel_label_offset(block, &labelx, &labely);
@@ -2698,16 +2684,7 @@ static void ed_panel_draw(const bContext *C,
Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt);
if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) {
- ed_panel_draw(C,
- area,
- region,
- &panel->children,
- child_pt,
- child_panel,
- w,
- em,
- vertical,
- unique_panel_str);
+ ed_panel_draw(C, region, &panel->children, child_pt, child_panel, w, em, unique_panel_str);
}
}
}
@@ -2724,14 +2701,12 @@ void ED_region_panels_layout_ex(const bContext *C,
ARegion *region,
ListBase *paneltypes,
const char *contexts[],
- int contextnr,
- const bool vertical,
const char *category_override)
{
/* collect panels to draw */
WorkSpace *workspace = CTX_wm_workspace(C);
LinkNode *panel_types_stack = NULL;
- for (PanelType *pt = paneltypes->last; pt; pt = pt->prev) {
+ LISTBASE_FOREACH_BACKWARD (PanelType *, pt, paneltypes) {
/* Only draw top level panels. */
if (pt->parent) {
continue;
@@ -2776,25 +2751,13 @@ void ED_region_panels_layout_ex(const bContext *C,
const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH;
int margin_x = 0;
const bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE;
- const bool is_context_new = (contextnr != -1) ? UI_view2d_tab_set(v2d, contextnr) : false;
bool update_tot_size = true;
- /* before setting the view */
- if (vertical) {
- /* only allow scrolling in vertical direction */
- v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
- v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
- v2d->scroll &= ~V2D_SCROLL_BOTTOM;
- v2d->scroll |= V2D_SCROLL_RIGHT;
- }
- else {
- /* for now, allow scrolling in both directions (since layouts are optimized for vertical,
- * they often don't fit in horizontal layout)
- */
- v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
- v2d->scroll |= V2D_SCROLL_BOTTOM;
- v2d->scroll &= ~V2D_SCROLL_RIGHT;
- }
+ /* only allow scrolling in vertical direction */
+ v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
+ v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
+ v2d->scroll &= ~V2D_SCROLL_BOTTOM;
+ v2d->scroll |= V2D_SCROLL_RIGHT;
/* collect categories */
if (use_category_tabs) {
@@ -2819,14 +2782,8 @@ void ED_region_panels_layout_ex(const bContext *C,
}
}
- if (vertical) {
- w = BLI_rctf_size_x(&v2d->cur);
- em = (region->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */
- }
- else {
- w = UI_PANEL_WIDTH;
- em = (region->type->prefsizex) ? 10 : 20;
- }
+ w = BLI_rctf_size_x(&v2d->cur);
+ em = (region->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */
w -= margin_x;
int w_box_panel = w - UI_PANEL_BOX_STYLE_MARGIN * 2.0f;
@@ -2859,14 +2816,12 @@ void ED_region_panels_layout_ex(const bContext *C,
}
ed_panel_draw(C,
- area,
region,
&region->panels,
pt,
panel,
(pt->flag & PNL_DRAW_BOX) ? w_box_panel : w,
em,
- vertical,
NULL);
}
@@ -2894,14 +2849,12 @@ void ED_region_panels_layout_ex(const bContext *C,
char unique_panel_str[8];
UI_list_panel_unique_str(panel, unique_panel_str);
ed_panel_draw(C,
- area,
region,
&region->panels,
panel->type,
panel,
(panel->type->flag & PNL_DRAW_BOX) ? w_box_panel : w,
em,
- vertical,
unique_panel_str);
}
}
@@ -2929,7 +2882,7 @@ void ED_region_panels_layout_ex(const bContext *C,
y = fabsf(region->sizey * UI_DPI_FAC - 1);
}
}
- else if (vertical) {
+ else {
/* We always keep the scroll offset -
* so the total view gets increased with the scrolled away part. */
if (v2d->cur.ymax < -FLT_EPSILON) {
@@ -2944,19 +2897,6 @@ void ED_region_panels_layout_ex(const bContext *C,
y = -y;
}
- else {
- /* don't jump back when panels close or hide */
- if (!is_context_new) {
- if (v2d->tot.xmax > v2d->winx) {
- x = max_ii(x, 0);
- }
- else {
- x = max_ii(x, v2d->cur.xmax);
- }
- }
-
- y = -y;
- }
if (update_tot_size) {
/* this also changes the 'cur' */
@@ -2970,8 +2910,7 @@ void ED_region_panels_layout_ex(const bContext *C,
void ED_region_panels_layout(const bContext *C, ARegion *region)
{
- bool vertical = true;
- ED_region_panels_layout_ex(C, region, &region->type->paneltypes, NULL, -1, vertical, NULL);
+ ED_region_panels_layout_ex(C, region, &region->type->paneltypes, NULL, NULL);
}
void ED_region_panels_draw(const bContext *C, ARegion *region)
@@ -3015,12 +2954,10 @@ void ED_region_panels_draw(const bContext *C, ARegion *region)
UI_view2d_scrollers_draw(v2d, mask);
}
-void ED_region_panels_ex(
- const bContext *C, ARegion *region, const char *contexts[], int contextnr, const bool vertical)
+void ED_region_panels_ex(const bContext *C, ARegion *region, const char *contexts[])
{
/* TODO: remove? */
- ED_region_panels_layout_ex(
- C, region, &region->type->paneltypes, contexts, contextnr, vertical, NULL);
+ ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
ED_region_panels_draw(C, region);
}
@@ -3046,7 +2983,6 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
const uiStyle *style = UI_style_get_dpi();
uiBlock *block;
uiLayout *layout;
- HeaderType *ht;
Header header = {NULL};
bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE;
@@ -3069,7 +3005,7 @@ void ED_region_header_layout(const bContext *C, ARegion *region)
UI_view2d_view_ortho(&region->v2d);
/* draw all headers types */
- for (ht = region->type->headertypes.first; ht; ht = ht->next) {
+ LISTBASE_FOREACH (HeaderType *, ht, &region->type->headertypes) {
if (ht->poll && !ht->poll(C, ht)) {
continue;
}
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index c17a34f97b9..3c70bf1bfd8 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -204,7 +204,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
- EditBone *ebone, *flipbone = NULL;
+ EditBone *flipbone = NULL;
const bool editable_bones = CTX_data_equals(member, "editable_bones");
if (arm && arm->edbo) {
@@ -216,7 +216,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
arm = ob->data;
/* Attention: X-Axis Mirroring is also handled here... */
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
/* first and foremost, bone must be visible and selected */
if (EBONE_VISIBLE(arm, ebone)) {
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
@@ -262,7 +262,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
if (CTX_data_equals(member, "selected_bones") ||
CTX_data_equals(member, "selected_editable_bones")) {
bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
- EditBone *ebone, *flipbone = NULL;
+ EditBone *flipbone = NULL;
const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
if (arm && arm->edbo) {
@@ -274,7 +274,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
arm = ob->data;
/* Attention: X-Axis Mirroring is also handled here... */
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
/* first and foremost, bone must be visible and selected */
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
@@ -479,8 +479,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
if (CTX_data_equals(member, "sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
- Sequence *seq;
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
}
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
@@ -491,8 +490,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
if (CTX_data_equals(member, "selected_sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
- Sequence *seq;
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
if (seq->flag & SELECT) {
CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
}
@@ -505,8 +503,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
if (CTX_data_equals(member, "selected_editable_sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (ed) {
- Sequence *seq;
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
}
@@ -520,16 +517,14 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bAnimContext ac;
if (ANIM_animdata_get_context(C, &ac) != 0) {
ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
ANIM_animdata_filter(&ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
+ LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
if (ale->datatype != ALE_NLASTRIP) {
continue;
}
NlaTrack *nlt = (NlaTrack *)ale->data;
- NlaStrip *strip;
- for (strip = nlt->strips.first; strip; strip = strip->next) {
+ LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
if (strip->flag & NLASTRIP_FLAG_SELECT) {
CTX_data_list_add(result, &scene->id, &RNA_NlaStrip, strip);
}
@@ -637,9 +632,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
- bGPDlayer *gpl;
-
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
if ((gpl->flag & GP_LAYER_HIDE) == 0) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
}
@@ -653,9 +646,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact);
if (gpd) {
- bGPDlayer *gpl;
-
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
if (BKE_gpencil_layer_is_editable(gpl)) {
CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
}
@@ -670,12 +661,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
if (gpd) {
- bGPDlayer *gpl;
-
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
bGPDframe *gpf;
- bGPDstroke *gps;
bGPDframe *init_gpf = gpl->actframe;
if (is_multiedit) {
init_gpf = gpl->frames.first;
@@ -683,7 +671,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
for (gpf = init_gpf; gpf; gpf = gpf->next) {
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (ED_gpencil_stroke_can_use_direct(area, gps)) {
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) {
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index a5d3c4842e6..9bb14ee8c01 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -379,11 +379,9 @@ void ED_screen_draw_edges(wmWindow *win)
float col[4], corner_scale, edge_thickness;
int verts_per_corner = 0;
- ScrArea *area;
-
rcti scissor_rect;
BLI_rcti_init_minmax(&scissor_rect);
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){area->v1->vec.x, area->v1->vec.y});
BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){area->v3->vec.x, area->v3->vec.y});
}
@@ -418,7 +416,7 @@ void ED_screen_draw_edges(wmWindow *win)
GPU_batch_uniform_1f(batch, "scale", corner_scale);
GPU_batch_uniform_4fv(batch, "color", col);
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
drawscredge_area(area, winsize_x, winsize_y, edge_thickness);
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index dbf84cad80b..f534296bd0b 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -230,8 +230,7 @@ bScreen *screen_add(Main *bmain, const char *name, const rcti *rect)
void screen_data_copy(bScreen *to, bScreen *from)
{
- ScrVert *s1, *s2;
- ScrEdge *se;
+ ScrVert *s2;
ScrArea *area, *saf;
/* free contents of 'to', is from blenkernel screen.c */
@@ -245,11 +244,11 @@ void screen_data_copy(bScreen *to, bScreen *from)
BLI_listbase_clear(&to->regionbase);
s2 = to->vertbase.first;
- for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) {
+ for (ScrVert *s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) {
s1->newv = s2;
}
- for (se = to->edgebase.first; se; se = se->next) {
+ LISTBASE_FOREACH (ScrEdge *, se, &to->edgebase) {
se->v1 = se->v1->newv;
se->v2 = se->v2->newv;
BKE_screen_sort_scrvert(&(se->v1), &(se->v2));
@@ -271,7 +270,7 @@ void screen_data_copy(bScreen *to, bScreen *from)
}
/* put at zero (needed?) */
- for (s1 = from->vertbase.first; s1; s1 = s1->next) {
+ LISTBASE_FOREACH (ScrVert *, s1, &from->vertbase) {
s1->newv = NULL;
}
}
@@ -538,9 +537,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
/* file read, set all screens, ... */
void ED_screens_init(Main *bmain, wmWindowManager *wm)
{
- wmWindow *win;
-
- for (win = wm->windows.first; win; win = win->next) {
+ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
if (BKE_workspace_active_get(win->workspace_hook) == NULL) {
BKE_workspace_active_set(win->workspace_hook, bmain->workspaces.first);
}
@@ -552,7 +549,7 @@ void ED_screens_init(Main *bmain, wmWindowManager *wm)
}
if (U.uiflag & USER_HEADER_FROM_PREF) {
- for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
BKE_screen_header_alignment_reset(screen);
}
}
@@ -614,7 +611,6 @@ void ED_area_exit(bContext *C, ScrArea *area)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
ScrArea *prevsa = CTX_wm_area(C);
- ARegion *region;
if (area->type && area->type->exit) {
area->type->exit(wm, area);
@@ -622,7 +618,7 @@ void ED_area_exit(bContext *C, ScrArea *area)
CTX_wm_area_set(C, area);
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
ED_region_exit(C, region);
}
@@ -683,10 +679,11 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
{
const bScreen *screen = WM_window_get_active_screen(win);
AZone *az = NULL;
- ScrArea *area;
+ ScrArea *area = NULL;
- for (area = screen->areabase.first; area; area = area->next) {
- if ((az = ED_area_actionzone_find_xy(area, xy))) {
+ LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
+ if ((az = ED_area_actionzone_find_xy(area_iter, xy))) {
+ area = area_iter;
break;
}
}
@@ -733,7 +730,6 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
}
ScrArea *area = NULL;
- ARegion *region;
ARegion *region_prev = screen->active_region;
ED_screen_areas_iter (win, screen, area_iter) {
@@ -750,7 +746,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
}
if (area) {
/* Make overlap active when mouse over. */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (ED_region_contains_xy(region, xy)) {
screen->active_region = region;
break;
@@ -767,8 +763,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
ED_screen_areas_iter (win, screen, area_iter) {
bool do_draw = false;
- for (region = area_iter->regionbase.first; region; region = region->next) {
-
+ LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) {
/* Call old area's deactivate if assigned. */
if (region == region_prev && area_iter->type->deactivate) {
area_iter->type->deactivate(area_iter);
@@ -789,7 +784,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
}
if (do_draw) {
- for (region = area_iter->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) {
if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
ED_region_tag_redraw_no_rebuild(region);
}
@@ -826,13 +821,12 @@ int ED_screen_area_active(const bContext *C)
if (win && screen && area) {
AZone *az = ED_area_actionzone_find_xy(area, &win->eventstate->x);
- ARegion *region;
if (az && az->type == AZONE_REGION) {
return 1;
}
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region == screen->active_region) {
return 1;
}
@@ -883,10 +877,10 @@ static void screen_global_area_refresh(wmWindow *win,
const short height_min,
const short height_max)
{
- ScrArea *area;
-
- for (area = win->global_areas.areabase.first; area; area = area->next) {
- if (area->spacetype == space_type) {
+ ScrArea *area = NULL;
+ LISTBASE_FOREACH (ScrArea *, area_iter, &win->global_areas.areabase) {
+ if (area_iter->spacetype == space_type) {
+ area = area_iter;
break;
}
}
@@ -1081,7 +1075,6 @@ static void screen_set_3dview_camera(Scene *scene,
v3d->camera = BKE_view_layer_camera_find(view_layer);
// XXX if (screen == curscreen) handle_view3d_lock();
if (!v3d->camera) {
- ARegion *region;
ListBase *regionbase;
/* regionbase is in different place depending if space is active */
@@ -1092,7 +1085,7 @@ static void screen_set_3dview_camera(Scene *scene,
regionbase = &v3d->regionbase;
}
- for (region = regionbase->first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
@@ -1240,13 +1233,12 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
wmWindowManager *wm = CTX_wm_manager(C);
WorkSpace *workspace = WM_window_get_active_workspace(win);
bScreen *screen, *oldscreen;
- ARegion *region;
if (area) {
/* ensure we don't have a button active anymore, can crash when
* switching screens with tooltip open because region and tooltip
* are no longer in the same screen */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
UI_blocklist_free(C, &region->uiblocks);
if (region->regiontimer) {
@@ -1299,7 +1291,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
glob_area->global->flag &= ~GLOBAL_AREA_IS_HIDDEN;
}
/* restore the old side panels/header visibility */
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region->flag = region->flagfullscreen;
}
}
@@ -1364,7 +1356,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN;
}
/* temporarily hide the side panels/header */
- for (region = newa->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &newa->regionbase) {
region->flagfullscreen = region->flag;
if (ELEM(region->regiontype,
@@ -1537,13 +1529,11 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
static ARegion *time_top_left_3dwindow(bScreen *screen)
{
ARegion *aret = NULL;
- ScrArea *area;
int min = 10000;
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
- ARegion *region;
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype == RGN_TYPE_WINDOW) {
if (region->winrct.xmin - region->winrct.ymin < min) {
aret = region;
@@ -1576,15 +1566,14 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
{
Scene *scene = DEG_get_input_scene(depsgraph);
- DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_TIME);
+ DEG_time_tag_update(bmain);
#ifdef DURIAN_CAMERA_SWITCH
void *camera = BKE_scene_camera_switch_find(scene);
if (camera && scene->camera != camera) {
- bScreen *screen;
scene->camera = camera;
/* are there cameras in the views that are not in the scene? */
- for (screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
BKE_screen_view3d_scene_sync(screen, scene);
}
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
@@ -1602,10 +1591,9 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
*/
bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene)
{
- ScrArea *area;
const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
switch (area->spacetype) {
case SPACE_VIEW3D: {
View3D *v3d;
@@ -1616,8 +1604,7 @@ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene)
v3d = area->spacedata.first;
if (v3d->camera && v3d->stereo3d_camera == STEREO_3D_ID) {
- ARegion *region;
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiondata && region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c
index 0b83a657265..4917dfa5e69 100644
--- a/source/blender/editors/screen/screen_geometry.c
+++ b/source/blender/editors/screen/screen_geometry.c
@@ -162,7 +162,6 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
const int screen_size_x = BLI_rcti_size_x(&screen_rect);
const int screen_size_y = BLI_rcti_size_y(&screen_rect);
- ScrVert *sv = NULL;
int screen_size_x_prev, screen_size_y_prev;
float min[2], max[2];
@@ -170,7 +169,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
min[0] = min[1] = 20000.0f;
max[0] = max[1] = 0.0f;
- for (sv = screen->vertbase.first; sv; sv = sv->next) {
+ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) {
const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y};
minmax_v2v2_v2(min, max, fv);
}
@@ -183,7 +182,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1);
/* make sure it fits! */
- for (sv = screen->vertbase.first; sv; sv = sv->next) {
+ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) {
sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx);
CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1);
@@ -208,7 +207,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
screen_geom_select_connected_edge(win, se);
/* all selected vertices get the right offset */
- for (sv = screen->vertbase.first; sv; sv = sv->next) {
+ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) {
/* if is a collapsed area */
if (sv != area->v1 && sv != area->v4) {
if (sv->flag) {
@@ -232,7 +231,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen)
screen_geom_select_connected_edge(win, se);
/* all selected vertices get the right offset */
- for (sv = screen->vertbase.first; sv; sv = sv->next) {
+ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) {
/* if is not a collapsed area */
if (sv != area->v2 && sv != area->v3) {
if (sv->flag) {
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index b002b23a7f3..b39b0ca7db6 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -692,10 +692,9 @@ static bool actionzone_area_poll(bContext *C)
if (screen && win && win->eventstate) {
const int *xy = &win->eventstate->x;
- AZone *az;
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- for (az = area->actionzones.first; az; az = az->next) {
+ LISTBASE_FOREACH (AZone *, az, &area->actionzones) {
if (BLI_rcti_isect_pt_v(&az->rect, xy)) {
return 1;
}
@@ -3068,13 +3067,12 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
static int marker_jump_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- TimeMarker *marker;
int closest = CFRA;
const bool next = RNA_boolean_get(op->ptr, "next");
bool found = false;
/* find matching marker in the right direction */
- for (marker = scene->markers.first; marker; marker = marker->next) {
+ LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
if (next) {
if ((marker->frame > CFRA) && (!found || closest > marker->frame)) {
closest = marker->frame;
@@ -3170,8 +3168,9 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op)
/* search current screen for 'fullscreen' areas */
/* prevents restoring info header, when mouse is over it */
- for (area = screen->areabase.first; area; area = area->next) {
- if (area->full) {
+ LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
+ if (area_iter->full) {
+ area = area_iter;
break;
}
}
@@ -3619,12 +3618,10 @@ static void SCREEN_OT_area_options(wmOperatorType *ot)
static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- bScreen *screen;
- ScrArea *area;
int tot = 0;
- for (screen = bmain->screens.first; screen; screen = screen->id.next) {
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacedata.first != area->spacedata.last) {
SpaceLink *sl = area->spacedata.first;
@@ -3854,7 +3851,6 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
region->alignment = 0;
if (area->spacetype == SPACE_VIEW3D) {
- ARegion *region_iter;
RegionView3D *rv3d = region->regiondata;
/* if this is a locked view, use settings from 'User' view */
@@ -3878,7 +3874,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
/* Accumulate locks, in case they're mixed. */
- for (region_iter = area->regionbase.first; region_iter; region_iter = region_iter->next) {
+ LISTBASE_FOREACH (ARegion *, region_iter, &area->regionbase) {
if (region_iter->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d_iter = region_iter->regiondata;
rv3d->viewlock_quad |= rv3d_iter->viewlock;
@@ -4441,8 +4437,6 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *window;
- ScrArea *area;
int sync;
double time;
@@ -4588,12 +4582,11 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
ED_update_for_newframe(bmain, depsgraph);
}
- for (window = wm->windows.first; window; window = window->next) {
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
const bScreen *win_screen = WM_window_get_active_screen(window);
- for (area = win_screen->areabase.first; area; area = area->next) {
- ARegion *region;
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ScrArea *, area, &win_screen->areabase) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
bool redraw = false;
if (region == sad->region) {
redraw = true;
@@ -4867,8 +4860,9 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op)
ScrArea *area = NULL;
/* search current screen for 'fullscreen' areas */
- for (area = screen->areabase.first; area; area = area->next) {
+ LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
if (area->full) {
+ area = area_iter;
break;
}
}
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index b20dc80d158..702c824077d 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -409,8 +409,7 @@ static void workspace_add_menu(bContext *UNUSED(C), uiLayout *layout, void *temp
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
if (startup_config) {
- for (WorkSpace *workspace = startup_config->workspaces.first; workspace;
- workspace = workspace->id.next) {
+ LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) {
uiLayout *row = uiLayoutRow(layout, false);
workspace_append_button(row, ot_append, workspace, startup_config->main);
has_startup_items = true;
@@ -420,8 +419,7 @@ static void workspace_add_menu(bContext *UNUSED(C), uiLayout *layout, void *temp
if (builtin_config) {
bool has_title = false;
- for (WorkSpace *workspace = builtin_config->workspaces.first; workspace;
- workspace = workspace->id.next) {
+ LISTBASE_FOREACH (WorkSpace *, workspace, &builtin_config->workspaces) {
if (startup_config &&
BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) {
continue;
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index 8a36cffa1f1..f4b076aca00 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -168,8 +168,7 @@ static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, v
static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen)
{
- for (bScreen *screen_iter = bmain->screens.first; screen_iter;
- screen_iter = screen_iter->id.next) {
+ LISTBASE_FOREACH (bScreen *, screen_iter, &bmain->screens) {
if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) {
ScrArea *area = screen_iter->areabase.first;
if (area && area->full == screen) {
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 0e38340d3bc..ee514fa745c 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -566,7 +566,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
if (load_tex(brush, vc, zoom, col, primary)) {
GPU_color_mask(true, true, true, true);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
GPU_matrix_push();
@@ -693,7 +693,7 @@ static bool paint_draw_cursor_overlay(
float center[2];
GPU_color_mask(true, true, true, true);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
if (ups->draw_anchored) {
copy_v2_v2(center, ups->anchored_initial_mouse);
@@ -776,7 +776,7 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
ePaintOverlayControlFlags flags = BKE_paint_get_overlay_flags();
eGPUBlend blend_state = GPU_blend_get();
- bool depth_test = GPU_depth_test_enabled();
+ eGPUDepthTest depth_test = GPU_depth_test_get();
/* Translate to region. */
GPU_matrix_push();
@@ -1147,9 +1147,9 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
/* Cursor normally draws on top, but for this part we need depth tests. */
- const bool depth_test = GPU_depth_test_enabled();
+ const eGPUDepthTest depth_test = GPU_depth_test_get();
if (!depth_test) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
GPU_line_width(1.0f);
@@ -1163,7 +1163,7 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
/* Restore depth test value. */
if (!depth_test) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 52cdebf3fd5..e709224f370 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -691,6 +691,14 @@ static float paint_space_stroke_spacing(bContext *C,
spacing = spacing * (1.5f - spacing_pressure);
}
+ if (SCULPT_is_cloth_deform_brush(brush)) {
+ /* The spacing in tools that use the cloth solver should not be affected by the brush radius to
+ * avoid affecting the simulation update rate when changing the radius of the brush.
+ With a value of 100 and the brush default of 10 for spacing, a simulation step runs every 2
+ pixels movement of the cursor. */
+ size_clamp = 100.0f;
+ }
+
/* stroke system is used for 2d paint too, so we need to account for
* the fact that brush can be scaled there. */
spacing *= stroke->zoom_2d;
@@ -1001,7 +1009,7 @@ bool paint_space_stroke_enabled(Brush *br, ePaintMode mode)
return false;
}
- if (br->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ if (br->sculpt_tool == SCULPT_TOOL_CLOTH || SCULPT_is_cloth_deform_brush(br)) {
/* The Cloth Brush is a special case for stroke spacing. Even if it has grab modes which do
* not support dynamic size, stroke spacing needs to be enabled so it is possible to control
* whether the simulation runs constantly or only when the brush moves when using the cloth
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 9a3fbe474b8..cf2ed0943eb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -1071,6 +1071,25 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
{0, NULL, 0, NULL, NULL},
};
+static EnumPropertyItem prop_cloth_filter_orientation_items[] = {
+ {SCULPT_FILTER_ORIENTATION_LOCAL,
+ "LOCAL",
+ 0,
+ "Local",
+ "Use the local axis to limit the force and set the gravity direction"},
+ {SCULPT_FILTER_ORIENTATION_WORLD,
+ "WORLD",
+ 0,
+ "World",
+ "Use the global axis to limit the force and set the gravity direction"},
+ {SCULPT_FILTER_ORIENTATION_VIEW,
+ "VIEW",
+ 0,
+ "View",
+ "Use the view axis to limit the force and set the gravity direction"},
+ {0, NULL, 0, NULL, NULL},
+};
+
typedef enum eClothFilterForceAxis {
CLOTH_FILTER_FORCE_X = 1 << 0,
CLOTH_FILTER_FORCE_Y = 1 << 1,
@@ -1120,7 +1139,15 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
switch (filter_type) {
case CLOTH_FILTER_GRAVITY:
- force[2] = -data->filter_strength * fade;
+ if (ss->filter_cache->orientation == SCULPT_FILTER_ORIENTATION_VIEW) {
+ /* When using the view orientation apply gravity in the -Y axis, this way objects will
+ * fall down instead of backwards. */
+ force[1] = -data->filter_strength * fade;
+ }
+ else {
+ force[2] = -data->filter_strength * fade;
+ }
+ SCULPT_filter_to_object_space(force, ss->filter_cache);
break;
case CLOTH_FILTER_INFLATE: {
float normal[3];
@@ -1138,11 +1165,13 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
break;
}
+ SCULPT_filter_to_orientation_space(force, ss->filter_cache);
for (int axis = 0; axis < 3; axis++) {
if (!ss->filter_cache->enabled_force_axis[axis]) {
force[axis] = 0.0f;
}
}
+ SCULPT_filter_to_object_space(force, ss->filter_cache);
add_v3_v3(force, sculpt_gravity);
@@ -1264,6 +1293,9 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y;
ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z;
+ SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation");
+ ss->filter_cache->orientation = orientation;
+
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1297,6 +1329,12 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
CLOTH_FILTER_FORCE_X | CLOTH_FILTER_FORCE_Y | CLOTH_FILTER_FORCE_Z,
"Force axis",
"Apply the force in the selected axis");
+ RNA_def_enum(ot->srna,
+ "orientation",
+ prop_cloth_filter_orientation_items,
+ SCULPT_FILTER_ORIENTATION_LOCAL,
+ "Orientation",
+ "Orientation of the axis to limit the filter force");
RNA_def_float(ot->srna,
"cloth_mass",
1.0f,
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index 56e70a8d47a..619a1b975b6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -181,7 +181,7 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache);
}
-typedef enum eSculptMeshFilterTypes {
+typedef enum eSculptMeshFilterType {
MESH_FILTER_SMOOTH = 0,
MESH_FILTER_SCALE = 1,
MESH_FILTER_INFLATE = 2,
@@ -193,7 +193,7 @@ typedef enum eSculptMeshFilterTypes {
MESH_FILTER_SHARPEN = 8,
MESH_FILTER_ENHANCE_DETAILS = 9,
MESH_FILTER_ERASE_DISPLACEMENT = 10,
-} eSculptMeshFilterTypes;
+} eSculptMeshFilterType;
static EnumPropertyItem prop_mesh_filter_types[] = {
{MESH_FILTER_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth mesh"},
@@ -258,7 +258,7 @@ static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets)
+static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type, bool use_face_sets)
{
return use_face_sets || ELEM(filter_type,
MESH_FILTER_SMOOTH,
@@ -277,7 +277,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
SculptSession *ss = data->ob->sculpt;
PBVHNode *node = data->nodes[i];
- const int filter_type = data->filter_type;
+ const eSculptMeshFilterType filter_type = data->filter_type;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i]);
@@ -486,49 +486,80 @@ static void mesh_filter_task_cb(void *__restrict userdata,
static void mesh_filter_enhance_details_init_directions(SculptSession *ss)
{
const int totvert = SCULPT_vertex_count_get(ss);
+ FilterCache *filter_cache = ss->filter_cache;
+
+ filter_cache->detail_directions = MEM_malloc_arrayN(
+ totvert, sizeof(float[3]), "detail directions");
for (int i = 0; i < totvert; i++) {
float avg[3];
SCULPT_neighbor_coords_average(ss, avg, i);
- sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
}
}
+static void mesh_filter_surface_smooth_init(SculptSession *ss,
+ const float shape_preservation,
+ const float current_vertex_displacement)
+{
+ const int totvert = SCULPT_vertex_count_get(ss);
+ FilterCache *filter_cache = ss->filter_cache;
+
+ filter_cache->surface_smooth_laplacian_disp = MEM_malloc_arrayN(
+ totvert, sizeof(float[3]), "surface smooth displacement");
+ filter_cache->surface_smooth_shape_preservation = shape_preservation;
+ filter_cache->surface_smooth_current_vertex = current_vertex_displacement;
+}
+
static void mesh_filter_init_limit_surface_co(SculptSession *ss)
{
const int totvert = SCULPT_vertex_count_get(ss);
- ss->filter_cache->limit_surface_co = MEM_malloc_arrayN(
- 3 * sizeof(float), totvert, "limit surface co");
+ FilterCache *filter_cache = ss->filter_cache;
+
+ filter_cache->limit_surface_co = MEM_malloc_arrayN(
+ sizeof(float[3]), totvert, "limit surface co");
for (int i = 0; i < totvert; i++) {
- SCULPT_vertex_limit_surface_get(ss, i, ss->filter_cache->limit_surface_co[i]);
+ SCULPT_vertex_limit_surface_get(ss, i, filter_cache->limit_surface_co[i]);
}
}
-static void mesh_filter_sharpen_init_factors(SculptSession *ss)
+static void mesh_filter_sharpen_init(SculptSession *ss,
+ const float smooth_ratio,
+ const float intensify_detail_strength,
+ const int curvature_smooth_iterations)
{
const int totvert = SCULPT_vertex_count_get(ss);
+ FilterCache *filter_cache = ss->filter_cache;
+
+ filter_cache->sharpen_smooth_ratio = smooth_ratio;
+ filter_cache->sharpen_intensify_detail_strength = intensify_detail_strength;
+ filter_cache->sharpen_curvature_smooth_iterations = curvature_smooth_iterations;
+ filter_cache->sharpen_factor = MEM_malloc_arrayN(sizeof(float), totvert, "sharpen factor");
+ filter_cache->detail_directions = MEM_malloc_arrayN(
+ totvert, sizeof(float[3]), "sharpen detail direction");
+
for (int i = 0; i < totvert; i++) {
float avg[3];
SCULPT_neighbor_coords_average(ss, avg, i);
- sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
- ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->detail_directions[i]);
+ sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ filter_cache->sharpen_factor[i] = len_v3(filter_cache->detail_directions[i]);
}
float max_factor = 0.0f;
for (int i = 0; i < totvert; i++) {
- if (ss->filter_cache->sharpen_factor[i] > max_factor) {
- max_factor = ss->filter_cache->sharpen_factor[i];
+ if (filter_cache->sharpen_factor[i] > max_factor) {
+ max_factor = filter_cache->sharpen_factor[i];
}
}
max_factor = 1.0f / max_factor;
for (int i = 0; i < totvert; i++) {
- ss->filter_cache->sharpen_factor[i] *= max_factor;
- ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]);
+ filter_cache->sharpen_factor[i] *= max_factor;
+ filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - filter_cache->sharpen_factor[i]);
}
/* Smooth the calculated factors and directions to remove high frecuency detail. */
for (int smooth_iterations = 0;
- smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations;
+ smooth_iterations < filter_cache->sharpen_curvature_smooth_iterations;
smooth_iterations++) {
for (int i = 0; i < totvert; i++) {
float direction_avg[3] = {0.0f, 0.0f, 0.0f};
@@ -537,15 +568,15 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
- add_v3_v3(direction_avg, ss->filter_cache->detail_directions[ni.index]);
- sharpen_avg += ss->filter_cache->sharpen_factor[ni.index];
+ add_v3_v3(direction_avg, filter_cache->detail_directions[ni.index]);
+ sharpen_avg += filter_cache->sharpen_factor[ni.index];
total++;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
- mul_v3_v3fl(ss->filter_cache->detail_directions[i], direction_avg, 1.0f / total);
- ss->filter_cache->sharpen_factor[i] = sharpen_avg / total;
+ mul_v3_v3fl(filter_cache->detail_directions[i], direction_avg, 1.0f / total);
+ filter_cache->sharpen_factor[i] = sharpen_avg / total;
}
}
}
@@ -590,7 +621,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- int filter_type = RNA_enum_get(op->ptr, "type");
+ eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type");
float filter_strength = RNA_float_get(op->ptr, "strength");
const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
@@ -654,17 +685,21 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
Object *ob = CTX_data_active_object(C);
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- int filter_type = RNA_enum_get(op->ptr, "type");
SculptSession *ss = ob->sculpt;
- PBVH *pbvh = ob->sculpt->pbvh;
- int deform_axis = RNA_enum_get(op->ptr, "deform_axis");
+ const eMeshFilterDeformAxis deform_axis = RNA_enum_get(op->ptr, "deform_axis");
+ const eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type");
+ const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
+ const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
+
if (deform_axis == 0) {
+ /* All axis are disabled, so the filter is not going to produce any deformation. */
return OPERATOR_CANCELLED;
}
- if (RNA_boolean_get(op->ptr, "use_face_sets")) {
- /* Update the active vertex */
+ if (use_face_sets) {
+ /* Update the active face set manually as the paint cursor is not enabled when using the Mesh
+ * Filter Tool. */
float mouse[2];
SculptCursorGeometryInfo sgi;
mouse[0] = event->mval[0];
@@ -672,67 +707,48 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
}
- const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
-
SCULPT_vertex_random_access_ensure(ss);
-
- const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false);
if (needs_topology_info) {
SCULPT_boundary_info_ensure(ob);
}
- const int totvert = SCULPT_vertex_count_get(ss);
- if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_topology_info && !ob->sculpt->pmap) {
- return OPERATOR_CANCELLED;
- }
-
- SCULPT_undo_push_begin("Mesh filter");
-
- if (ELEM(filter_type, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS)) {
- SCULPT_boundary_info_ensure(ob);
- }
+ SCULPT_undo_push_begin("Mesh Filter");
SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
- if (use_face_sets) {
- ss->filter_cache->active_face_set = SCULPT_active_face_set_get(ss);
- }
- else {
- ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
- }
-
- if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SURFACE_SMOOTH) {
- ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(sizeof(float[3]) * totvert,
- "surface smooth disp");
- ss->filter_cache->surface_smooth_shape_preservation = RNA_float_get(
- op->ptr, "surface_smooth_shape_preservation");
- ss->filter_cache->surface_smooth_current_vertex = RNA_float_get(
- op->ptr, "surface_smooth_current_vertex");
- }
-
- if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) {
- ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio");
- ss->filter_cache->sharpen_intensify_detail_strength = RNA_float_get(
- op->ptr, "sharpen_intensify_detail_strength");
- ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get(
- op->ptr, "sharpen_curvature_smooth_iterations");
-
- ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor");
- ss->filter_cache->detail_directions = MEM_malloc_arrayN(
- totvert, sizeof(float[3]), "sharpen detail direction");
-
- mesh_filter_sharpen_init_factors(ss);
- }
-
- if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ENHANCE_DETAILS) {
- ss->filter_cache->detail_directions = MEM_malloc_arrayN(
- totvert, sizeof(float[3]), "detail direction");
- mesh_filter_enhance_details_init_directions(ss);
- }
+ FilterCache *filter_cache = ss->filter_cache;
+ filter_cache->active_face_set = use_face_sets ? SCULPT_active_face_set_get(ss) :
+ SCULPT_FACE_SET_NONE;
- if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ERASE_DISPLACEMENT) {
- mesh_filter_init_limit_surface_co(ss);
+ switch (filter_type) {
+ case MESH_FILTER_SURFACE_SMOOTH: {
+ const float shape_preservation = RNA_float_get(op->ptr, "surface_smooth_shape_preservation");
+ const float current_vertex_displacement = RNA_float_get(op->ptr,
+ "surface_smooth_current_vertex");
+ mesh_filter_surface_smooth_init(ss, shape_preservation, current_vertex_displacement);
+ break;
+ }
+ case MESH_FILTER_SHARPEN: {
+ const float smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio");
+ const float intensify_detail_strength = RNA_float_get(op->ptr,
+ "sharpen_intensify_detail_strength");
+ const int curvature_smooth_iterations = RNA_int_get(op->ptr,
+ "sharpen_curvature_smooth_iterations");
+ mesh_filter_sharpen_init(
+ ss, smooth_ratio, intensify_detail_strength, curvature_smooth_iterations);
+ break;
+ }
+ case MESH_FILTER_ENHANCE_DETAILS: {
+ mesh_filter_enhance_details_init_directions(ss);
+ break;
+ }
+ case MESH_FILTER_ERASE_DISPLACEMENT: {
+ mesh_filter_init_limit_surface_co(ss);
+ break;
+ }
+ default:
+ break;
}
ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X;
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index bdada4d2565..b52b04eba3a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -326,6 +326,12 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(nodes);
}
+ /* Update the viewport navigation rotation origin. */
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ copy_v3_v3(ups->average_stroke_accum, ss->pivot_pos);
+ ups->average_stroke_counter = 1;
+ ups->last_stroke_valid = true;
+
ED_region_tag_redraw(region);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index dc34e56dc92..d7cf2e4d544 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -292,9 +292,7 @@ static void buttons_main_region_layout_properties(const bContext *C,
break;
}
- const bool vertical = true;
- ED_region_panels_layout_ex(
- C, region, &region->type->paneltypes, contexts, sbuts->mainb, vertical, NULL);
+ ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
}
static void buttons_main_region_layout(const bContext *C, ARegion *region)
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index d58f5ede7d7..058436a46bf 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -523,7 +523,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_R16F, false, rectf, zoomx, zoomy, NULL);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GPU_R16F, false, rectf, zoomx, zoomy, NULL);
MEM_freeN(rectf);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a64d5505ebe..1f7929cea7b 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -662,7 +662,7 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
srgb_to_linearrgb_v3_v3(col, col);
GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
image_user_refresh_scene(C, sima);
@@ -836,9 +836,7 @@ static void image_buttons_region_layout(const bContext *C, ARegion *region)
break;
}
- const bool vertical = true;
- ED_region_panels_layout_ex(
- C, region, &region->type->paneltypes, contexts_base, -1, vertical, NULL);
+ ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts_base, NULL);
}
static void image_buttons_region_draw(const bContext *C, ARegion *region)
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index bc9bd0e18f2..dc8f616c5e6 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -1847,11 +1847,7 @@ static int nlaedit_sync_actlen_exec(bContext *C, wmOperator *op)
continue;
}
- /* recalculate the length of the action */
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
-
- /* adjust the strip extents in response to this */
- BKE_nlastrip_recalculate_bounds(strip);
+ BKE_nlastrip_recalculate_bounds_sync_action(strip);
ale->update |= ANIM_UPDATE_DEPS;
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 814473b0e9a..917bb8e75fd 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -1738,7 +1738,7 @@ void drawnodespace(const bContext *C, ARegion *region)
UI_view2d_view_ortho(v2d);
UI_ThemeClearColor(TH_BACK);
GPU_clear(GPU_COLOR_BIT);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
/* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
UI_view2d_region_to_view(&region->v2d,
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 1705b9dd606..cf6a86ba6d7 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2743,6 +2743,23 @@ static void outliner_icon_background_colors(float icon_color[4], float icon_bord
icon_border[3] = 0.2f;
}
+/* Draw a rounded rectangle behind icons of active elements. */
+static void outliner_draw_active_indicator(const float minx,
+ const float miny,
+ const float maxx,
+ const float maxy,
+ const float icon_color[4],
+ const float icon_border[4])
+{
+ const float ufac = UI_UNIT_X / 20.0f;
+ const float radius = UI_UNIT_Y / 4.0f;
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true, minx, miny + ufac, maxx, maxy - ufac, radius, icon_color);
+ UI_draw_roundbox_aa(false, minx, miny + ufac, maxx, maxy - ufac, radius, icon_border);
+ GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
+}
+
static void outliner_draw_iconrow_doit(uiBlock *block,
TreeElement *te,
const uiFontStyle *fstyle,
@@ -2756,31 +2773,19 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
TreeStoreElem *tselem = TREESTORE(te);
if (active != OL_DRAWSEL_NONE) {
- float ufac = UI_UNIT_X / 20.0f;
float icon_color[4], icon_border[4];
outliner_icon_background_colors(icon_color, icon_border);
if (active == OL_DRAWSEL_ACTIVE) {
UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_color);
icon_border[3] = 0.3f;
}
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
-
- UI_draw_roundbox_aa(true,
- (float)*offsx,
- (float)ys + ufac,
- (float)*offsx + UI_UNIT_X,
- (float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 4.0f,
- icon_color);
- /* border around it */
- UI_draw_roundbox_aa(false,
- (float)*offsx,
- (float)ys + ufac,
- (float)*offsx + UI_UNIT_X,
- (float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 4.0f,
- icon_border);
- GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
+
+ outliner_draw_active_indicator((float)*offsx,
+ (float)ys,
+ (float)*offsx + UI_UNIT_X,
+ (float)ys + UI_UNIT_Y,
+ icon_color,
+ icon_border);
}
if (tselem->flag & TSE_HIGHLIGHTED) {
@@ -3052,23 +3057,12 @@ static void outliner_draw_tree_element(bContext *C,
/* active circle */
if (active != OL_DRAWSEL_NONE) {
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- (float)startx + offsx + UI_UNIT_X,
- (float)*starty + ufac,
- (float)startx + offsx + 2.0f * UI_UNIT_X,
- (float)*starty + UI_UNIT_Y - ufac,
- UI_UNIT_Y / 4.0f,
- icon_bgcolor);
- /* border around it */
- UI_draw_roundbox_aa(false,
- (float)startx + offsx + UI_UNIT_X,
- (float)*starty + ufac,
- (float)startx + offsx + 2.0f * UI_UNIT_X,
- (float)*starty + UI_UNIT_Y - ufac,
- UI_UNIT_Y / 4.0f,
- icon_border);
- GPU_blend(GPU_BLEND_ALPHA); /* roundbox disables it */
+ outliner_draw_active_indicator((float)startx + offsx + UI_UNIT_X,
+ (float)*starty,
+ (float)startx + offsx + 2.0f * UI_UNIT_X,
+ (float)*starty + UI_UNIT_Y,
+ icon_bgcolor,
+ icon_border);
te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index cd2fcd8e2cf..8567dd4da13 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -193,13 +193,7 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv
if (te->xs == data->x_location) {
outliner_item_openclose(te, data->open, false);
- /* Avoid rebuild if possible. */
- if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
- ED_region_tag_redraw(region);
- }
- else {
- ED_region_tag_redraw_no_rebuild(region);
- }
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
}
}
@@ -239,13 +233,7 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
(toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
outliner_item_openclose(te, open, toggle_all);
- /* Avoid rebuild if possible. */
- if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
- ED_region_tag_redraw(region);
- }
- else {
- ED_region_tag_redraw_no_rebuild(region);
- }
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
/* Only toggle once for single click toggling */
if (event->type == LEFTMOUSE) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 33dbbb274c0..9795bb73efe 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -237,7 +237,7 @@ void outliner_build_tree(struct Main *mainvar,
struct SpaceOutliner *space_outliner,
struct ARegion *region);
-bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem);
+bool outliner_mode_requires_always_rebuild(const struct SpaceOutliner *space_outliner);
typedef struct IDsSelectedData {
struct ListBase selected_array;
@@ -515,6 +515,8 @@ float outliner_restrict_columns_width(const struct SpaceOutliner *space_outliner
TreeElement *outliner_find_element_with_flag(const ListBase *lb, short flag);
bool outliner_is_element_visible(const TreeElement *te);
void outliner_scroll_view(struct ARegion *region, int delta_y);
+void outliner_tag_redraw_avoid_rebuild_on_open_change(const struct SpaceOutliner *space_outliner,
+ struct ARegion *region);
/* outliner_sync.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 1ac1b46f0d1..d720747e953 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1000,7 +1000,9 @@ static eOLDrawState tree_element_active_master_collection(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
LayerCollection *layer_collection = view_layer->layer_collections.first;
BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
+ * when only the active collection changes. */
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
}
return OL_DRAWSEL_NONE;
@@ -1022,7 +1024,9 @@ static eOLDrawState tree_element_active_layer_collection(bContext *C,
LayerCollection *layer_collection = te->directdata;
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
BKE_layer_collection_activate(view_layer, layer_collection);
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
+ * when only the active collection changes. */
+ WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
}
return OL_DRAWSEL_NONE;
@@ -1507,7 +1511,7 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- ED_region_tag_redraw(region);
+ ED_region_tag_redraw_no_rebuild(region);
ED_outliner_select_sync_from_outliner(C, space_outliner);
@@ -1729,7 +1733,7 @@ static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEven
outliner_walk_scroll(region, active_te);
ED_outliner_select_sync_from_outliner(C, space_outliner);
- ED_region_tag_redraw(region);
+ outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 4eed824207e..2a13f9d6a66 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -792,10 +792,11 @@ static void id_override_library_create_fn(bContext *C,
}
else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
BKE_lib_override_library_create_from_id(bmain, id_root, true);
- }
- BKE_main_id_clear_newpoins(bmain);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ /* Cleanup. */
+ BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ }
}
}
@@ -829,6 +830,37 @@ static void id_override_library_reset_fn(bContext *C,
static void id_override_library_resync_fn(bContext *C,
ReportList *UNUSED(reports),
+ Scene *scene,
+ TreeElement *te,
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *UNUSED(user_data))
+{
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+ ID *id_root = tselem->id;
+
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+ Main *bmain = CTX_data_main(C);
+
+ id_root->tag |= LIB_TAG_DOIT;
+
+ /* Tag all linked parents in tree hierarchy to be also overridden. */
+ while ((te = te->parent) != NULL) {
+ if (!TSE_IS_REAL_ID(te->store_elem)) {
+ continue;
+ }
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(te->store_elem->id)) {
+ break;
+ }
+ te->store_elem->id->tag |= LIB_TAG_DOIT;
+ }
+
+ BKE_lib_override_library_resync(bmain, scene, CTX_data_view_layer(C), id_root);
+ }
+}
+
+static void id_override_library_delete_fn(bContext *C,
+ ReportList *UNUSED(reports),
Scene *UNUSED(scene),
TreeElement *te,
TreeStoreElem *UNUSED(tsep),
@@ -853,10 +885,8 @@ static void id_override_library_resync_fn(bContext *C,
}
te->store_elem->id->tag |= LIB_TAG_DOIT;
}
- BKE_lib_override_library_resync(bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root);
- BKE_main_id_clear_newpoins(bmain);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ BKE_lib_override_library_delete(bmain, id_root);
}
}
@@ -1600,6 +1630,7 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
ED_outliner_select_sync_from_object_tag(C);
return OPERATOR_FINISHED;
@@ -1641,6 +1672,7 @@ typedef enum eOutlinerIdOpTypes {
OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET,
OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY,
OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY,
+ OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY,
OUTLINER_IDOP_SINGLE,
OUTLINER_IDOP_DELETE,
OUTLINER_IDOP_REMAP,
@@ -1693,6 +1725,12 @@ static const EnumPropertyItem prop_id_op_types[] = {
"Resync Library Override Hierarchy",
"Rebuild this local override from its linked reference, as well as its hierarchy of "
"dependencies"},
+ {OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY,
+ "OVERRIDE_LIBRARY_DELETE_HIERARCHY",
+ 0,
+ "Delete Library Override Hierarchy",
+ "Delete this local override (including its hierarchy of override dependencies) and relink "
+ "its usages to the linked data-blocks"},
{0, "", 0, NULL, NULL},
{OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""},
{OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""},
@@ -1725,6 +1763,8 @@ static bool outliner_id_operation_item_poll(bContext *C,
return true;
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY:
return true;
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY:
+ return true;
case OUTLINER_IDOP_SINGLE:
if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
return true;
@@ -1860,7 +1900,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
}
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: {
- /* make local */
outliner_do_libdata_operation(C,
op->reports,
scene,
@@ -1872,7 +1911,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
}
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: {
- /* make local */
outliner_do_libdata_operation(C,
op->reports,
scene,
@@ -1884,7 +1922,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
}
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: {
- /* make local */
outliner_do_libdata_operation(C,
op->reports,
scene,
@@ -1896,7 +1933,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
}
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: {
- /* make local */
outliner_do_libdata_operation(C,
op->reports,
scene,
@@ -1908,7 +1944,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
}
case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY: {
- /* make local */
outliner_do_libdata_operation(C,
op->reports,
scene,
@@ -1919,6 +1954,17 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
ED_undo_push(C, "Resync Overridden Data Hierarchy");
break;
}
+ case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: {
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ space_outliner,
+ &space_outliner->tree,
+ id_override_library_delete_fn,
+ &(OutlinerLibOverrideData){.do_hierarchy = true});
+ ED_undo_push(C, "Delete Overridden Data Hierarchy");
+ break;
+ }
case OUTLINER_IDOP_SINGLE: {
/* make single user */
switch (idlevel) {
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 60058c82283..9e3cbabf283 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -244,14 +244,12 @@ static TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
/* -------------------------------------------------------- */
/**
- * Check if an element type needs a full rebuild if the open/collapsed state changes.
- * These element types don't add children if collapsed.
- *
- * This current check isn't great really. A per element-type flag would be preferable.
+ * Check if a display mode needs a full rebuild if the open/collapsed state changes.
+ * Element types in these modes don't actually add children if collapsed, so the rebuild is needed.
*/
-bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem)
+bool outliner_mode_requires_always_rebuild(const SpaceOutliner *space_outliner)
{
- return ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_KEYMAP);
+ return ELEM(space_outliner->outlinevis, SO_DATA_API);
}
/* special handling of hierarchical non-lib data */
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 1da44b5e51e..25dc7bc271e 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -37,6 +37,7 @@
#include "ED_armature.h"
#include "ED_outliner.h"
+#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -455,6 +456,23 @@ void outliner_scroll_view(ARegion *region, int delta_y)
}
}
+/**
+ * The outliner should generally use #ED_region_tag_redraw_no_rebuild() to avoid unnecessary tree
+ * rebuilds. If elements are open or closed, we may still have to rebuild.
+ * Upon changing the open/closed state, call this to avoid rebuilds if possible.
+ */
+void outliner_tag_redraw_avoid_rebuild_on_open_change(const SpaceOutliner *space_outliner,
+ ARegion *region)
+{
+ /* Avoid rebuild if possible. */
+ if (outliner_mode_requires_always_rebuild(space_outliner)) {
+ ED_region_tag_redraw(region);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(region);
+ }
+}
+
/* Get base of object under cursor. Used for eyedropper tool */
Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2])
{
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index b14afed81dd..6854367d975 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -114,6 +114,8 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
switch (wmn->data) {
case ND_OB_ACTIVE:
case ND_OB_SELECT:
+ ED_region_tag_redraw_no_rebuild(region);
+ break;
case ND_OB_VISIBLE:
case ND_OB_RENDER:
case ND_MODE:
@@ -121,15 +123,23 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
case ND_FRAME:
case ND_RENDER_OPTIONS:
case ND_SEQUENCER:
- case ND_LAYER:
case ND_LAYER_CONTENT:
case ND_WORLD:
case ND_SCENEBROWSE:
ED_region_tag_redraw(region);
break;
+ case ND_LAYER:
+ /* Avoid rebuild if only the active collection changes */
+ if ((wmn->subtype == NS_LAYER_COLLECTION) && (wmn->action == NA_ACTIVATED)) {
+ ED_region_tag_redraw_no_rebuild(region);
+ break;
+ }
+
+ ED_region_tag_redraw(region);
+ break;
}
- if (wmn->action & NA_EDITED) {
- ED_region_tag_redraw(region);
+ if (wmn->action == NA_EDITED) {
+ ED_region_tag_redraw_no_rebuild(region);
}
break;
case NC_OBJECT:
@@ -181,7 +191,7 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
case NC_MATERIAL:
switch (wmn->data) {
case ND_SHADING_LINKS:
- ED_region_tag_redraw(region);
+ ED_region_tag_redraw_no_rebuild(region);
break;
}
break;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 8a6b97b3834..eb066f6afea 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1772,7 +1772,7 @@ void sequencer_draw_preview(const bContext *C,
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
sequencer_preview_clear();
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 0242bb4fe24..3efdee9cec9 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -141,8 +141,7 @@ static void userpref_main_region_layout(const bContext *C, ARegion *region)
BLI_str_tolower_ascii(id_lower, strlen(id_lower));
}
- ED_region_panels_layout_ex(
- C, region, &region->type->paneltypes, contexts, U.space_data.section_active, true, NULL);
+ ED_region_panels_layout_ex(C, region, &region->type->paneltypes, contexts, NULL);
}
static void userpref_operatortypes(void)
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index e5ba27cef07..de0b420a3b5 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1323,9 +1323,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C,
paneltypes = &art->paneltypes;
}
- const bool vertical = true;
- ED_region_panels_layout_ex(
- C, region, paneltypes, contexts_base, -1, vertical, category_override);
+ ED_region_panels_layout_ex(C, region, paneltypes, contexts_base, category_override);
}
static void view3d_buttons_region_layout(const bContext *C, ARegion *region)
@@ -1453,7 +1451,7 @@ static void view3d_tools_region_init(wmWindowManager *wm, ARegion *region)
static void view3d_tools_region_draw(const bContext *C, ARegion *region)
{
- ED_region_panels_ex(C, region, (const char *[]){CTX_data_mode_string(C), NULL}, -1, true);
+ ED_region_panels_ex(C, region, (const char *[]){CTX_data_mode_string(C), NULL});
}
/* area (not region) level listener */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 33b365b45aa..4cc48dfd175 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1618,7 +1618,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *region)
GPU_pass_cache_garbage_collect();
/* No depth test for drawing action zones afterwards. */
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
v3d->flag |= V3D_INVALID_BACKBUF;
}
@@ -2321,12 +2321,12 @@ void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *r
GPU_clear(GPU_DEPTH_BIT);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
GPUViewport *viewport = WM_draw_region_get_viewport(region);
DRW_draw_depth_loop_gpencil(depsgraph, region, v3d, viewport);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
/* *********************** customdata **************** */
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 6c61c83731d..6c2f4df7004 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -586,23 +586,23 @@ static void draw_primitive_view(const struct bContext *C, ARegion *UNUSED(region
UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, color);
const bool use_depth = !XRAY_ENABLED(ipd->v3d);
- const bool depth_test_enabled = GPU_depth_test_enabled();
+ const eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
if (use_depth) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
color[3] = 0.15f;
draw_primitive_view_impl(C, ipd, color);
}
if (use_depth) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
color[3] = 1.0f;
draw_primitive_view_impl(C, ipd, color);
if (use_depth) {
if (depth_test_enabled == false) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b986ebb75b6..d015b5dcc89 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1100,7 +1100,7 @@ int view3d_opengl_select(ViewContext *vc,
wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, &rect);
if (!XRAY_ACTIVE(v3d)) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
/* If in xray mode, we select the wires in priority. */
@@ -1165,7 +1165,7 @@ int view3d_opengl_select(ViewContext *vc,
wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, NULL);
if (!XRAY_ACTIVE(v3d)) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
DRW_opengl_context_disable();
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 0aa6b4f6131..4e5eaf4bf51 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -785,7 +785,6 @@ void drawConstraint(TransInfo *t)
else {
if (tc->mode & CON_SELECT) {
float vec[3];
- int depth_test_enabled;
convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1]));
add_v3_v3(vec, t->center_global);
@@ -794,9 +793,9 @@ void drawConstraint(TransInfo *t)
drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0);
drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0);
- depth_test_enabled = GPU_depth_test_enabled();
+ eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
if (depth_test_enabled) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
const uint shdr_pos = GPU_vertformat_attr_add(
@@ -821,7 +820,7 @@ void drawConstraint(TransInfo *t)
immUnbindProgram();
if (depth_test_enabled) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
}
@@ -843,7 +842,6 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
if (t->flag & T_PROP_EDIT) {
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float tmat[4][4], imat[4][4];
- int depth_test_enabled;
if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) {
copy_m4_m4(tmat, rv3d->viewmat);
@@ -873,9 +871,9 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask));
}
- depth_test_enabled = GPU_depth_test_enabled();
+ eGPUDepthTest depth_test_enabled = GPU_depth_test_get();
if (depth_test_enabled) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -899,7 +897,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
immUnbindProgram();
if (depth_test_enabled) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
GPU_matrix_pop();
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index dffee72205b..14ef5e87534 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -1343,7 +1343,7 @@ void drawDial3d(const TransInfo *t)
BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END);
gizmo_get_axis_color(axis_idx, NULL, color, color);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
@@ -1359,7 +1359,7 @@ void drawDial3d(const TransInfo *t)
});
GPU_line_smooth(false);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 45debe964f4..fe97a9fba87 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -1147,7 +1147,7 @@ void drawEdgeSlide(TransInfo *t)
const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_ALPHA);
@@ -1266,7 +1266,7 @@ void drawEdgeSlide(TransInfo *t)
GPU_blend(GPU_BLEND_NONE);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
static void edge_slide_snap_apply(TransInfo *t, float *value)
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 11d0b375e6f..4367dd5ee92 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -390,7 +390,7 @@ void drawVertSlide(TransInfo *t)
const int alpha_shade = -160;
int i;
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_ALPHA);
@@ -485,7 +485,7 @@ void drawVertSlide(TransInfo *t)
GPU_matrix_pop();
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
}
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 09b5df82c2b..5db41570e00 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -184,7 +184,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
const float *loc_prev = NULL;
const float *normal = NULL;
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
if (!BLI_listbase_is_empty(&t->tsnap.points)) {
@@ -228,7 +228,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
ED_gizmotypes_snap_3d_draw_util(
rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem);
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
}
else if (t->spacetype == SPACE_IMAGE) {
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index faeefcb989e..d80e7f3c754 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -451,13 +451,13 @@ static void draw_uvs(SpaceImage *sima,
GPU_batch_program_set_builtin(batch->edges, shader);
/* Inner Line. Use depth test to insure selection is drawn on top. */
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
GPU_line_width(1.0f);
GPU_batch_uniform_4fv(batch->edges, "edgeColor", col1);
GPU_batch_uniform_4fv(batch->edges, "selectColor", col2);
GPU_batch_uniform_1f(batch->edges, "dashWidth", dash_width);
GPU_batch_draw(batch->edges);
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
GPU_provoking_vertex(GPU_VERTEX_LAST);
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 45b379c5e0a..50a5a0243f8 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -93,6 +93,7 @@ set(SRC
opengl/gl_context.cc
opengl/gl_drawlist.cc
opengl/gl_shader.cc
+ opengl/gl_shader_interface.cc
opengl/gl_state.cc
opengl/gl_vertex_array.cc
@@ -119,7 +120,6 @@ set(SRC
GPU_primitive.h
GPU_select.h
GPU_shader.h
- GPU_shader_interface.h
GPU_state.h
GPU_texture.h
GPU_uniformbuffer.h
@@ -140,6 +140,7 @@ set(SRC
intern/gpu_private.h
intern/gpu_select_private.h
intern/gpu_shader_private.hh
+ intern/gpu_shader_interface.hh
intern/gpu_state_private.hh
intern/gpu_vertex_format_private.h
@@ -148,6 +149,7 @@ set(SRC
opengl/gl_context.hh
opengl/gl_drawlist.hh
opengl/gl_shader.hh
+ opengl/gl_shader_interface.hh
opengl/gl_state.hh
opengl/gl_vertex_array.hh
)
diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h
index e3d47cfe084..be7e604fb96 100644
--- a/source/blender/gpu/GPU_context.h
+++ b/source/blender/gpu/GPU_context.h
@@ -27,7 +27,6 @@
#include "GPU_batch.h"
#include "GPU_common.h"
-#include "GPU_shader_interface.h"
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index 41d4f5d28d3..6057770d2d9 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -29,7 +29,6 @@
#include "GPU_immediate_util.h"
#include "GPU_primitive.h"
#include "GPU_shader.h"
-#include "GPU_shader_interface.h"
#include "GPU_texture.h"
#include "GPU_vertex_format.h"
@@ -103,13 +102,11 @@ void immVertex2iv(uint attr_id, const int data[2]);
/* Provide uniform values that don't change for the entire draw call. */
void immUniform1i(const char *name, int x);
-void immUniform4iv(const char *name, const int data[4]);
void immUniform1f(const char *name, float x);
void immUniform2f(const char *name, float x, float y);
void immUniform2fv(const char *name, const float data[2]);
void immUniform3f(const char *name, float x, float y, float z);
void immUniform3fv(const char *name, const float data[3]);
-void immUniformArray3fv(const char *name, const float *data, int count);
void immUniform4f(const char *name, float x, float y, float z, float w);
void immUniform4fv(const char *name, const float data[4]);
void immUniformArray4fv(const char *bare_name, const float *data, int count);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 99fcae19984..b38cc1f3244 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -27,7 +27,6 @@
extern "C" {
#endif
-struct GPUShaderInterface;
struct GPUTexture;
struct GPUUniformBuffer;
struct GPUVertBuf;
@@ -35,8 +34,6 @@ struct GPUVertBuf;
/* TODO(fclem) These members should be private and the
* whole struct should just be an opaque pointer. */
typedef struct GPUShader {
- /** Uniform & attribute locations for shader. */
- struct GPUShaderInterface *interface;
/** For debugging purpose. */
char name[64];
} GPUShader;
@@ -90,6 +87,41 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader);
int GPU_shader_get_program(GPUShader *shader);
+typedef enum {
+ GPU_UNIFORM_MODEL = 0, /* mat4 ModelMatrix */
+ GPU_UNIFORM_VIEW, /* mat4 ViewMatrix */
+ GPU_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */
+ GPU_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */
+ GPU_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */
+ GPU_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */
+
+ GPU_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */
+ GPU_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */
+ GPU_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */
+ GPU_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */
+ GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */
+
+ GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */
+ GPU_UNIFORM_ORCO, /* vec4 OrcoTexCoFactors[] */
+ GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */
+
+ GPU_UNIFORM_COLOR, /* vec4 color */
+ GPU_UNIFORM_BASE_INSTANCE, /* int baseInstance */
+ GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */
+ GPU_UNIFORM_RESOURCE_ID, /* int resourceId */
+ GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */
+
+ GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */
+} GPUUniformBuiltin;
+
+typedef enum {
+ GPU_UNIFORM_BLOCK_VIEW = 0, /* viewBlock */
+ GPU_UNIFORM_BLOCK_MODEL, /* modelBlock */
+ GPU_UNIFORM_BLOCK_INFO, /* infoBlock */
+
+ GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */
+} GPUUniformBlockBuiltin;
+
void GPU_shader_set_srgb_uniform(GPUShader *shader);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
@@ -123,8 +155,6 @@ void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, cons
int GPU_shader_get_attribute(GPUShader *shader, const char *name);
-char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len);
-
void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear);
/* Builtin/Non-generated shaders */
diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h
deleted file mode 100644
index 47e4e432d66..00000000000
--- a/source/blender/gpu/GPU_shader_interface.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 by Mike Erwin.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- *
- * GPU shader interface (C --> GLSL)
- */
-
-#pragma once
-
-#include "GPU_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- GPU_UNIFORM_MODEL = 0, /* mat4 ModelMatrix */
- GPU_UNIFORM_VIEW, /* mat4 ViewMatrix */
- GPU_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */
- GPU_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */
- GPU_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */
- GPU_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */
-
- GPU_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */
- GPU_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */
- GPU_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */
- GPU_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */
- GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */
-
- GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */
- GPU_UNIFORM_ORCO, /* vec4 OrcoTexCoFactors[] */
- GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */
-
- GPU_UNIFORM_COLOR, /* vec4 color */
- GPU_UNIFORM_BASE_INSTANCE, /* int baseInstance */
- GPU_UNIFORM_RESOURCE_CHUNK, /* int resourceChunk */
- GPU_UNIFORM_RESOURCE_ID, /* int resourceId */
- GPU_UNIFORM_SRGB_TRANSFORM, /* bool srgbTarget */
-
- GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */
-} GPUUniformBuiltin;
-
-typedef enum {
- GPU_UNIFORM_BLOCK_VIEW = 0, /* viewBlock */
- GPU_UNIFORM_BLOCK_MODEL, /* modelBlock */
- GPU_UNIFORM_BLOCK_INFO, /* infoBlock */
-
- GPU_NUM_UNIFORM_BLOCKS, /* Special value, denotes number of builtin uniforms block. */
-} GPUUniformBlockBuiltin;
-
-typedef struct GPUShaderInput {
- uint32_t name_offset;
- uint32_t name_hash;
- int32_t location;
- /** Defined at interface creation or in shader. Only for Samplers, UBOs and Vertex Attribs. */
- int32_t binding;
-} GPUShaderInput;
-
-#define GPU_SHADERINTERFACE_REF_ALLOC_COUNT 16
-
-typedef struct GPUShaderInterface {
- /** Buffer containing all inputs names separated by '\0'. */
- char *name_buffer;
- /** Reference to GPUBatches using this interface */
- void **batches;
- uint batches_len;
- /** Input counts. */
- uint attribute_len;
- uint ubo_len;
- uint uniform_len;
- /** Enabled bindpoints that needs to be fed with data. */
- uint16_t enabled_attr_mask;
- uint16_t enabled_ubo_mask;
- uint64_t enabled_tex_mask;
- /** Opengl Location of builtin uniforms. Fast access, no lookup needed. */
- int32_t builtins[GPU_NUM_UNIFORMS];
- int32_t builtin_blocks[GPU_NUM_UNIFORM_BLOCKS];
- /** Flat array. In this order: Attributes, Ubos, Uniforms. */
- GPUShaderInput inputs[0];
-} GPUShaderInterface;
-
-GPUShaderInterface *GPU_shaderinterface_create(int32_t program_id);
-void GPU_shaderinterface_discard(GPUShaderInterface *);
-
-const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *, const char *name);
-int32_t GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
- GPUUniformBuiltin builtin);
-int32_t GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
- GPUUniformBlockBuiltin builtin);
-const GPUShaderInput *GPU_shaderinterface_ubo(const GPUShaderInterface *, const char *name);
-const GPUShaderInput *GPU_shaderinterface_attr(const GPUShaderInterface *, const char *name);
-
-/* keep track of batches using this interface */
-void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *interface, void *cache);
-void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface *interface, void *cache);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index be3250f6654..6a59baa38f0 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -66,9 +66,9 @@ typedef enum eGPUBlend {
typedef enum eGPUDepthTest {
GPU_DEPTH_NONE = 0,
- GPU_DEPTH_ALWAYS,
+ GPU_DEPTH_ALWAYS, /* Used to draw to the depth buffer without really testing. */
GPU_DEPTH_LESS,
- GPU_DEPTH_LESS_EQUAL,
+ GPU_DEPTH_LESS_EQUAL, /* Default. */
GPU_DEPTH_EQUAL,
GPU_DEPTH_GREATER,
GPU_DEPTH_GREATER_EQUAL,
@@ -106,11 +106,10 @@ extern "C" {
void GPU_blend(eGPUBlend blend);
void GPU_face_culling(eGPUFaceCullTest culling);
-void GPU_front_facing(bool invert);
+void GPU_depth_test(eGPUDepthTest test);
void GPU_provoking_vertex(eGPUProvokingVertex vert);
+void GPU_front_facing(bool invert);
void GPU_depth_range(float near, float far);
-void GPU_depth_test(bool enable);
-bool GPU_depth_test_enabled(void);
void GPU_scissor_test(bool enable);
void GPU_line_smooth(bool enable);
void GPU_line_width(float width);
@@ -144,6 +143,7 @@ void GPU_stencil_write_mask_set(uint write_mask);
void GPU_stencil_compare_mask_set(uint compare_mask);
eGPUBlend GPU_blend_get(void);
+eGPUDepthTest GPU_depth_test_get(void);
eGPUWriteMask GPU_write_mask_get(void);
void GPU_flush(void);
diff --git a/source/blender/gpu/intern/gpu_attr_binding.cc b/source/blender/gpu/intern/gpu_attr_binding.cc
index 6cb60884620..2a48107e190 100644
--- a/source/blender/gpu/intern/gpu_attr_binding.cc
+++ b/source/blender/gpu/intern/gpu_attr_binding.cc
@@ -61,9 +61,7 @@ static void write_attr_location(GPUAttrBinding *binding, uint a_idx, uint locati
binding->enabled_bits |= 1 << a_idx;
}
-void get_attr_locations(const GPUVertFormat *format,
- GPUAttrBinding *binding,
- const GPUShaderInterface *shaderface)
+void get_attr_locations(const GPUVertFormat *format, GPUAttrBinding *binding, GPUShader *shader)
{
AttrBinding_clear(binding);
@@ -71,13 +69,12 @@ void get_attr_locations(const GPUVertFormat *format,
const GPUVertAttr *a = &format->attrs[a_idx];
for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
- const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, name);
-#if TRUST_NO_ONE
- assert(input != NULL);
+ int loc = GPU_shader_get_attribute(shader, name);
/* TODO: make this a recoverable runtime error?
* indicates mismatch between vertex format and program. */
-#endif
- write_attr_location(binding, a_idx, input->location);
+ BLI_assert(loc != -1);
+
+ write_attr_location(binding, a_idx, loc);
}
}
}
diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h
index 4d359343c38..cd67a51a822 100644
--- a/source/blender/gpu/intern/gpu_attr_binding_private.h
+++ b/source/blender/gpu/intern/gpu_attr_binding_private.h
@@ -25,8 +25,8 @@
#pragma once
-#include "GPU_shader_interface.h"
#include "GPU_vertex_format.h"
+#include "gpu_shader_interface.hh"
#ifdef __cplusplus
extern "C" {
@@ -35,9 +35,7 @@ extern "C" {
/* TODO(fclem) remove, use shaderface directly. */
void AttrBinding_clear(GPUAttrBinding *binding);
-void get_attr_locations(const GPUVertFormat *format,
- GPUAttrBinding *binding,
- const GPUShaderInterface *shaderface);
+void get_attr_locations(const GPUVertFormat *format, GPUAttrBinding *binding, GPUShader *shader);
uint read_attr_location(const GPUAttrBinding *binding, uint a_idx);
#ifdef __cplusplus
diff --git a/source/blender/gpu/intern/gpu_batch_private.hh b/source/blender/gpu/intern/gpu_batch_private.hh
index 3a8044efc1d..11efd784238 100644
--- a/source/blender/gpu/intern/gpu_batch_private.hh
+++ b/source/blender/gpu/intern/gpu_batch_private.hh
@@ -28,7 +28,6 @@
#include "GPU_batch.h"
#include "GPU_context.h"
-#include "GPU_shader_interface.h"
namespace blender {
namespace gpu {
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index dd05689d69a..431dbe848f7 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -73,7 +73,6 @@ typedef struct {
GLuint vao_id;
GPUShader *bound_program;
- const GPUShaderInterface *shader_interface;
GPUAttrBinding attr_binding;
uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
} Immediate;
@@ -148,14 +147,13 @@ void immBindShader(GPUShader *shader)
BLI_assert(imm.bound_program == NULL);
imm.bound_program = shader;
- imm.shader_interface = shader->interface;
if (!imm.vertex_format.packed) {
VertexFormat_pack(&imm.vertex_format);
}
GPU_shader_bind(shader);
- get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface);
+ get_attr_locations(&imm.vertex_format, &imm.attr_binding, shader);
GPU_matrix_bind(shader);
GPU_shader_set_srgb_uniform(shader);
}
@@ -749,123 +747,77 @@ void immVertex2iv(uint attr_id, const int data[2])
/* --- generic uniform functions --- */
-#if 0
-# if TRUST_NO_ONE
-# define GET_UNIFORM \
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); \
- assert(uniform);
-# else
-# define GET_UNIFORM \
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(imm.shader_interface, name);
-# endif
-#else
-/* NOTE: It is possible to have uniform fully optimized out from the shader.
- * In this case we can't assert failure or allow NULL-pointer dereference.
- * TODO(sergey): How can we detect existing-but-optimized-out uniform but still
- * catch typos in uniform names passed to immUniform*() functions? */
-# define GET_UNIFORM \
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); \
- if (uniform == NULL) \
- return;
-#endif
-
void immUniform1f(const char *name, float x)
{
- GET_UNIFORM
- glUniform1f(uniform->location, x);
+ GPU_shader_uniform_1f(imm.bound_program, name, x);
}
void immUniform2f(const char *name, float x, float y)
{
- GET_UNIFORM
- glUniform2f(uniform->location, x, y);
+ GPU_shader_uniform_2f(imm.bound_program, name, x, y);
}
void immUniform2fv(const char *name, const float data[2])
{
- GET_UNIFORM
- glUniform2fv(uniform->location, 1, data);
+ GPU_shader_uniform_2fv(imm.bound_program, name, data);
}
void immUniform3f(const char *name, float x, float y, float z)
{
- GET_UNIFORM
- glUniform3f(uniform->location, x, y, z);
+ GPU_shader_uniform_3f(imm.bound_program, name, x, y, z);
}
void immUniform3fv(const char *name, const float data[3])
{
- GET_UNIFORM
- glUniform3fv(uniform->location, 1, data);
-}
-
-/* can increase this limit or move to another file */
-#define MAX_UNIFORM_NAME_LEN 60
-
-/* Note array index is not supported for name (i.e: "array[0]"). */
-void immUniformArray3fv(const char *name, const float *data, int count)
-{
- GET_UNIFORM
- glUniform3fv(uniform->location, count, data);
+ GPU_shader_uniform_3fv(imm.bound_program, name, data);
}
void immUniform4f(const char *name, float x, float y, float z, float w)
{
- GET_UNIFORM
- glUniform4f(uniform->location, x, y, z, w);
+ GPU_shader_uniform_4f(imm.bound_program, name, x, y, z, w);
}
void immUniform4fv(const char *name, const float data[4])
{
- GET_UNIFORM
- glUniform4fv(uniform->location, 1, data);
+ GPU_shader_uniform_4fv(imm.bound_program, name, data);
}
/* Note array index is not supported for name (i.e: "array[0]"). */
void immUniformArray4fv(const char *name, const float *data, int count)
{
- GET_UNIFORM
- glUniform4fv(uniform->location, count, data);
+ GPU_shader_uniform_4fv_array(imm.bound_program, name, count, (float(*)[4])data);
}
void immUniformMatrix4fv(const char *name, const float data[4][4])
{
- GET_UNIFORM
- glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data);
+ GPU_shader_uniform_mat4(imm.bound_program, name, data);
}
void immUniform1i(const char *name, int x)
{
- GET_UNIFORM
- glUniform1i(uniform->location, x);
-}
-
-void immUniform4iv(const char *name, const int data[4])
-{
- GET_UNIFORM
- glUniform4iv(uniform->location, 1, data);
+ GPU_shader_uniform_1i(imm.bound_program, name, x);
}
void immBindTexture(const char *name, GPUTexture *tex)
{
- GET_UNIFORM
- GPU_texture_bind(tex, uniform->binding);
+ int binding = GPU_shader_get_texture_binding(imm.bound_program, name);
+ GPU_texture_bind(tex, binding);
}
void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state)
{
- GET_UNIFORM
- GPU_texture_bind_ex(tex, state, uniform->binding, true);
+ int binding = GPU_shader_get_texture_binding(imm.bound_program, name);
+ GPU_texture_bind_ex(tex, state, binding, true);
}
/* --- convenience functions for setting "uniform vec4 color" --- */
void immUniformColor4f(float r, float g, float b, float a)
{
- int32_t uniform_loc = GPU_shaderinterface_uniform_builtin(imm.shader_interface,
- GPU_UNIFORM_COLOR);
+ int32_t uniform_loc = GPU_shader_get_builtin_uniform(imm.bound_program, GPU_UNIFORM_COLOR);
BLI_assert(uniform_loc != -1);
- glUniform4f(uniform_loc, r, g, b, a);
+ float data[4] = {r, g, b, a};
+ GPU_shader_uniform_vector(imm.bound_program, uniform_loc, 4, 1, data);
}
void immUniformColor4fv(const float rgba[4])
diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc
index 951652b9393..cdb6d303588 100644
--- a/source/blender/gpu/intern/gpu_matrix.cc
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -21,8 +21,6 @@
* \ingroup gpu
*/
-#include "GPU_shader_interface.h"
-
#include "gpu_context_private.hh"
#include "gpu_matrix_private.h"
@@ -649,14 +647,13 @@ void GPU_matrix_bind(GPUShader *shader)
* call this before a draw call if desired matrices are dirty
* call glUseProgram before this, as glUniform expects program to be bound
*/
- const GPUShaderInterface *shaderface = shader->interface;
- int32_t MV = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW);
- int32_t P = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION);
- int32_t MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP);
-
- int32_t N = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_NORMAL);
- int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV);
- int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV);
+ int32_t MV = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW);
+ int32_t P = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_PROJECTION);
+ int32_t MVP = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP);
+
+ int32_t N = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL);
+ int32_t MV_inv = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV);
+ int32_t P_inv = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_PROJECTION_INV);
if (MV != -1) {
GPU_shader_uniform_vector(shader, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL));
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 29e2615345c..f7fd1faeb1e 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
@@ -287,7 +288,7 @@ typedef struct GPUPickState {
int viewport[4];
int scissor[4];
eGPUWriteMask write_mask;
- bool depth_test;
+ eGPUDepthTest depth_test;
} GPUPickState;
static GPUPickState g_pick_state = {0};
@@ -311,18 +312,17 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
/* Restrict OpenGL operations for when we don't have cache */
if (ps->is_cached == false) {
ps->write_mask = GPU_write_mask_get();
- ps->depth_test = GPU_depth_test_enabled();
+ ps->depth_test = GPU_depth_test_get();
GPU_scissor_get(ps->scissor);
/* disable writing to the framebuffer */
GPU_color_mask(false, false, false, false);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
+ GPU_depth_mask(true);
/* Always use #GL_LEQUAL even though GPU_SELECT_PICK_ALL always clears the buffer. This is
* because individual objects themselves might have sections that overlap and we need these
* to have the correct distance information. */
- glDepthFunc(GL_LEQUAL);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
float viewport[4];
GPU_viewport_size_get_f(viewport);
@@ -339,7 +339,7 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
/* It's possible we don't want to clear depth buffer,
* so existing elements are masked by current z-buffer. */
- glClear(GL_DEPTH_BUFFER_BIT);
+ GPU_clear(GPU_DEPTH_BIT);
/* scratch buffer (read new values here) */
ps->gl.rect_depth_test = depth_buf_malloc(rect_len);
@@ -519,7 +519,7 @@ bool gpu_select_pick_load_id(uint id, bool end)
if (g_pick_state.mode == GPU_SELECT_PICK_ALL) {
/* we want new depths every time */
- glClear(GL_DEPTH_BUFFER_BIT);
+ GPU_clear(GPU_DEPTH_BIT);
}
}
}
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index 62414febb44..7e41faf8678 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
+#include "GPU_framebuffer.h"
#include "GPU_glew.h"
#include "GPU_select.h"
#include "GPU_state.h"
@@ -65,7 +66,7 @@ typedef struct GPUQueryState {
int viewport[4];
int scissor[4];
eGPUWriteMask write_mask;
- bool depth_test;
+ eGPUDepthTest depth_test;
} GPUQueryState;
static GPUQueryState g_query_state = {0};
@@ -91,7 +92,7 @@ void gpu_select_query_begin(
glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
g_query_state.write_mask = GPU_write_mask_get();
- g_query_state.depth_test = GPU_depth_test_enabled();
+ g_query_state.depth_test = GPU_depth_test_get();
GPU_scissor_get(g_query_state.scissor);
/* disable writing to the framebuffer */
@@ -112,20 +113,17 @@ void gpu_select_query_begin(
if (mode == GPU_SELECT_ALL) {
/* glQueries on Windows+Intel drivers only works with depth testing turned on.
* See T62947 for details */
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
- glDepthMask(GL_TRUE);
+ GPU_depth_test(GPU_DEPTH_ALWAYS);
+ GPU_depth_mask(true);
}
else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
- glClear(GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LEQUAL);
+ GPU_clear(GPU_DEPTH_BIT);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
+ GPU_depth_mask(true);
}
else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_EQUAL);
+ GPU_depth_test(GPU_DEPTH_EQUAL);
+ GPU_depth_mask(false);
}
}
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 536396ad3c6..21678548b13 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -196,9 +196,7 @@ Shader::Shader(const char *sh_name)
Shader::~Shader()
{
- if (this->interface) {
- GPU_shaderinterface_discard(this->interface);
- }
+ delete interface;
}
static void standard_defines(Vector<const char *> &sources)
@@ -484,43 +482,49 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader)
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
{
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ const ShaderInput *uniform = interface->uniform_get(name);
return uniform ? uniform->location : -1;
}
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
{
- return GPU_shaderinterface_uniform_builtin(shader->interface,
- static_cast<GPUUniformBuiltin>(builtin));
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ return interface->uniform_builtin((GPUUniformBuiltin)builtin);
}
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
{
- return GPU_shaderinterface_block_builtin(shader->interface,
- static_cast<GPUUniformBlockBuiltin>(builtin));
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin);
}
+/* DEPRECATED. */
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
{
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ const ShaderInput *ubo = interface->ubo_get(name);
return ubo ? ubo->location : -1;
}
int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
{
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ const ShaderInput *ubo = interface->ubo_get(name);
return ubo ? ubo->binding : -1;
}
int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
{
- const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ const ShaderInput *tex = interface->uniform_get(name);
return tex ? tex->binding : -1;
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
- const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
+ ShaderInterface *interface = static_cast<Shader *>(shader)->interface;
+ const ShaderInput *attr = interface->attr_get(name);
return attr ? attr->location : -1;
}
@@ -565,14 +569,10 @@ void GPU_shader_uniform_float(GPUShader *shader, int location, float value)
GPU_shader_uniform_vector(shader, location, 1, 1, &value);
}
-#define GET_UNIFORM \
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(sh->interface, name); \
- BLI_assert(uniform);
-
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
{
- GET_UNIFORM
- GPU_shader_uniform_int(sh, uniform->location, value);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_int(sh, loc, value);
}
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
@@ -600,44 +600,44 @@ void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, fl
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float x)
{
- GET_UNIFORM
- GPU_shader_uniform_float(sh, uniform->location, x);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_float(sh, loc, x);
}
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 2, 1, data);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 2, 1, data);
}
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 3, 1, data);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 3, 1, data);
}
void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 4, 1, data);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 4, 1, data);
}
void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 16, 1, (const float *)data);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 16, 1, (const float *)data);
}
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 2, len, (const float *)val);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 2, len, (const float *)val);
}
void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4])
{
- GET_UNIFORM
- GPU_shader_uniform_vector(sh, uniform->location, 4, len, (const float *)val);
+ const int loc = GPU_shader_get_uniform(sh, name);
+ GPU_shader_uniform_vector(sh, loc, 4, len, (const float *)val);
}
/** \} */
@@ -657,7 +657,7 @@ static int g_shader_builtin_srgb_transform = 0;
void GPU_shader_set_srgb_uniform(GPUShader *shader)
{
- int32_t loc = GPU_shaderinterface_uniform_builtin(shader->interface, GPU_UNIFORM_SRGB_TRANSFORM);
+ int32_t loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_SRGB_TRANSFORM);
if (loc != -1) {
GPU_shader_uniform_vector_int(shader, loc, 1, 1, &g_shader_builtin_srgb_transform);
}
diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc
index ef90dde1877..dc59dca9f78 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.cc
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -23,161 +23,41 @@
* GPU shader interface (C --> GLSL)
*/
-#include "BKE_global.h"
-
-#include "BLI_bitmap.h"
-#include "BLI_math_base.h"
-
#include "MEM_guardedalloc.h"
-#include "GPU_shader_interface.h"
-
-#include "gpu_batch_private.hh"
-#include "gpu_context_private.hh"
-
-#include "gl_batch.hh"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define DEBUG_SHADER_INTERFACE 0
-
-#if DEBUG_SHADER_INTERFACE
-# include <stdio.h>
-#endif
-
-using namespace blender::gpu;
-
-static const char *BuiltinUniform_name(GPUUniformBuiltin u)
-{
- switch (u) {
- case GPU_UNIFORM_MODEL:
- return "ModelMatrix";
- case GPU_UNIFORM_VIEW:
- return "ViewMatrix";
- case GPU_UNIFORM_MODELVIEW:
- return "ModelViewMatrix";
- case GPU_UNIFORM_PROJECTION:
- return "ProjectionMatrix";
- case GPU_UNIFORM_VIEWPROJECTION:
- return "ViewProjectionMatrix";
- case GPU_UNIFORM_MVP:
- return "ModelViewProjectionMatrix";
-
- case GPU_UNIFORM_MODEL_INV:
- return "ModelMatrixInverse";
- case GPU_UNIFORM_VIEW_INV:
- return "ViewMatrixInverse";
- case GPU_UNIFORM_MODELVIEW_INV:
- return "ModelViewMatrixInverse";
- case GPU_UNIFORM_PROJECTION_INV:
- return "ProjectionMatrixInverse";
- case GPU_UNIFORM_VIEWPROJECTION_INV:
- return "ViewProjectionMatrixInverse";
-
- case GPU_UNIFORM_NORMAL:
- return "NormalMatrix";
- case GPU_UNIFORM_ORCO:
- return "OrcoTexCoFactors";
- case GPU_UNIFORM_CLIPPLANES:
- return "WorldClipPlanes";
-
- case GPU_UNIFORM_COLOR:
- return "color";
- case GPU_UNIFORM_BASE_INSTANCE:
- return "baseInstance";
- case GPU_UNIFORM_RESOURCE_CHUNK:
- return "resourceChunk";
- case GPU_UNIFORM_RESOURCE_ID:
- return "resourceId";
- case GPU_UNIFORM_SRGB_TRANSFORM:
- return "srgbTarget";
+#include "BLI_span.hh"
+#include "BLI_vector.hh"
- default:
- return NULL;
- }
-}
+#include "gpu_shader_interface.hh"
-static const char *BuiltinUniformBlock_name(GPUUniformBlockBuiltin u)
-{
- switch (u) {
- case GPU_UNIFORM_BLOCK_VIEW:
- return "viewBlock";
- case GPU_UNIFORM_BLOCK_MODEL:
- return "modelBlock";
- case GPU_UNIFORM_BLOCK_INFO:
- return "infoBlock";
- default:
- return NULL;
- }
-}
+namespace blender::gpu {
-GPU_INLINE bool match(const char *a, const char *b)
+ShaderInterface::ShaderInterface(void)
{
- return STREQ(a, b);
+ /* TODO(fclem) add unique ID for debugging. */
}
-GPU_INLINE uint hash_string(const char *str)
+ShaderInterface::~ShaderInterface(void)
{
- uint i = 0, c;
- while ((c = *str++)) {
- i = i * 37 + c;
- }
- return i;
+ /* Free memory used by name_buffer. */
+ MEM_freeN(name_buffer_);
+ MEM_freeN(inputs_);
}
-GPU_INLINE uint32_t set_input_name(GPUShaderInterface *shaderface,
- GPUShaderInput *input,
- char *name,
- uint32_t name_len)
+static void sort_input_list(MutableSpan<ShaderInput> dst)
{
- /* remove "[0]" from array name */
- if (name[name_len - 1] == ']') {
- name[name_len - 3] = '\0';
- name_len -= 3;
+ if (dst.size() == 0) {
+ return;
}
- input->name_offset = (uint32_t)(name - shaderface->name_buffer);
- input->name_hash = hash_string(name);
- return name_len + 1; /* include NULL terminator */
-}
-
-GPU_INLINE const GPUShaderInput *input_lookup(const GPUShaderInterface *shaderface,
- const GPUShaderInput *const inputs,
- const uint inputs_len,
- const char *name)
-{
- const uint name_hash = hash_string(name);
- /* Simple linear search for now. */
- for (int i = inputs_len - 1; i >= 0; i--) {
- if (inputs[i].name_hash == name_hash) {
- if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
- /* Hash colision resolve. */
- for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
- if (match(name, shaderface->name_buffer + inputs[i].name_offset)) {
- return inputs + i; /* not found */
- }
- }
- return NULL; /* not found */
- }
-
- /* This is a bit dangerous since we could have a hash collision.
- * where the asked uniform that does not exist has the same hash
- * as a real uniform. */
- BLI_assert(match(name, shaderface->name_buffer + inputs[i].name_offset));
- return inputs + i;
- }
- }
- return NULL; /* not found */
-}
+ Vector<ShaderInput> inputs_vec = Vector<ShaderInput>(dst.size());
+ MutableSpan<ShaderInput> src = inputs_vec.as_mutable_span();
+ src.copy_from(dst);
-/* Note that this modify the src array. */
-GPU_INLINE void sort_input_list(GPUShaderInput *dst, GPUShaderInput *src, const uint input_len)
-{
- for (uint i = 0; i < input_len; i++) {
- GPUShaderInput *input_src = &src[0];
- for (uint j = 1; j < input_len; j++) {
+ /* Simple sorting by going through the array and selecting the biggest element each time. */
+ for (uint i = 0; i < dst.size(); i++) {
+ ShaderInput *input_src = &src[0];
+ for (uint j = 1; j < src.size(); j++) {
if (src[j].name_hash > input_src->name_hash) {
input_src = &src[j];
}
@@ -187,360 +67,60 @@ GPU_INLINE void sort_input_list(GPUShaderInput *dst, GPUShaderInput *src, const
}
}
-static int block_binding(int32_t program, uint32_t block_index)
+/* Sorts all inputs inside their respective array.
+ * This is to allow fast hash collision detection.
+ * See ShaderInterface::input_lookup for more details. */
+void ShaderInterface::sort_inputs(void)
{
- /* For now just assign a consecutive index. In the future, we should set it in
- * the shader using layout(binding = i) and query its value. */
- glUniformBlockBinding(program, block_index, block_index);
- return block_index;
+ sort_input_list(MutableSpan<ShaderInput>(inputs_, attr_len_));
+ sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_, ubo_len_));
+ sort_input_list(MutableSpan<ShaderInput>(inputs_ + attr_len_ + ubo_len_, uniform_len_));
}
-static int sampler_binding(int32_t program,
- uint32_t uniform_index,
- int32_t uniform_location,
- int *sampler_len)
+void ShaderInterface::debug_print(void)
{
- /* Identify sampler uniforms and asign sampler units to them. */
- GLint type;
- glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
-
- switch (type) {
- case GL_SAMPLER_1D:
- case GL_SAMPLER_2D:
- case GL_SAMPLER_3D:
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_CUBE_MAP_ARRAY_ARB: /* OpenGL 4.0 */
- case GL_SAMPLER_1D_SHADOW:
- case GL_SAMPLER_2D_SHADOW:
- case GL_SAMPLER_1D_ARRAY:
- case GL_SAMPLER_2D_ARRAY:
- case GL_SAMPLER_1D_ARRAY_SHADOW:
- case GL_SAMPLER_2D_ARRAY_SHADOW:
- case GL_SAMPLER_2D_MULTISAMPLE:
- case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
- case GL_SAMPLER_CUBE_SHADOW:
- case GL_SAMPLER_BUFFER:
- case GL_INT_SAMPLER_1D:
- case GL_INT_SAMPLER_2D:
- case GL_INT_SAMPLER_3D:
- case GL_INT_SAMPLER_CUBE:
- case GL_INT_SAMPLER_1D_ARRAY:
- case GL_INT_SAMPLER_2D_ARRAY:
- case GL_INT_SAMPLER_2D_MULTISAMPLE:
- case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
- case GL_INT_SAMPLER_BUFFER:
- case GL_UNSIGNED_INT_SAMPLER_1D:
- case GL_UNSIGNED_INT_SAMPLER_2D:
- case GL_UNSIGNED_INT_SAMPLER_3D:
- case GL_UNSIGNED_INT_SAMPLER_CUBE:
- case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
- case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
- case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
- case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
- case GL_UNSIGNED_INT_SAMPLER_BUFFER: {
- /* For now just assign a consecutive index. In the future, we should set it in
- * the shader using layout(binding = i) and query its value. */
- int binding = *sampler_len;
- glUniform1i(uniform_location, binding);
- (*sampler_len)++;
- return binding;
- }
- default:
- return -1;
- }
-}
+ Span<ShaderInput> attrs = Span<ShaderInput>(inputs_, attr_len_);
+ Span<ShaderInput> ubos = Span<ShaderInput>(inputs_ + attr_len_, ubo_len_);
+ Span<ShaderInput> uniforms = Span<ShaderInput>(inputs_ + attr_len_ + ubo_len_, uniform_len_);
+ char *name_buf = name_buffer_;
+ const char format[] = " | %.8x : %4d : %s\n";
-GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
-{
-#ifndef NDEBUG
- GLint curr_program;
- glGetIntegerv(GL_CURRENT_PROGRAM, &curr_program);
- BLI_assert(curr_program == program);
-#endif
-
- GLint max_attr_name_len = 0, attr_len = 0;
- glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_len);
- glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len);
-
- GLint max_ubo_name_len = 0, ubo_len = 0;
- glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len);
- glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len);
-
- GLint max_uniform_name_len = 0, active_uniform_len = 0, uniform_len = 0;
- glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_len);
- glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniform_len);
- uniform_len = active_uniform_len;
-
- /* Work around driver bug with Intel HD 4600 on Windows 7/8, where
- * GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH does not work. */
- if (attr_len > 0 && max_attr_name_len == 0) {
- max_attr_name_len = 256;
- }
- if (ubo_len > 0 && max_ubo_name_len == 0) {
- max_ubo_name_len = 256;
+ printf(" \033[1mGPUShaderInterface : \033[0m\n");
+ if (attrs.size() > 0) {
+ printf("\n Attributes :\n");
}
- if (uniform_len > 0 && max_uniform_name_len == 0) {
- max_uniform_name_len = 256;
+ for (const ShaderInput &attr : attrs) {
+ printf(format, attr.name_hash, attr.location, name_buf + attr.name_offset);
}
- /* GL_ACTIVE_UNIFORMS lied to us! Remove the UBO uniforms from the total before
- * allocating the uniform array. */
- GLint max_ubo_uni_len = 0;
- for (int i = 0; i < ubo_len; i++) {
- GLint ubo_uni_len;
- glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
- max_ubo_uni_len = max_ii(max_ubo_uni_len, ubo_uni_len);
- uniform_len -= ubo_uni_len;
+ if (uniforms.size() > 0) {
+ printf("\n Uniforms :\n");
}
- /* Bit set to true if uniform comes from a uniform block. */
- BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__);
- /* Set uniforms from block for exclusion. */
- GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
- for (int i = 0; i < ubo_len; i++) {
- GLint ubo_uni_len;
- glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
- glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, ubo_uni_ids);
- for (int u = 0; u < ubo_uni_len; u++) {
- BLI_BITMAP_ENABLE(uniforms_from_blocks, ubo_uni_ids[u]);
+ for (const ShaderInput &uni : uniforms) {
+ /* Bypass samplers. */
+ if (uni.binding == -1) {
+ printf(format, uni.name_hash, uni.location, name_buf + uni.name_offset);
}
}
- MEM_freeN(ubo_uni_ids);
- uint32_t name_buffer_offset = 0;
- const uint32_t name_buffer_len = attr_len * max_attr_name_len + ubo_len * max_ubo_name_len +
- uniform_len * max_uniform_name_len;
-
- int input_tot_len = attr_len + ubo_len + uniform_len;
- size_t interface_size = sizeof(GPUShaderInterface) + sizeof(GPUShaderInput) * input_tot_len;
-
- GPUShaderInterface *shaderface = (GPUShaderInterface *)MEM_callocN(interface_size,
- "GPUShaderInterface");
- shaderface->attribute_len = attr_len;
- shaderface->ubo_len = ubo_len;
- shaderface->uniform_len = uniform_len;
- shaderface->name_buffer = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
- GPUShaderInput *inputs = shaderface->inputs;
-
- /* Temp buffer. */
- int input_tmp_len = max_iii(attr_len, ubo_len, uniform_len);
- GPUShaderInput *inputs_tmp = (GPUShaderInput *)MEM_mallocN(
- sizeof(GPUShaderInput) * input_tmp_len, "name_buffer");
-
- /* Attributes */
- shaderface->enabled_attr_mask = 0;
- for (int i = 0, idx = 0; i < attr_len; i++) {
- char *name = shaderface->name_buffer + name_buffer_offset;
- GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
- GLsizei name_len = 0;
- GLenum type;
- GLint size;
-
- glGetActiveAttrib(program, i, remaining_buffer, &name_len, &size, &type, name);
- GLint location = glGetAttribLocation(program, name);
- /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
- if (location == -1) {
- shaderface->attribute_len--;
- continue;
- }
-
- GPUShaderInput *input = &inputs_tmp[idx++];
- input->location = input->binding = location;
-
- name_buffer_offset += set_input_name(shaderface, input, name, name_len);
- shaderface->enabled_attr_mask |= (1 << input->location);
+ if (ubos.size() > 0) {
+ printf("\n Uniform Buffer Objects :\n");
}
- sort_input_list(inputs, inputs_tmp, shaderface->attribute_len);
- inputs += shaderface->attribute_len;
-
- /* Uniform Blocks */
- for (int i = 0, idx = 0; i < ubo_len; i++) {
- char *name = shaderface->name_buffer + name_buffer_offset;
- GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
- GLsizei name_len = 0;
-
- glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name);
-
- GPUShaderInput *input = &inputs_tmp[idx++];
- input->binding = input->location = block_binding(program, i);
-
- name_buffer_offset += set_input_name(shaderface, input, name, name_len);
- shaderface->enabled_ubo_mask |= (1 << input->binding);
+ for (const ShaderInput &ubo : ubos) {
+ printf(format, ubo.name_hash, ubo.binding, name_buf + ubo.name_offset);
}
- sort_input_list(inputs, inputs_tmp, shaderface->ubo_len);
- inputs += shaderface->ubo_len;
- /* Uniforms */
- for (int i = 0, idx = 0, sampler = 0; i < active_uniform_len; i++) {
- if (BLI_BITMAP_TEST(uniforms_from_blocks, i)) {
- continue;
- }
- char *name = shaderface->name_buffer + name_buffer_offset;
- GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
- GLsizei name_len = 0;
-
- glGetActiveUniformName(program, i, remaining_buffer, &name_len, name);
-
- GPUShaderInput *input = &inputs_tmp[idx++];
- input->location = glGetUniformLocation(program, name);
- input->binding = sampler_binding(program, i, input->location, &sampler);
-
- name_buffer_offset += set_input_name(shaderface, input, name, name_len);
- shaderface->enabled_tex_mask |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
- }
- sort_input_list(inputs, inputs_tmp, shaderface->uniform_len);
-
- /* Builtin Uniforms */
- for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
- GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
- shaderface->builtins[u] = glGetUniformLocation(program, BuiltinUniform_name(u));
- }
-
- /* Builtin Uniforms Blocks */
- for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) {
- GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int);
- const GPUShaderInput *block = GPU_shaderinterface_ubo(shaderface, BuiltinUniformBlock_name(u));
- shaderface->builtin_blocks[u] = (block != NULL) ? block->binding : -1;
- }
-
- /* Batches ref buffer */
- shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = (void **)MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *),
- "GPUShaderInterface batches");
-
- MEM_freeN(uniforms_from_blocks);
- MEM_freeN(inputs_tmp);
-
- /* Resize name buffer to save some memory. */
- if (name_buffer_offset < name_buffer_len) {
- shaderface->name_buffer = (char *)MEM_reallocN(shaderface->name_buffer, name_buffer_offset);
- }
-
-#if DEBUG_SHADER_INTERFACE
- char *name_buf = shaderface->name_buffer;
- printf("--- GPUShaderInterface %p, program %d ---\n", shaderface, program);
- if (shaderface->attribute_len > 0) {
- printf("Attributes {\n");
- for (int i = 0; i < shaderface->attribute_len; i++) {
- GPUShaderInput *input = shaderface->inputs + i;
- printf("\t(location = %d) %s;\n", input->location, name_buf + input->name_offset);
- }
- printf("};\n");
- }
- if (shaderface->ubo_len > 0) {
- printf("Uniform Buffer Objects {\n");
- for (int i = 0; i < shaderface->ubo_len; i++) {
- GPUShaderInput *input = shaderface->inputs + shaderface->attribute_len + i;
- printf("\t(binding = %d) %s;\n", input->binding, name_buf + input->name_offset);
- }
- printf("};\n");
+ if (enabled_tex_mask_ > 0) {
+ printf("\n Samplers :\n");
}
- if (shaderface->enabled_tex_mask > 0) {
- printf("Samplers {\n");
- for (int i = 0; i < shaderface->uniform_len; i++) {
- GPUShaderInput *input = shaderface->inputs + shaderface->attribute_len +
- shaderface->ubo_len + i;
- if (input->binding != -1) {
- printf("\t(location = %d, binding = %d) %s;\n",
- input->location,
- input->binding,
- name_buf + input->name_offset);
- }
- }
- printf("};\n");
- }
- if (shaderface->uniform_len > 0) {
- printf("Uniforms {\n");
- for (int i = 0; i < shaderface->uniform_len; i++) {
- GPUShaderInput *input = shaderface->inputs + shaderface->attribute_len +
- shaderface->ubo_len + i;
- if (input->binding == -1) {
- printf("\t(location = %d) %s;\n", input->location, name_buf + input->name_offset);
- }
+ for (const ShaderInput &samp : uniforms) {
+ /* Bypass uniforms. */
+ if (samp.binding != -1) {
+ printf(format, samp.name_hash, samp.binding, name_buf + samp.name_offset);
}
- printf("};\n");
}
- printf("--- GPUShaderInterface end ---\n\n");
-#endif
- return shaderface;
-}
-
-void GPU_shaderinterface_discard(GPUShaderInterface *shaderface)
-{
- /* Free memory used by name_buffer. */
- MEM_freeN(shaderface->name_buffer);
- /* Remove this interface from all linked Batches vao cache. */
- for (int i = 0; i < shaderface->batches_len; i++) {
- if (shaderface->batches[i] != NULL) {
- /* XXX GL specific. to be removed during refactor. */
- reinterpret_cast<GLVaoCache *>(shaderface->batches[i])->remove(shaderface);
- }
- }
- MEM_freeN(shaderface->batches);
- /* Free memory used by shader interface by its self. */
- MEM_freeN(shaderface);
+ printf("\n");
}
-const GPUShaderInput *GPU_shaderinterface_attr(const GPUShaderInterface *shaderface,
- const char *name)
-{
- uint ofs = 0;
- return input_lookup(shaderface, shaderface->inputs + ofs, shaderface->attribute_len, name);
-}
-
-const GPUShaderInput *GPU_shaderinterface_ubo(const GPUShaderInterface *shaderface,
- const char *name)
-{
- uint ofs = shaderface->attribute_len;
- return input_lookup(shaderface, shaderface->inputs + ofs, shaderface->ubo_len, name);
-}
-
-const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *shaderface,
- const char *name)
-{
- uint ofs = shaderface->attribute_len + shaderface->ubo_len;
- return input_lookup(shaderface, shaderface->inputs + ofs, shaderface->uniform_len, name);
-}
-
-int32_t GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
- GPUUniformBuiltin builtin)
-{
- BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
- return shaderface->builtins[builtin];
-}
-
-int32_t GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
- GPUUniformBlockBuiltin builtin)
-{
- BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
- return shaderface->builtin_blocks[builtin];
-}
-
-void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, void *batch)
-{
- int i; /* find first unused slot */
- for (i = 0; i < shaderface->batches_len; i++) {
- if (shaderface->batches[i] == NULL) {
- break;
- }
- }
- if (i == shaderface->batches_len) {
- /* Not enough place, realloc the array. */
- i = shaderface->batches_len;
- shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = (void **)MEM_recallocN(shaderface->batches,
- sizeof(void *) * shaderface->batches_len);
- }
- /** XXX todo cleanup. */
- shaderface->batches[i] = reinterpret_cast<void *>(batch);
-}
-
-void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface *shaderface, void *batch)
-{
- for (int i = 0; i < shaderface->batches_len; i++) {
- if (shaderface->batches[i] == batch) {
- shaderface->batches[i] = NULL;
- break; /* cannot have duplicates */
- }
- }
-}
+} // namespace blender::gpu
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
new file mode 100644
index 00000000000..76925f4fddb
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -0,0 +1,225 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 by Mike Erwin.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * GPU shader interface (C --> GLSL)
+ *
+ * Structure detailling needed vertex inputs and resources for a specific shader.
+ * A shader interface can be shared between two similar shaders.
+ */
+
+#pragma once
+
+#include <cstring> /* required for STREQ later on. */
+
+#include "BLI_hash.h"
+#include "BLI_utildefines.h"
+
+#include "GPU_shader.h"
+
+namespace blender::gpu {
+
+typedef struct ShaderInput {
+ uint32_t name_offset;
+ uint32_t name_hash;
+ int32_t location;
+ /** Defined at interface creation or in shader. Only for Samplers, UBOs and Vertex Attribs. */
+ int32_t binding;
+} ShaderInput;
+
+class ShaderInterface {
+ /* TODO(fclem) should be protected. */
+ public:
+ /** Flat array. In this order: Attributes, Ubos, Uniforms. */
+ ShaderInput *inputs_ = NULL;
+ /** Buffer containing all inputs names separated by '\0'. */
+ char *name_buffer_ = NULL;
+ /** Input counts inside input array. */
+ uint attr_len_ = 0;
+ uint ubo_len_ = 0;
+ uint uniform_len_ = 0;
+ /** Enabled bindpoints that needs to be fed with data. */
+ uint16_t enabled_attr_mask_ = 0;
+ uint16_t enabled_ubo_mask_ = 0;
+ uint64_t enabled_tex_mask_ = 0;
+ /** Location of builtin uniforms. Fast access, no lookup needed. */
+ int32_t builtins_[GPU_NUM_UNIFORMS];
+ int32_t builtin_blocks_[GPU_NUM_UNIFORM_BLOCKS];
+
+ public:
+ ShaderInterface();
+ virtual ~ShaderInterface();
+
+ void debug_print(void);
+
+ inline const ShaderInput *attr_get(const char *name) const
+ {
+ return input_lookup(inputs_, attr_len_, name);
+ }
+
+ inline const ShaderInput *ubo_get(const char *name) const
+ {
+ return input_lookup(inputs_ + attr_len_, ubo_len_, name);
+ }
+
+ inline const ShaderInput *uniform_get(const char *name) const
+ {
+ return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
+ }
+
+ /* Returns uniform location. */
+ inline int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
+ {
+ BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
+ return builtins_[builtin];
+ }
+
+ /* Returns binding position. */
+ inline int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
+ {
+ BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
+ return builtin_blocks_[builtin];
+ }
+
+ protected:
+ static inline const char *builtin_uniform_name(GPUUniformBuiltin u);
+ static inline const char *builtin_uniform_block_name(GPUUniformBlockBuiltin u);
+
+ inline uint32_t set_input_name(ShaderInput *input, char *name, uint32_t name_len) const;
+
+ /* Finalize interface construction by sorting the ShaderInputs for faster lookups. */
+ void sort_inputs(void);
+
+ private:
+ inline const ShaderInput *input_lookup(const ShaderInput *const inputs,
+ const uint inputs_len,
+ const char *name) const;
+};
+
+inline const char *ShaderInterface::builtin_uniform_name(GPUUniformBuiltin u)
+{
+ switch (u) {
+ case GPU_UNIFORM_MODEL:
+ return "ModelMatrix";
+ case GPU_UNIFORM_VIEW:
+ return "ViewMatrix";
+ case GPU_UNIFORM_MODELVIEW:
+ return "ModelViewMatrix";
+ case GPU_UNIFORM_PROJECTION:
+ return "ProjectionMatrix";
+ case GPU_UNIFORM_VIEWPROJECTION:
+ return "ViewProjectionMatrix";
+ case GPU_UNIFORM_MVP:
+ return "ModelViewProjectionMatrix";
+
+ case GPU_UNIFORM_MODEL_INV:
+ return "ModelMatrixInverse";
+ case GPU_UNIFORM_VIEW_INV:
+ return "ViewMatrixInverse";
+ case GPU_UNIFORM_MODELVIEW_INV:
+ return "ModelViewMatrixInverse";
+ case GPU_UNIFORM_PROJECTION_INV:
+ return "ProjectionMatrixInverse";
+ case GPU_UNIFORM_VIEWPROJECTION_INV:
+ return "ViewProjectionMatrixInverse";
+
+ case GPU_UNIFORM_NORMAL:
+ return "NormalMatrix";
+ case GPU_UNIFORM_ORCO:
+ return "OrcoTexCoFactors";
+ case GPU_UNIFORM_CLIPPLANES:
+ return "WorldClipPlanes";
+
+ case GPU_UNIFORM_COLOR:
+ return "color";
+ case GPU_UNIFORM_BASE_INSTANCE:
+ return "baseInstance";
+ case GPU_UNIFORM_RESOURCE_CHUNK:
+ return "resourceChunk";
+ case GPU_UNIFORM_RESOURCE_ID:
+ return "resourceId";
+ case GPU_UNIFORM_SRGB_TRANSFORM:
+ return "srgbTarget";
+
+ default:
+ return NULL;
+ }
+}
+
+inline const char *ShaderInterface::builtin_uniform_block_name(GPUUniformBlockBuiltin u)
+{
+ switch (u) {
+ case GPU_UNIFORM_BLOCK_VIEW:
+ return "viewBlock";
+ case GPU_UNIFORM_BLOCK_MODEL:
+ return "modelBlock";
+ case GPU_UNIFORM_BLOCK_INFO:
+ return "infoBlock";
+ default:
+ return NULL;
+ }
+}
+
+/* Returns string length including '\0' terminator. */
+inline uint32_t ShaderInterface::set_input_name(ShaderInput *input,
+ char *name,
+ uint32_t name_len) const
+{
+ /* remove "[0]" from array name */
+ if (name[name_len - 1] == ']') {
+ name[name_len - 3] = '\0';
+ name_len -= 3;
+ }
+
+ input->name_offset = (uint32_t)(name - name_buffer_);
+ input->name_hash = BLI_hash_string(name);
+ return name_len + 1; /* include NULL terminator */
+}
+
+inline const ShaderInput *ShaderInterface::input_lookup(const ShaderInput *const inputs,
+ const uint inputs_len,
+ const char *name) const
+{
+ const uint name_hash = BLI_hash_string(name);
+ /* Simple linear search for now. */
+ for (int i = inputs_len - 1; i >= 0; i--) {
+ if (inputs[i].name_hash == name_hash) {
+ if ((i > 0) && UNLIKELY(inputs[i - 1].name_hash == name_hash)) {
+ /* Hash colision resolve. */
+ for (; i >= 0 && inputs[i].name_hash == name_hash; i--) {
+ if (STREQ(name, name_buffer_ + inputs[i].name_offset)) {
+ return inputs + i; /* not found */
+ }
+ }
+ return NULL; /* not found */
+ }
+
+ /* This is a bit dangerous since we could have a hash collision.
+ * where the asked uniform that does not exist has the same hash
+ * as a real uniform. */
+ BLI_assert(STREQ(name, name_buffer_ + inputs[i].name_offset));
+ return inputs + i;
+ }
+ }
+ return NULL; /* not found */
+}
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
index 1f667fb4cf9..d51c3b03ecb 100644
--- a/source/blender/gpu/intern/gpu_shader_private.hh
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -23,14 +23,18 @@
#include "BLI_span.hh"
#include "GPU_shader.h"
-#include "GPU_shader_interface.h"
#include "GPU_vertex_buffer.h"
+#include "gpu_shader_interface.hh"
namespace blender {
namespace gpu {
class Shader : public GPUShader {
public:
+ /** Uniform & attribute locations for shader. */
+ ShaderInterface *interface;
+
+ public:
Shader(const char *name);
virtual ~Shader();
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index 2c09773e8f5..1be3b06fa34 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -74,10 +74,9 @@ void GPU_provoking_vertex(eGPUProvokingVertex vert)
SET_IMMUTABLE_STATE(provoking_vert, vert);
}
-/* TODO explicit depth test. */
-void GPU_depth_test(bool enable)
+void GPU_depth_test(eGPUDepthTest test)
{
- SET_IMMUTABLE_STATE(depth_test, (enable) ? GPU_DEPTH_LESS_EQUAL : GPU_DEPTH_NONE);
+ SET_IMMUTABLE_STATE(depth_test, test);
}
void GPU_line_smooth(bool enable)
@@ -240,10 +239,10 @@ eGPUWriteMask GPU_write_mask_get()
return (eGPUWriteMask)state.write_mask;
}
-bool GPU_depth_test_enabled()
+eGPUDepthTest GPU_depth_test_get()
{
GPUState &state = GPU_context_active_get()->state_manager->state;
- return state.depth_test != GPU_DEPTH_NONE;
+ return (eGPUDepthTest)state.depth_test;
}
void GPU_scissor_get(int coords[4])
diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc
index fade8763065..9ca0a9f71db 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -33,6 +33,7 @@
#include "gpu_batch_private.hh"
#include "gpu_primitive_private.h"
+#include "gpu_shader_private.hh"
#include "gl_batch.hh"
#include "gl_context.hh"
@@ -71,7 +72,7 @@ void GLVaoCache::init(void)
}
/* Create a new VAO object and store it in the cache. */
-void GLVaoCache::insert(const GPUShaderInterface *interface, GLuint vao)
+void GLVaoCache::insert(const GLShaderInterface *interface, GLuint vao)
{
/* Now insert the cache. */
if (!is_dynamic_vao_count) {
@@ -90,8 +91,7 @@ void GLVaoCache::insert(const GPUShaderInterface *interface, GLuint vao)
/* Erase previous entries, they will be added back if drawn again. */
for (int i = 0; i < GPU_VAO_STATIC_LEN; i++) {
if (static_vaos.interfaces[i] != NULL) {
- GPU_shaderinterface_remove_batch_ref(
- const_cast<GPUShaderInterface *>(static_vaos.interfaces[i]), this);
+ const_cast<GLShaderInterface *>(static_vaos.interfaces[i])->ref_remove(this);
context_->vao_free(static_vaos.vao_ids[i]);
}
}
@@ -99,8 +99,8 @@ void GLVaoCache::insert(const GPUShaderInterface *interface, GLuint vao)
is_dynamic_vao_count = true;
/* Init dynamic arrays and let the branch below set the values. */
dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_callocN(
- dynamic_vaos.count * sizeof(GPUShaderInterface *), "dyn vaos interfaces");
+ dynamic_vaos.interfaces = (const GLShaderInterface **)MEM_callocN(
+ dynamic_vaos.count * sizeof(GLShaderInterface *), "dyn vaos interfaces");
dynamic_vaos.vao_ids = (GLuint *)MEM_callocN(dynamic_vaos.count * sizeof(GLuint),
"dyn vaos ids");
}
@@ -118,8 +118,8 @@ void GLVaoCache::insert(const GPUShaderInterface *interface, GLuint vao)
/* Not enough place, realloc the array. */
i = dynamic_vaos.count;
dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_recallocN(
- (void *)dynamic_vaos.interfaces, sizeof(GPUShaderInterface *) * dynamic_vaos.count);
+ dynamic_vaos.interfaces = (const GLShaderInterface **)MEM_recallocN(
+ (void *)dynamic_vaos.interfaces, sizeof(GLShaderInterface *) * dynamic_vaos.count);
dynamic_vaos.vao_ids = (GLuint *)MEM_recallocN(dynamic_vaos.vao_ids,
sizeof(GLuint) * dynamic_vaos.count);
}
@@ -127,15 +127,15 @@ void GLVaoCache::insert(const GPUShaderInterface *interface, GLuint vao)
dynamic_vaos.vao_ids[i] = vao;
}
- GPU_shaderinterface_add_batch_ref(const_cast<GPUShaderInterface *>(interface), this);
+ const_cast<GLShaderInterface *>(interface)->ref_add(this);
}
-void GLVaoCache::remove(const GPUShaderInterface *interface)
+void GLVaoCache::remove(const GLShaderInterface *interface)
{
const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN;
GLuint *vaos = (is_dynamic_vao_count) ? dynamic_vaos.vao_ids : static_vaos.vao_ids;
- const GPUShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
- static_vaos.interfaces;
+ const GLShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
+ static_vaos.interfaces;
for (int i = 0; i < count; i++) {
if (interfaces[i] == interface) {
context_->vao_free(vaos[i]);
@@ -151,8 +151,8 @@ void GLVaoCache::clear(void)
GLContext *ctx = static_cast<GLContext *>(GPU_context_active_get());
const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN;
GLuint *vaos = (is_dynamic_vao_count) ? dynamic_vaos.vao_ids : static_vaos.vao_ids;
- const GPUShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
- static_vaos.interfaces;
+ const GLShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
+ static_vaos.interfaces;
/* Early out, nothing to free. */
if (context_ == NULL) {
return;
@@ -171,10 +171,9 @@ void GLVaoCache::clear(void)
}
for (int i = 0; i < count; i++) {
- if (interfaces[i] == NULL) {
- continue;
+ if (interfaces[i] != NULL) {
+ const_cast<GLShaderInterface *>(interfaces[i])->ref_remove(this);
}
- GPU_shaderinterface_remove_batch_ref(const_cast<GPUShaderInterface *>(interfaces[i]), this);
}
if (is_dynamic_vao_count) {
@@ -190,11 +189,11 @@ void GLVaoCache::clear(void)
}
/* Return 0 on cache miss (invalid VAO) */
-GLuint GLVaoCache::lookup(const GPUShaderInterface *interface)
+GLuint GLVaoCache::lookup(const GLShaderInterface *interface)
{
const int count = (is_dynamic_vao_count) ? dynamic_vaos.count : GPU_VAO_STATIC_LEN;
- const GPUShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
- static_vaos.interfaces;
+ const GLShaderInterface **interfaces = (is_dynamic_vao_count) ? dynamic_vaos.interfaces :
+ static_vaos.interfaces;
for (int i = 0; i < count; i++) {
if (interfaces[i] == interface) {
return (is_dynamic_vao_count) ? dynamic_vaos.vao_ids[i] : static_vaos.vao_ids[i];
@@ -226,7 +225,9 @@ GLuint GLVaoCache::base_instance_vao_get(GPUBatch *batch, int i_first)
{
this->context_check();
/* Make sure the interface is up to date. */
- if (interface_ != GPU_context_active_get()->shader->interface) {
+ Shader *shader = static_cast<Shader *>(GPU_context_active_get()->shader);
+ GLShaderInterface *interface = static_cast<GLShaderInterface *>(shader->interface);
+ if (interface_ != interface) {
vao_get(batch);
/* Trigger update. */
base_instance_ = 0;
@@ -255,9 +256,10 @@ GLuint GLVaoCache::vao_get(GPUBatch *batch)
{
this->context_check();
- GPUContext *ctx = GPU_context_active_get();
- if (interface_ != ctx->shader->interface) {
- interface_ = ctx->shader->interface;
+ Shader *shader = static_cast<Shader *>(GPU_context_active_get()->shader);
+ GLShaderInterface *interface = static_cast<GLShaderInterface *>(shader->interface);
+ if (interface_ != interface) {
+ interface_ = interface;
vao_id_ = this->lookup(interface_);
if (vao_id_ == 0) {
diff --git a/source/blender/gpu/opengl/gl_batch.hh b/source/blender/gpu/opengl/gl_batch.hh
index d70f43aed2a..9a7767d679d 100644
--- a/source/blender/gpu/opengl/gl_batch.hh
+++ b/source/blender/gpu/opengl/gl_batch.hh
@@ -32,11 +32,11 @@
#include "glew-mx.h"
-#include "GPU_shader_interface.h"
-
namespace blender {
namespace gpu {
+class GLShaderInterface;
+
#define GPU_VAO_STATIC_LEN 3
/* Vao management: remembers all geometry state (vertex attribute bindings & element buffer)
@@ -47,7 +47,7 @@ class GLVaoCache {
/** Context for which the vao_cache_ was generated. */
struct GLContext *context_ = NULL;
/** Last interface this batch was drawn with. */
- GPUShaderInterface *interface_ = NULL;
+ GLShaderInterface *interface_ = NULL;
/** Cached vao for the last interface. */
GLuint vao_id_ = 0;
/** Used whend arb_base_instance is not supported. */
@@ -58,13 +58,13 @@ class GLVaoCache {
union {
/** Static handle count */
struct {
- const GPUShaderInterface *interfaces[GPU_VAO_STATIC_LEN];
+ const GLShaderInterface *interfaces[GPU_VAO_STATIC_LEN];
GLuint vao_ids[GPU_VAO_STATIC_LEN];
} static_vaos;
/** Dynamic handle count */
struct {
uint count;
- const GPUShaderInterface **interfaces;
+ const GLShaderInterface **interfaces;
GLuint *vao_ids;
} dynamic_vaos;
};
@@ -76,9 +76,9 @@ class GLVaoCache {
GLuint vao_get(GPUBatch *batch);
GLuint base_instance_vao_get(GPUBatch *batch, int i_first);
- GLuint lookup(const GPUShaderInterface *interface);
- void insert(const GPUShaderInterface *interface, GLuint vao_id);
- void remove(const GPUShaderInterface *interface);
+ GLuint lookup(const GLShaderInterface *interface);
+ void insert(const GLShaderInterface *interface, GLuint vao_id);
+ void remove(const GLShaderInterface *interface);
void clear(void);
private:
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index ea33ff00d69..93ed7a408c6 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -29,6 +29,7 @@
#include "GPU_platform.h"
#include "gl_shader.hh"
+#include "gl_shader_interface.hh"
using namespace blender;
using namespace blender::gpu;
@@ -203,10 +204,7 @@ bool GLShader::finalize(void)
return false;
}
- /* TODO(fclem) We need this to modify the image binding points using glUniform.
- * This could be avoided using glProgramUniform in GL 4.1. */
- glUseProgram(shader_program_);
- interface = GPU_shaderinterface_create(shader_program_);
+ interface = new GLShaderInterface(shader_program_);
return true;
}
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
new file mode 100644
index 00000000000..423db5c8c97
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -0,0 +1,297 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2016 by Mike Erwin.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * GPU shader interface (C --> GLSL)
+ */
+
+#include "BLI_bitmap.h"
+
+#include "gl_batch.hh"
+
+#include "gl_shader_interface.hh"
+
+namespace blender::gpu {
+
+/* -------------------------------------------------------------------- */
+/** \name Binding assignment
+ *
+ * To mimic vulkan, we assign binding at shader creation to avoid shader recompilation.
+ * In the future, we should set it in the shader using layout(binding = i) and query its value.
+ * \{ */
+
+static inline int block_binding(int32_t program, uint32_t block_index)
+{
+ /* For now just assign a consecutive index. In the future, we should set it in
+ * the shader using layout(binding = i) and query its value. */
+ glUniformBlockBinding(program, block_index, block_index);
+ return block_index;
+}
+
+static inline int sampler_binding(int32_t program,
+ uint32_t uniform_index,
+ int32_t uniform_location,
+ int *sampler_len)
+{
+ /* Identify sampler uniforms and asign sampler units to them. */
+ GLint type;
+ glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
+
+ switch (type) {
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_ARB: /* OpenGL 4.0 */
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_1D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_1D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_1D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_1D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_1D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER: {
+ /* For now just assign a consecutive index. In the future, we should set it in
+ * the shader using layout(binding = i) and query its value. */
+ int binding = *sampler_len;
+ glUniform1i(uniform_location, binding);
+ (*sampler_len)++;
+ return binding;
+ }
+ default:
+ return -1;
+ }
+}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Creation / Destruction
+ * \{ */
+
+GLShaderInterface::GLShaderInterface(GLuint program)
+{
+ /* Necessary to make glUniform works. */
+ glUseProgram(program);
+
+ GLint max_attr_name_len = 0, attr_len = 0;
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_len);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len);
+
+ GLint max_ubo_name_len = 0, ubo_len = 0;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len);
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len);
+
+ GLint max_uniform_name_len = 0, active_uniform_len = 0, uniform_len = 0;
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_len);
+ glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniform_len);
+ uniform_len = active_uniform_len;
+
+ /* Work around driver bug with Intel HD 4600 on Windows 7/8, where
+ * GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH does not work. */
+ if (attr_len > 0 && max_attr_name_len == 0) {
+ max_attr_name_len = 256;
+ }
+ if (ubo_len > 0 && max_ubo_name_len == 0) {
+ max_ubo_name_len = 256;
+ }
+ if (uniform_len > 0 && max_uniform_name_len == 0) {
+ max_uniform_name_len = 256;
+ }
+
+ /* GL_ACTIVE_UNIFORMS lied to us! Remove the UBO uniforms from the total before
+ * allocating the uniform array. */
+ GLint max_ubo_uni_len = 0;
+ for (int i = 0; i < ubo_len; i++) {
+ GLint ubo_uni_len;
+ glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
+ max_ubo_uni_len = max_ii(max_ubo_uni_len, ubo_uni_len);
+ uniform_len -= ubo_uni_len;
+ }
+ /* Bit set to true if uniform comes from a uniform block. */
+ BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__);
+ /* Set uniforms from block for exclusion. */
+ GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
+ for (int i = 0; i < ubo_len; i++) {
+ GLint ubo_uni_len;
+ glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
+ glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, ubo_uni_ids);
+ for (int u = 0; u < ubo_uni_len; u++) {
+ BLI_BITMAP_ENABLE(uniforms_from_blocks, ubo_uni_ids[u]);
+ }
+ }
+ MEM_freeN(ubo_uni_ids);
+
+ int input_tot_len = attr_len + ubo_len + uniform_len;
+ inputs_ = (ShaderInput *)MEM_callocN(sizeof(ShaderInput) * input_tot_len, __func__);
+
+ const uint32_t name_buffer_len = attr_len * max_attr_name_len + ubo_len * max_ubo_name_len +
+ uniform_len * max_uniform_name_len;
+ name_buffer_ = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
+ uint32_t name_buffer_offset = 0;
+
+ /* Attributes */
+ enabled_attr_mask_ = 0;
+ for (int i = 0; i < attr_len; i++) {
+ char *name = name_buffer_ + name_buffer_offset;
+ GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+ GLsizei name_len = 0;
+ GLenum type;
+ GLint size;
+
+ glGetActiveAttrib(program, i, remaining_buffer, &name_len, &size, &type, name);
+ GLint location = glGetAttribLocation(program, name);
+ /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
+ if (location == -1) {
+ continue;
+ }
+
+ ShaderInput *input = &inputs_[attr_len_++];
+ input->location = input->binding = location;
+
+ name_buffer_offset += set_input_name(input, name, name_len);
+ enabled_attr_mask_ |= (1 << input->location);
+ }
+
+ /* Uniform Blocks */
+ for (int i = 0; i < ubo_len; i++) {
+ char *name = name_buffer_ + name_buffer_offset;
+ GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name);
+
+ ShaderInput *input = &inputs_[attr_len_ + ubo_len_++];
+ input->binding = input->location = block_binding(program, i);
+
+ name_buffer_offset += this->set_input_name(input, name, name_len);
+ enabled_ubo_mask_ |= (1 << input->binding);
+ }
+
+ /* Uniforms */
+ for (int i = 0, sampler = 0; i < active_uniform_len; i++) {
+ if (BLI_BITMAP_TEST(uniforms_from_blocks, i)) {
+ continue;
+ }
+ char *name = name_buffer_ + name_buffer_offset;
+ GLsizei remaining_buffer = name_buffer_len - name_buffer_offset;
+ GLsizei name_len = 0;
+
+ glGetActiveUniformName(program, i, remaining_buffer, &name_len, name);
+
+ ShaderInput *input = &inputs_[attr_len_ + ubo_len_ + uniform_len_++];
+ input->location = glGetUniformLocation(program, name);
+ input->binding = sampler_binding(program, i, input->location, &sampler);
+
+ name_buffer_offset += this->set_input_name(input, name, name_len);
+ enabled_tex_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
+ }
+
+ /* Builtin Uniforms */
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
+ GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
+ builtins_[u] = glGetUniformLocation(program, builtin_uniform_name(u));
+ }
+
+ /* Builtin Uniforms Blocks */
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) {
+ GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int);
+ const ShaderInput *block = this->ubo_get(builtin_uniform_block_name(u));
+ builtin_blocks_[u] = (block != NULL) ? block->binding : -1;
+ }
+
+ MEM_freeN(uniforms_from_blocks);
+
+ /* Resize name buffer to save some memory. */
+ if (name_buffer_offset < name_buffer_len) {
+ name_buffer_ = (char *)MEM_reallocN(name_buffer_, name_buffer_offset);
+ }
+
+ // this->debug_print();
+
+ this->sort_inputs();
+}
+
+GLShaderInterface::~GLShaderInterface()
+{
+ for (auto *ref : refs_) {
+ if (ref != NULL) {
+ ref->remove(this);
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Batch Reference
+ * \{ */
+
+void GLShaderInterface::ref_add(GLVaoCache *ref)
+{
+ for (int i = 0; i < refs_.size(); i++) {
+ if (refs_[i] == NULL) {
+ refs_[i] = ref;
+ return;
+ }
+ }
+ refs_.append(ref);
+}
+
+void GLShaderInterface::ref_remove(GLVaoCache *ref)
+{
+ for (int i = 0; i < refs_.size(); i++) {
+ if (refs_[i] == ref) {
+ refs_[i] = NULL;
+ break; /* cannot have duplicates */
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Validation
+ * TODO
+ * \{ */
+
+/** \} */
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/opengl/gl_shader_interface.hh b/source/blender/gpu/opengl/gl_shader_interface.hh
new file mode 100644
index 00000000000..fdf9512ef79
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_shader_interface.hh
@@ -0,0 +1,60 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * GPU shader interface (C --> GLSL)
+ *
+ * Structure detailling needed vertex inputs and resources for a specific shader.
+ * A shader interface can be shared between two similar shaders.
+ */
+
+#pragma once
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_vector.hh"
+
+#include "glew-mx.h"
+
+#include "gpu_shader_interface.hh"
+
+namespace blender::gpu {
+
+class GLVaoCache;
+
+class GLShaderInterface : public ShaderInterface {
+ private:
+ /** Reference to VaoCaches using this interface */
+ Vector<GLVaoCache *> refs_;
+
+ public:
+ GLShaderInterface(GLuint program);
+ ~GLShaderInterface();
+
+ void ref_add(GLVaoCache *ref);
+ void ref_remove(GLVaoCache *ref);
+
+ // bool resource_binding_validate();
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("GLShaderInterface");
+};
+
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc
index 907dc37e46f..b2d2445f113 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.cc
+++ b/source/blender/gpu/opengl/gl_vertex_array.cc
@@ -23,9 +23,9 @@
#include "GPU_glew.h"
-#include "GPU_shader_interface.h"
#include "GPU_vertex_buffer.h"
+#include "gpu_shader_interface.hh"
#include "gpu_vertex_format_private.h"
#include "gl_batch.hh"
@@ -33,14 +33,14 @@
#include "gl_vertex_array.hh"
-using namespace blender::gpu;
+namespace blender::gpu {
/* -------------------------------------------------------------------- */
/** \name Vertex Array Bindings
* \{ */
/* Returns enabled vertex pointers as a bitflag (one bit per attrib). */
-static uint16_t vbo_bind(const GPUShaderInterface *interface,
+static uint16_t vbo_bind(const ShaderInterface *interface,
const GPUVertFormat *format,
uint v_first,
uint v_len,
@@ -68,7 +68,7 @@ static uint16_t vbo_bind(const GPUShaderInterface *interface,
for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
- const GPUShaderInput *input = GPU_shaderinterface_attr(interface, name);
+ const ShaderInput *input = interface->attr_get(name);
if (input == NULL) {
continue;
@@ -111,10 +111,10 @@ static uint16_t vbo_bind(const GPUShaderInterface *interface,
/* Update the Attrib Binding of the currently bound VAO. */
void GLVertArray::update_bindings(const GLuint vao,
const GPUBatch *batch,
- const GPUShaderInterface *interface,
+ const ShaderInterface *interface,
const int base_instance)
{
- uint16_t attr_mask = interface->enabled_attr_mask;
+ uint16_t attr_mask = interface->enabled_attr_mask_;
glBindVertexArray(vao);
@@ -156,3 +156,5 @@ void GLVertArray::update_bindings(const GLuint vao,
}
/** \} */
+
+} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/opengl/gl_vertex_array.hh b/source/blender/gpu/opengl/gl_vertex_array.hh
index 6da414d7e62..59cd50ad7b8 100644
--- a/source/blender/gpu/opengl/gl_vertex_array.hh
+++ b/source/blender/gpu/opengl/gl_vertex_array.hh
@@ -26,7 +26,7 @@
#include "glew-mx.h"
#include "GPU_batch.h"
-#include "GPU_shader_interface.h"
+#include "gl_shader_interface.hh"
namespace blender {
namespace gpu {
@@ -35,7 +35,7 @@ namespace GLVertArray {
void update_bindings(const GLuint vao,
const GPUBatch *batch,
- const GPUShaderInterface *interface,
+ const ShaderInterface *interface,
const int base_instance);
} // namespace GLVertArray
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index feda4ba43eb..e16a22f5459 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -686,10 +686,6 @@ typedef enum IDRecalcFlag {
ID_RECALC_PARAMETERS = (1 << 21),
- /* Makes it so everything what depends on time.
- * Basically, the same what changing frame in a timeline will do. */
- ID_RECALC_TIME = (1 << 22),
-
/* Input has changed and datablock is to be reload from disk.
* Applies to movie clips to inform that copy-on-written version is to be refreshed for the new
* input file or for color space changes. */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 3ec7963a81e..ec1a77c9520 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1883,11 +1883,10 @@ static void object_simplify_update(Object *ob)
}
if (ob->instance_collection) {
- CollectionObject *cob;
-
- for (cob = ob->instance_collection->gobject.first; cob; cob = cob->next) {
- object_simplify_update(cob->ob);
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (ob->instance_collection, ob_collection) {
+ object_simplify_update(ob_collection);
}
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index a387ba31c84..d0676ec1947 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -228,7 +228,7 @@ static int bpy_slot_from_py(BMesh *bm,
break;
}
case BMO_OP_SLOT_FLT: {
- float param = PyFloat_AsDouble(value);
+ const float param = PyFloat_AsDouble(value);
if (param == -1 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" expected a float, not %.200s",
@@ -840,7 +840,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
{
char slot_name_strip[MAX_SLOTNAME];
const char *ch = strchr(slot->slot_name, '.'); /* can't fail! */
- int tot = ch - slot->slot_name;
+ const int tot = ch - slot->slot_name;
BLI_assert(ch != NULL);
memcpy(slot_name_strip, slot->slot_name, tot);
slot_name_strip[tot] = '\0';
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 04bceb17c20..2b174de7136 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1093,7 +1093,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
bool use_deform = true;
bool use_cage = false;
bool use_fnorm = true;
- CustomData_MeshMasks data_masks = CD_MASK_BMESH;
+ const CustomData_MeshMasks data_masks = CD_MASK_BMESH;
BPY_BM_CHECK_OBJ(self);
@@ -1346,7 +1346,7 @@ static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject
}
}
else {
- char filter_flags_ch = (char)filter_flags;
+ const char filter_flags_ch = (char)filter_flags;
BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, filter_flags_ch)) {
mul_m4_v3((float(*)[4])mat_ptr, eve->co);
@@ -3222,7 +3222,7 @@ static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
{
/* don't need error check here */
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -3255,7 +3255,7 @@ static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
if (start < 0 || stop < 0) {
/* only get the length for negative values */
- Py_ssize_t len = bpy_bmelemseq_length(self);
+ const Py_ssize_t len = bpy_bmelemseq_length(self);
if (start < 0) {
start += len;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 51616030d30..a9a9a3ad5d9 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -714,7 +714,7 @@ static PyObject *bpy_bmlayercollection_subscript_slice(BPy_BMLayerCollection *se
Py_ssize_t start,
Py_ssize_t stop)
{
- Py_ssize_t len = bpy_bmlayercollection_length(self);
+ const Py_ssize_t len = bpy_bmlayercollection_length(self);
int count = 0;
PyObject *tuple;
@@ -746,7 +746,7 @@ static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, Py
return bpy_bmlayercollection_subscript_str(self, _PyUnicode_AsString(key));
}
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -779,7 +779,7 @@ static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, Py
if (start < 0 || stop < 0) {
/* only get the length for negative values */
- Py_ssize_t len = bpy_bmlayercollection_length(self);
+ const Py_ssize_t len = bpy_bmlayercollection_length(self);
if (start < 0) {
start += len;
}
@@ -1127,7 +1127,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
}
case CD_PROP_FLOAT:
case CD_PAINT_MASK: {
- float tmp_val = PyFloat_AsDouble(py_value);
+ const float tmp_val = PyFloat_AsDouble(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
PyErr_Format(
PyExc_TypeError, "expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
@@ -1140,7 +1140,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
}
case CD_PROP_INT32:
case CD_FACEMAP: {
- int tmp_val = PyC_Long_AsI32(py_value);
+ const int tmp_val = PyC_Long_AsI32(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
/* error is set */
ret = -1;
@@ -1187,7 +1187,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
break;
}
case CD_BWEIGHT: {
- float tmp_val = PyFloat_AsDouble(py_value);
+ const float tmp_val = PyFloat_AsDouble(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
PyErr_Format(
PyExc_TypeError, "expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
@@ -1199,7 +1199,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
break;
}
case CD_CREASE: {
- float tmp_val = PyFloat_AsDouble(py_value);
+ const float tmp_val = PyFloat_AsDouble(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
PyErr_Format(
PyExc_TypeError, "expected a float, not a %.200s", Py_TYPE(py_value)->tp_name);
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index d69668341ff..9bb9815f731 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -246,7 +246,7 @@ static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *self, PyObject *ke
{
/* don't need error check here */
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -279,7 +279,7 @@ static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *self, PyObject *ke
if (start < 0 || stop < 0) {
/* only get the length for negative values */
- Py_ssize_t len = bpy_bmeditselseq_length(self);
+ const Py_ssize_t len = bpy_bmeditselseq_length(self);
if (start < 0) {
start += len;
}
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 405541554c9..89fe9f8c6aa 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -461,7 +461,7 @@ int BGL_typeSize(int type)
static int gl_buffer_type_from_py_buffer(Py_buffer *pybuffer)
{
const char format = PyC_StructFmt_type_from_str(pybuffer->format);
- Py_ssize_t itemsize = pybuffer->itemsize;
+ const Py_ssize_t itemsize = pybuffer->itemsize;
if (PyC_StructFmt_type_is_float_any(format)) {
if (itemsize == 4) {
@@ -705,7 +705,7 @@ static int BGL_BufferOrOffsetConverter(PyObject *object, BufferOrOffset *buffer)
return 1;
}
if (PyNumber_Check(object)) {
- Py_ssize_t offset = PyNumber_AsSsize_t(object, PyExc_IndexError);
+ const Py_ssize_t offset = PyNumber_AsSsize_t(object, PyExc_IndexError);
if (offset == -1 && PyErr_Occurred()) {
return 0;
}
@@ -907,7 +907,7 @@ static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
Buffer *row = (Buffer *)Buffer_item(self, i);
if (row) {
- int ret = Buffer_ass_slice(row, 0, self->dimensions[1], v);
+ const int ret = Buffer_ass_slice(row, 0, self->dimensions[1], v);
Py_DECREF(row);
return ret;
}
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 615ce514a3e..314a34e3dec 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -435,7 +435,7 @@ static IDProperty *idp_from_PyBytes(const char *name, PyObject *ob)
static int idp_array_type_from_formatstr_and_size(const char *typestr, Py_ssize_t itemsize)
{
- char format = PyC_StructFmt_type_from_str(typestr);
+ const char format = PyC_StructFmt_type_from_str(typestr);
if (PyC_StructFmt_type_is_float_any(format)) {
if (itemsize == 4) {
@@ -473,7 +473,7 @@ static IDProperty *idp_from_PySequence_Buffer(const char *name, Py_buffer *buffe
IDProperty *prop;
IDPropertyTemplate val = {0};
- int id_type = idp_array_type_from_formatstr_and_size(buffer->format, buffer->itemsize);
+ const int id_type = idp_array_type_from_formatstr_and_size(buffer->format, buffer->itemsize);
if (id_type == -1) {
/* should never happen as the type has been checked before */
return NULL;
@@ -560,7 +560,7 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob)
if (PyObject_CheckBuffer(ob)) {
PyObject_GetBuffer(ob, &buffer, PyBUF_SIMPLE | PyBUF_FORMAT);
- char format = PyC_StructFmt_type_from_str(buffer.format);
+ const char format = PyC_StructFmt_type_from_str(buffer.format);
if (PyC_StructFmt_type_is_float_any(format) ||
(PyC_StructFmt_type_is_int_any(format) && buffer.itemsize == 4)) {
use_buffer = true;
@@ -589,7 +589,7 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob)
static IDProperty *idp_from_PyMapping(const char *name, PyObject *ob)
{
IDProperty *prop;
- IDPropertyTemplate val = {0};
+ const IDPropertyTemplate val = {0};
PyObject *keys, *vals, *key, *pval;
int i, len;
@@ -1559,8 +1559,8 @@ static int itemsize_by_idarray_type(int array_type)
static int BPy_IDArray_getbuffer(BPy_IDArray *self, Py_buffer *view, int flags)
{
IDProperty *prop = self->prop;
- int itemsize = itemsize_by_idarray_type(prop->subtype);
- int length = itemsize * prop->len;
+ const int itemsize = itemsize_by_idarray_type(prop->subtype);
+ const int length = itemsize * prop->len;
if (PyBuffer_FillInfo(view, (PyObject *)self, IDP_Array(prop), length, false, flags) == -1) {
return -1;
diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c
index 3536236754e..5dc4aa6ce7c 100644
--- a/source/blender/python/generic/imbuf_py_api.c
+++ b/source/blender/python/generic/imbuf_py_api.c
@@ -260,7 +260,7 @@ static int py_imbuf_filepath_set(Py_ImBuf *self, PyObject *value, void *UNUSED(c
}
ImBuf *ibuf = self->ibuf;
- Py_ssize_t value_str_len_max = sizeof(ibuf->name);
+ const Py_ssize_t value_str_len_max = sizeof(ibuf->name);
Py_ssize_t value_str_len;
const char *value_str = _PyUnicode_AsStringAndSize(value, &value_str_len);
if (value_str_len >= value_str_len_max) {
@@ -425,8 +425,8 @@ static PyObject *M_imbuf_new(PyObject *UNUSED(self), PyObject *args, PyObject *k
}
/* TODO, make options */
- uchar planes = 4;
- uint flags = IB_rect;
+ const uchar planes = 4;
+ const uint flags = IB_rect;
ImBuf *ibuf = IMB_allocImBuf(UNPACK2(size), planes, flags);
if (ibuf == NULL) {
@@ -500,7 +500,7 @@ static PyObject *M_imbuf_write(PyObject *UNUSED(self), PyObject *args, PyObject
filepath = py_imb->ibuf->name;
}
- bool ok = IMB_saveiff(py_imb->ibuf, filepath, IB_rect);
+ const bool ok = IMB_saveiff(py_imb->ibuf, filepath, IB_rect);
if (ok == false) {
PyErr_Format(
PyExc_IOError, "write: Unable to write image file (%s) '%s'", strerror(errno), filepath);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 838a1239210..195442d34f6 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -207,7 +207,7 @@ PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
*/
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
{
- uint tot = PyTuple_GET_SIZE(tuple);
+ const uint tot = PyTuple_GET_SIZE(tuple);
uint i;
for (i = 0; i < tot; i++) {
@@ -218,7 +218,7 @@ void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
void PyC_List_Fill(PyObject *list, PyObject *value)
{
- uint tot = PyList_GET_SIZE(list);
+ const uint tot = PyList_GET_SIZE(list);
uint i;
for (i = 0; i < tot; i++) {
@@ -377,7 +377,7 @@ void PyC_StackSpit(void)
}
/* lame but handy */
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
PyRun_SimpleString("__import__('traceback').print_stack()");
PyGILState_Release(gilstate);
}
@@ -948,7 +948,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
FILE *fp = fopen(filepath, "r");
if (fp) {
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
va_list vargs;
@@ -1423,7 +1423,7 @@ bool PyC_RunString_AsString(const char *imports[],
*/
int PyC_Long_AsBool(PyObject *value)
{
- int test = _PyLong_AsInt(value);
+ const int test = _PyLong_AsInt(value);
if (UNLIKELY((uint)test > 1)) {
PyErr_SetString(PyExc_TypeError, "Python number not a bool (0/1)");
return -1;
@@ -1433,7 +1433,7 @@ int PyC_Long_AsBool(PyObject *value)
int8_t PyC_Long_AsI8(PyObject *value)
{
- int test = _PyLong_AsInt(value);
+ const int test = _PyLong_AsInt(value);
if (UNLIKELY(test < INT8_MIN || test > INT8_MAX)) {
PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int8");
return -1;
@@ -1443,7 +1443,7 @@ int8_t PyC_Long_AsI8(PyObject *value)
int16_t PyC_Long_AsI16(PyObject *value)
{
- int test = _PyLong_AsInt(value);
+ const int test = _PyLong_AsInt(value);
if (UNLIKELY(test < INT16_MIN || test > INT16_MAX)) {
PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int16");
return -1;
@@ -1458,7 +1458,7 @@ int16_t PyC_Long_AsI16(PyObject *value)
uint8_t PyC_Long_AsU8(PyObject *value)
{
- ulong test = PyLong_AsUnsignedLong(value);
+ const ulong test = PyLong_AsUnsignedLong(value);
if (UNLIKELY(test > UINT8_MAX)) {
PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint8");
return (uint8_t)-1;
@@ -1468,7 +1468,7 @@ uint8_t PyC_Long_AsU8(PyObject *value)
uint16_t PyC_Long_AsU16(PyObject *value)
{
- ulong test = PyLong_AsUnsignedLong(value);
+ const ulong test = PyLong_AsUnsignedLong(value);
if (UNLIKELY(test > UINT16_MAX)) {
PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint16");
return (uint16_t)-1;
@@ -1478,7 +1478,7 @@ uint16_t PyC_Long_AsU16(PyObject *value)
uint32_t PyC_Long_AsU32(PyObject *value)
{
- ulong test = PyLong_AsUnsignedLong(value);
+ const ulong test = PyLong_AsUnsignedLong(value);
if (UNLIKELY(test > UINT32_MAX)) {
PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C uint32");
return (uint32_t)-1;
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index c1a6ce09d37..f9ff0558570 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -78,7 +78,7 @@ static int bpygpu_uniform_location_get(GPUShader *shader,
const char *name,
const char *error_prefix)
{
- int uniform = GPU_shader_get_uniform(shader, name);
+ const int uniform = GPU_shader_get_uniform(shader, name);
if (uniform == -1) {
PyErr_Format(PyExc_ValueError, "%s: uniform %.32s not found", error_prefix, name);
@@ -158,7 +158,7 @@ static PyObject *bpygpu_shader_uniform_from_name(BPyGPUShader *self, PyObject *a
return NULL;
}
- int uniform = bpygpu_uniform_location_get(self->shader, name, "GPUShader.get_uniform");
+ const int uniform = bpygpu_uniform_location_get(self->shader, name, "GPUShader.get_uniform");
if (uniform == -1) {
return NULL;
@@ -184,7 +184,7 @@ static PyObject *bpygpu_shader_uniform_block_from_name(BPyGPUShader *self, PyObj
return NULL;
}
- int uniform = GPU_shader_get_uniform_block(self->shader, name);
+ const int uniform = GPU_shader_get_uniform_block(self->shader, name);
if (uniform == -1) {
PyErr_Format(PyExc_ValueError, "GPUShader.get_uniform_block: uniform %.32s not found", name);
@@ -504,7 +504,7 @@ static PyObject *bpygpu_shader_attr_from_name(BPyGPUShader *self, PyObject *arg)
return NULL;
}
- int attr = GPU_shader_get_attribute(self->shader, name);
+ const int attr = GPU_shader_get_attribute(self->shader, name);
if (attr == -1) {
PyErr_Format(PyExc_ValueError, "GPUShader.attr_from_name: attribute %.32s not found", name);
diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.c b/source/blender/python/gpu/gpu_py_vertex_buffer.c
index 57290fdc3c4..9372770e45e 100644
--- a/source/blender/python/gpu/gpu_py_vertex_buffer.c
+++ b/source/blender/python/gpu/gpu_py_vertex_buffer.c
@@ -134,7 +134,7 @@ static bool bpygpu_vertbuf_fill_impl(GPUVertBuf *vbo,
return false;
}
- uint comp_len = pybuffer.ndim == 1 ? 1 : (uint)pybuffer.shape[1];
+ const uint comp_len = pybuffer.ndim == 1 ? 1 : (uint)pybuffer.shape[1];
if (pybuffer.shape[0] != vbo->vertex_len) {
PyErr_Format(
diff --git a/source/blender/python/gpu/gpu_py_vertex_format.c b/source/blender/python/gpu/gpu_py_vertex_format.c
index d8266be7e2c..1cbcaba6bfb 100644
--- a/source/blender/python/gpu/gpu_py_vertex_format.c
+++ b/source/blender/python/gpu/gpu_py_vertex_format.c
@@ -112,7 +112,7 @@ static int bpygpu_ParseVertCompType(PyObject *o, void *p)
return 0;
}
- int comp_type = bpygpu_parse_component_type(str, length);
+ const int comp_type = bpygpu_parse_component_type(str, length);
if (comp_type == -1) {
PyErr_Format(PyExc_ValueError, "unknown component type: '%s", str);
return 0;
@@ -132,7 +132,7 @@ static int bpygpu_ParseVertFetchMode(PyObject *o, void *p)
return 0;
}
- int fetch_mode = bpygpu_parse_fetch_mode(str, length);
+ const int fetch_mode = bpygpu_parse_fetch_mode(str, length);
if (fetch_mode == -1) {
PyErr_Format(PyExc_ValueError, "unknown type literal: '%s'", str);
return 0;
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 4ee936aff91..f0de05f95b3 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -343,7 +343,7 @@ static PyObject *bpy_app_debug_value_get(PyObject *UNUSED(self), void *UNUSED(cl
static int bpy_app_debug_value_set(PyObject *UNUSED(self), PyObject *value, void *UNUSED(closure))
{
- short param = PyC_Long_AsI16(value);
+ const short param = PyC_Long_AsI16(value);
if (param == -1 && PyErr_Occurred()) {
PyC_Err_SetString_Prefix(PyExc_TypeError,
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index cdbd3bc0b9c..a874e23ff32 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -318,7 +318,7 @@ void bpy_app_generic_callback(struct Main *UNUSED(main),
{
PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)];
if (PyList_GET_SIZE(cb_list) > 0) {
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
const int num_arguments = 2;
PyObject *args_all = PyTuple_New(num_arguments); /* save python creating each call */
diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c
index 2e688609961..7cca3ae4700 100644
--- a/source/blender/python/intern/bpy_app_icons.c
+++ b/source/blender/python/intern/bpy_app_icons.c
@@ -71,8 +71,8 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
return NULL;
}
- int coords_size = sizeof(uchar[2]) * tris_len * 3;
- int colors_size = sizeof(uchar[4]) * tris_len * 3;
+ const int coords_size = sizeof(uchar[2]) * tris_len * 3;
+ const int colors_size = sizeof(uchar[4]) * tris_len * 3;
uchar(*coords)[2] = MEM_mallocN(coords_size, __func__);
uchar(*colors)[4] = MEM_mallocN(colors_size, __func__);
@@ -86,7 +86,7 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
geom->coords = coords;
geom->colors = colors;
geom->icon_id = 0;
- int icon_id = BKE_icon_geom_ensure(geom);
+ const int icon_id = BKE_icon_geom_ensure(geom);
return PyLong_FromLong(icon_id);
}
@@ -117,7 +117,7 @@ static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self),
PyErr_SetString(PyExc_ValueError, "Unable to load from file");
return NULL;
}
- int icon_id = BKE_icon_geom_ensure(geom);
+ const int icon_id = BKE_icon_geom_ensure(geom);
return PyLong_FromLong(icon_id);
}
diff --git a/source/blender/python/intern/bpy_app_opensubdiv.c b/source/blender/python/intern/bpy_app_opensubdiv.c
index 3f14c4dca57..09cd6201831 100644
--- a/source/blender/python/intern/bpy_app_opensubdiv.c
+++ b/source/blender/python/intern/bpy_app_opensubdiv.c
@@ -63,7 +63,7 @@ static PyObject *make_opensubdiv_info(void)
#define SetObjItem(obj) PyStructSequence_SET_ITEM(opensubdiv_info, pos++, obj)
#ifdef WITH_OPENSUBDIV
- int curversion = openSubdiv_getVersionHex();
+ const int curversion = openSubdiv_getVersionHex();
SetObjItem(PyBool_FromLong(1));
SetObjItem(PyC_Tuple_Pack_I32(curversion / 10000, (curversion / 100) % 100, curversion % 100));
SetObjItem(PyUnicode_FromFormat(
diff --git a/source/blender/python/intern/bpy_app_timers.c b/source/blender/python/intern/bpy_app_timers.c
index f1dd8b9e803..af299952b72 100644
--- a/source/blender/python/intern/bpy_app_timers.c
+++ b/source/blender/python/intern/bpy_app_timers.c
@@ -65,7 +65,7 @@ static double py_timer_execute(uintptr_t UNUSED(uuid), void *user_data)
gilstate = PyGILState_Ensure();
PyObject *py_ret = PyObject_CallObject(function, NULL);
- double ret = handle_returned_value(function, py_ret);
+ const double ret = handle_returned_value(function, py_ret);
PyGILState_Release(gilstate);
@@ -151,7 +151,7 @@ PyDoc_STRVAR(bpy_app_timers_is_registered_doc,
" :rtype: bool\n");
static PyObject *bpy_app_timers_is_registered(PyObject *UNUSED(self), PyObject *function)
{
- bool ret = BLI_timer_is_registered((intptr_t)function);
+ const bool ret = BLI_timer_is_registered((intptr_t)function);
return PyBool_FromLong(ret);
}
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index c152c920453..f95261df6b2 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -92,7 +92,7 @@ static GHashKey *_ghashutil_keyalloc(const void *msgctxt, const void *msgid)
static uint _ghashutil_keyhash(const void *ptr)
{
const GHashKey *key = ptr;
- uint hash = BLI_ghashutil_strhash(key->msgctxt);
+ const uint hash = BLI_ghashutil_strhash(key->msgctxt);
return hash ^ BLI_ghashutil_strhash(key->msgid);
}
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 7fb4b0c469c..4ef685b7987 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -228,7 +228,7 @@ static void bpy_pydriver_namespace_clear_self(void)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
- bool use_gil = true; /* !PyC_IsInterpreterActive(); */
+ const bool use_gil = true; /* !PyC_IsInterpreterActive(); */
if (use_gil) {
gilstate = PyGILState_Ensure();
@@ -594,7 +594,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
#endif
{
/* try to get variable value */
- float tval = driver_get_variable_value(driver, dvar);
+ const float tval = driver_get_variable_value(driver, dvar);
driver_arg = PyFloat_FromDouble((double)tval);
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index b0b36baa839..bc7318e1a15 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -169,7 +169,7 @@ void BPY_text_free_code(Text *text)
{
if (text->compiled) {
PyGILState_STATE gilstate;
- bool use_gil = !PyC_IsInterpreterActive();
+ const bool use_gil = !PyC_IsInterpreterActive();
if (use_gil) {
gilstate = PyGILState_Ensure();
@@ -446,14 +446,14 @@ void BPY_python_backtrace(FILE *fp)
void BPY_DECREF(void *pyob_ptr)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
Py_DECREF((PyObject *)pyob_ptr);
PyGILState_Release(gilstate);
}
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
const int do_invalidate = (Py_REFCNT((PyObject *)pyob_ptr) > 1);
Py_DECREF((PyObject *)pyob_ptr);
if (do_invalidate) {
@@ -509,7 +509,7 @@ void BPY_modules_load_user(bContext *C)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
{
PyGILState_STATE gilstate;
- bool use_gil = !PyC_IsInterpreterActive();
+ const bool use_gil = !PyC_IsInterpreterActive();
PyObject *pyctx;
PyObject *item;
@@ -544,7 +544,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
PyErr_Clear();
}
else {
- int len = PySequence_Fast_GET_SIZE(seq_fast);
+ const int len = PySequence_Fast_GET_SIZE(seq_fast);
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
int i;
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index bcf13b1d88f..bdad4d03ae7 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -321,7 +321,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
{
Main *bmain = CTX_data_main(BPy_GetContext());
Main *mainl = NULL;
- int err = 0;
+ const int err = 0;
const bool do_append = ((self->flag & FILE_LINK) == 0);
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
@@ -338,7 +338,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
// printf("lib: %s\n", name_plural);
if (ls && PyList_Check(ls)) {
/* loop */
- Py_ssize_t size = PyList_GET_SIZE(ls);
+ const Py_ssize_t size = PyList_GET_SIZE(ls);
Py_ssize_t i;
for (i = 0; i < size; i++) {
@@ -423,7 +423,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
const char *name_plural = BKE_idtype_idcode_to_name_plural(idcode);
PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
if (ls && PyList_Check(ls)) {
- Py_ssize_t size = PyList_GET_SIZE(ls);
+ const Py_ssize_t size = PyList_GET_SIZE(ls);
Py_ssize_t i;
PyObject *item;
diff --git a/source/blender/python/intern/bpy_msgbus.c b/source/blender/python/intern/bpy_msgbus.c
index 45c5aba1e3e..3739f56dc79 100644
--- a/source/blender/python/intern/bpy_msgbus.c
+++ b/source/blender/python/intern/bpy_msgbus.c
@@ -192,7 +192,7 @@ static void bpy_msgbus_notify(bContext *C,
static void bpy_msgbus_subscribe_value_free_data(struct wmMsgSubscribeKey *UNUSED(msg_key),
struct wmMsgSubscribeValue *msg_val)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
Py_DECREF(msg_val->owner);
Py_DECREF(msg_val->user_data);
PyGILState_Release(gilstate);
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 66c67ca061c..859f0027f14 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -351,7 +351,7 @@ static bool bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *
value = false;
}
else {
- int value_i = PyC_Long_AsBool(ret);
+ const int value_i = PyC_Long_AsBool(ret);
if (value_i == -1 && PyErr_Occurred()) {
PyC_Err_PrintWithFunc(py_func);
@@ -443,7 +443,7 @@ static bool bpy_prop_poll_cb(struct PointerRNA *self,
PyObject *ret;
bool result;
const int is_write_ok = pyrna_write_check();
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
BLI_assert(self != NULL);
@@ -560,7 +560,7 @@ static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr,
PyGILState_STATE gilstate;
bool use_gil;
const bool is_write_ok = pyrna_write_check();
- int len = RNA_property_array_length(ptr, prop);
+ const int len = RNA_property_array_length(ptr, prop);
BLI_assert(py_data != NULL);
@@ -804,7 +804,7 @@ static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr,
PyGILState_STATE gilstate;
bool use_gil;
const bool is_write_ok = pyrna_write_check();
- int len = RNA_property_array_length(ptr, prop);
+ const int len = RNA_property_array_length(ptr, prop);
BLI_assert(py_data != NULL);
@@ -1048,7 +1048,7 @@ static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr,
PyGILState_STATE gilstate;
bool use_gil;
const bool is_write_ok = pyrna_write_check();
- int len = RNA_property_array_length(ptr, prop);
+ const int len = RNA_property_array_length(ptr, prop);
BLI_assert(py_data != NULL);
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 955a24bc880..a3ded8813ac 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -464,7 +464,7 @@ static int mathutils_rna_vector_set(BaseMathObject *bmo, int subtype)
if (subtype == MATHUTILS_CB_SUBTYPE_EUL) {
EulerObject *eul = (EulerObject *)bmo;
PropertyRNA *prop_eul_order = NULL;
- short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
+ const short order = pyrna_rotation_euler_order_get(&self->ptr, eul->order, &prop_eul_order);
if (order != eul->order) {
RNA_property_enum_set(&self->ptr, prop_eul_order, eul->order);
if (RNA_property_update_check(prop_eul_order)) {
@@ -599,7 +599,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr,
}
if (*r_prop_eul_order) {
- short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
+ const short order = RNA_property_enum_get(ptr, *r_prop_eul_order);
/* Could be quat or axisangle. */
if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) {
return order;
@@ -714,7 +714,8 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
/* Attempt to get order,
* only needed for thick types since wrapped with update via callbacks. */
PropertyRNA *prop_eul_order = NULL;
- short order = pyrna_rotation_euler_order_get(ptr, EULER_ORDER_XYZ, &prop_eul_order);
+ const short order = pyrna_rotation_euler_order_get(
+ ptr, EULER_ORDER_XYZ, &prop_eul_order);
ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA. */
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
@@ -1725,7 +1726,7 @@ static int pyrna_py_to_prop(
}
case PROP_INT: {
int overflow;
- long param = PyLong_AsLongAndOverflow(value, &overflow);
+ const long param = PyLong_AsLongAndOverflow(value, &overflow);
if (overflow || (param > INT_MAX) || (param < INT_MIN)) {
PyErr_Format(PyExc_ValueError,
"%.200s %.200s.%.200s value not in 'int' range "
@@ -1757,7 +1758,7 @@ static int pyrna_py_to_prop(
break;
}
case PROP_FLOAT: {
- float param = PyFloat_AsDouble(value);
+ const float param = PyFloat_AsDouble(value);
if (PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s expected a float type, not %.200s",
@@ -1935,8 +1936,8 @@ static int pyrna_py_to_prop(
PyObject *value_new = NULL;
StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop);
- int flag = RNA_property_flag(prop);
- int flag_parameter = RNA_parameter_flag(prop);
+ const int flag = RNA_property_flag(prop);
+ const int flag_parameter = RNA_parameter_flag(prop);
/* This is really nasty! Done so we can fake the operator having direct properties, eg:
* layout.prop(self, "filepath")
@@ -2075,7 +2076,7 @@ static int pyrna_py_to_prop(
BKE_reports_init(&reports, RPT_STORE);
RNA_property_pointer_set(
ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports);
- int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
+ const int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
if (err == -1) {
Py_XDECREF(value_new);
return -1;
@@ -2233,7 +2234,7 @@ static int pyrna_py_to_prop_array_index(BPy_PropertyArrayRNA *self, int index, P
/* See if we can coerce into a Python type - 'PropertyType'. */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN: {
- int param = PyC_Long_AsBool(value);
+ const int param = PyC_Long_AsBool(value);
if (param == -1) {
/* Error is set. */
@@ -2698,7 +2699,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
}
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -2732,7 +2733,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
if (start < 0 || stop < 0) {
/* Only get the length for negative values. */
- Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
+ const Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
if (start < 0) {
start += len;
}
@@ -2827,7 +2828,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
else
#endif
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return -1;
}
@@ -2899,7 +2900,7 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
else
#endif
if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -2919,11 +2920,11 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
if (key_slice->start == Py_None && key_slice->stop == Py_None) {
/* Note: no significant advantage with optimizing [:] slice as with collections,
* but include here for consistency with collection slice func */
- Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
+ const Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
- int len = pyrna_prop_array_length(self);
+ const int len = pyrna_prop_array_length(self);
Py_ssize_t start, stop, slicelength;
if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
@@ -3055,7 +3056,7 @@ static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items
BLI_assert(totdim == 1);
int i;
for (i = 0; i != length; i++) {
- int v = PyLong_AsLong(value_items[i]);
+ const int v = PyLong_AsLong(value_items[i]);
value[i] = v;
}
return i;
@@ -3097,7 +3098,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr,
}
int dimsize[3];
- int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
+ const int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
if (totdim > 1) {
BLI_assert(dimsize[arraydim] == length);
}
@@ -3247,7 +3248,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
}
else if (PyIndex_Check(key)) {
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+ const Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
ret = -1;
}
@@ -3256,7 +3257,7 @@ static int pyrna_prop_array_ass_subscript(BPy_PropertyArrayRNA *self,
}
}
else if (PySlice_Check(key)) {
- Py_ssize_t len = pyrna_prop_array_length(self);
+ const Py_ssize_t len = pyrna_prop_array_length(self);
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
@@ -4249,7 +4250,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
ListBase newlb;
short newtype;
- int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
+ const int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
if (done == 1) { /* Found. */
switch (newtype) {
@@ -4401,7 +4402,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb
if (value) {
/* Check if the value is a property. */
if (is_deferred_prop) {
- int ret = deferred_register_prop(srna, attr, value);
+ const int ret = deferred_register_prop(srna, attr, value);
if (ret == -1) {
/* Error set. */
return ret;
@@ -4471,7 +4472,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
ListBase newlb;
short newtype;
- int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
+ const int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
if (done == 1) {
PyErr_Format(
@@ -4646,7 +4647,7 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
{
- int key = PyLong_AsLong(value);
+ const int key = PyLong_AsLong(value);
#ifdef USE_PEDANTIC_WRITE
if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) {
@@ -5172,7 +5173,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self,
static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format)
{
- char f = format ? *format : 'B'; /* B is assumed when not set */
+ const char f = format ? *format : 'B'; /* B is assumed when not set */
switch (raw_type) {
case PROP_RAW_CHAR:
@@ -5400,7 +5401,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
PyObject *item = NULL;
Py_ssize_t i, seq_size, size;
void *array = NULL;
- PropertyType prop_type = RNA_property_type(self->prop);
+ const PropertyType prop_type = RNA_property_type(self->prop);
/* Get/set both take the same args currently. */
PyObject *seq;
@@ -5498,7 +5499,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self,
}
}
else {
- char f = buf.format ? buf.format[0] : 0;
+ const char f = buf.format ? buf.format[0] : 0;
if ((prop_type == PROP_INT && (buf.itemsize != sizeof(int) || (f != 'l' && f != 'i'))) ||
(prop_type == PROP_FLOAT && (buf.itemsize != sizeof(float) || f != 'f'))) {
PyBuffer_Release(&buf);
@@ -8030,7 +8031,7 @@ static int rna_function_arg_count(FunctionRNA *func, int *min_count)
const ListBase *lb = RNA_function_defined_parameters(func);
PropertyRNA *parm;
Link *link;
- int flag = RNA_function_flag(func);
+ const int flag = RNA_function_flag(func);
const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
int count = is_staticmethod ? 0 : 1;
bool done_min_count = false;
@@ -8273,7 +8274,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
ParameterIterator iter;
PointerRNA funcptr;
int err = 0, i, ret_len = 0, arg_count;
- int flag = RNA_function_flag(func);
+ const int flag = RNA_function_flag(func);
const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
const bool is_classmethod = (flag & FUNC_NO_SELF) && (flag & FUNC_USE_SELF_TYPE);
@@ -9015,7 +9016,7 @@ void pyrna_struct_type_extend_capi(struct StructRNA *srna,
py_method = PyCFunction_New(method, NULL);
}
- int err = PyDict_SetItemString(dict, method->ml_name, py_method);
+ const int err = PyDict_SetItemString(dict, method->ml_name, py_method);
Py_DECREF(py_method);
BLI_assert(!(err < 0));
UNUSED_VARS_NDEBUG(err);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index ae19f89c348..1d52706c5f9 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -131,7 +131,7 @@ static int pyrna_struct_anim_args_parse_ex(PointerRNA *ptr,
}
}
else {
- int array_len = RNA_property_array_length(&r_ptr, prop);
+ const int array_len = RNA_property_array_length(&r_ptr, prop);
if ((*r_index) < -1 || (*r_index) >= array_len) {
PyErr_Format(PyExc_TypeError,
"%.200s index out of range \"%s\", given %d, array length is %d",
@@ -316,7 +316,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
int index = -1;
float cfra = FLT_MAX;
const char *group_name = NULL;
- char keytype = BEZT_KEYTYPE_KEYFRAME; /* XXX: Expose this as a one-off option... */
+ const char keytype = BEZT_KEYTYPE_KEYFRAME; /* XXX: Expose this as a one-off option... */
int options = 0;
PYRNA_STRUCT_CHECK_OBJ(self);
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index 66e07d556a6..cb3fe9cb600 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -361,7 +361,7 @@ static int validate_array(PyObject *rvalue,
const char *error_prefix)
{
int dimsize[MAX_ARRAY_DIMENSION];
- int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
+ const int totdim = RNA_property_array_dimension(ptr, prop, dimsize);
/* validate type first because length validation may modify property array length */
@@ -466,7 +466,7 @@ static char *copy_values(PyObject *seq,
const ItemConvert_FuncArg *convert_item,
RNA_SetIndexFunc rna_set_index)
{
- int totdim = RNA_property_array_dimension(ptr, prop, NULL);
+ const int totdim = RNA_property_array_dimension(ptr, prop, NULL);
const Py_ssize_t seq_size = PySequence_Size(seq);
Py_ssize_t i;
@@ -487,7 +487,7 @@ static char *copy_values(PyObject *seq,
if (dim == 0) {
if (MatrixObject_Check(seq)) {
MatrixObject *pymat = (MatrixObject *)seq;
- size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float);
+ const size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float);
/* read callback already done by validate */
/* since this is the first iteration we can assume data is allocated */
@@ -993,7 +993,7 @@ PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
/* TODO, multi-dimensional arrays */
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
{
- int len = RNA_property_array_length(ptr, prop);
+ const int len = RNA_property_array_length(ptr, prop);
int type;
int i;
@@ -1011,7 +1011,7 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
switch (type) {
case PROP_FLOAT: {
- float value_f = PyFloat_AsDouble(value);
+ const float value_f = PyFloat_AsDouble(value);
if (value_f == -1 && PyErr_Occurred()) {
PyErr_Clear();
return 0;
@@ -1044,7 +1044,7 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
break;
}
case PROP_INT: {
- int value_i = PyC_Long_AsI32(value);
+ const int value_i = PyC_Long_AsI32(value);
if (value_i == -1 && PyErr_Occurred()) {
PyErr_Clear();
return 0;
@@ -1077,7 +1077,7 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
break;
}
case PROP_BOOLEAN: {
- int value_i = PyC_Long_AsBool(value);
+ const int value_i = PyC_Long_AsBool(value);
if (value_i == -1 && PyErr_Occurred()) {
PyErr_Clear();
return 0;
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index 976b8a65ac7..2f8be0c44e0 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -84,7 +84,7 @@ static void cb_region_draw(const bContext *C, ARegion *UNUSED(region), void *cus
static PyObject *PyC_Tuple_CopySized(PyObject *src, int len_dst)
{
PyObject *dst = PyTuple_New(len_dst);
- int len_src = PyTuple_GET_SIZE(src);
+ const int len_src = PyTuple_GET_SIZE(src);
BLI_assert(len_src <= len_dst);
for (int i = 0; i < len_src; i++) {
PyObject *item = PyTuple_GET_ITEM(src, i);
diff --git a/source/blender/python/intern/bpy_rna_driver.c b/source/blender/python/intern/bpy_rna_driver.c
index 9240e34bbab..3bddd0ad8c0 100644
--- a/source/blender/python/intern/bpy_rna_driver.c
+++ b/source/blender/python/intern/bpy_rna_driver.c
@@ -57,7 +57,7 @@ PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct D
}
else {
/* object & property */
- PropertyType type = RNA_property_type(prop);
+ const PropertyType type = RNA_property_type(prop);
if (type == PROP_ENUM) {
/* Note that enum's are converted to strings by default,
* we want to avoid that, see: T52213 */
diff --git a/source/blender/python/intern/bpy_rna_gizmo.c b/source/blender/python/intern/bpy_rna_gizmo.c
index 4ef718ef023..575824e8a86 100644
--- a/source/blender/python/intern/bpy_rna_gizmo.c
+++ b/source/blender/python/intern/bpy_rna_gizmo.c
@@ -63,7 +63,7 @@ static void py_rna_gizmo_handler_get_cb(const wmGizmo *UNUSED(gz),
wmGizmoProperty *gz_prop,
void *value_p)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data;
PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_GIZMO_FN_SLOT_GET], NULL);
@@ -110,7 +110,7 @@ static void py_rna_gizmo_handler_set_cb(const wmGizmo *UNUSED(gz),
wmGizmoProperty *gz_prop,
const void *value_p)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data;
@@ -159,7 +159,7 @@ static void py_rna_gizmo_handler_range_get_cb(const wmGizmo *UNUSED(gz),
{
struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data;
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_GIZMO_FN_SLOT_RANGE_GET], NULL);
if (ret == NULL) {
@@ -211,7 +211,7 @@ static void py_rna_gizmo_handler_free_cb(const wmGizmo *UNUSED(gz), wmGizmoPrope
{
struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data;
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
for (int i = 0; i < BPY_GIZMO_FN_SLOT_LEN; i++) {
Py_XDECREF(data->fn_slots[i]);
}
@@ -234,7 +234,7 @@ PyDoc_STRVAR(
" :type range: callable\n");
static PyObject *bpy_gizmo_target_set_handler(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
{
- PyGILState_STATE gilstate = PyGILState_Ensure();
+ const PyGILState_STATE gilstate = PyGILState_Ensure();
struct {
PyObject *self;
@@ -368,7 +368,7 @@ static PyObject *bpy_gizmo_target_get_value(PyObject *UNUSED(self), PyObject *ar
return PyC_Tuple_PackArray_F32(value, array_len);
}
- float value = WM_gizmo_target_property_float_get(gz, gz_prop);
+ const float value = WM_gizmo_target_property_float_get(gz, gz_prop);
return PyFloat_FromDouble(value);
break;
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 308d2ef9618..ca38d7008f6 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -208,7 +208,7 @@ int mathutils_array_parse(
if (size != -1) {
if (flag & MU_ARRAY_ZERO) {
- int size_left = array_max - size;
+ const int size_left = array_max - size;
if (size_left) {
memset(&array[size], 0, sizeof(float) * size_left);
}
@@ -541,9 +541,9 @@ int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
{
/* solid, fast routine across all platforms
* with constant time behavior */
- int ai = *(int *)(&af);
- int bi = *(int *)(&bf);
- int test = SIGNMASK(ai ^ bi);
+ const int ai = *(int *)(&af);
+ const int bi = *(int *)(&bf);
+ const int test = SIGNMASK(ai ^ bi);
int diff, v1, v2;
assert((0 == test) || (0xFFFFFFFF == test));
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index 6bffff467cd..8a7f782de3c 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -749,7 +749,7 @@ PyDoc_STRVAR(Color_channel_hsv_v_doc, "HSV Value component in [0, 1].\n\n:type:
static PyObject *Color_channel_hsv_get(ColorObject *self, void *type)
{
float hsv[3];
- int i = POINTER_AS_INT(type);
+ const int i = POINTER_AS_INT(type);
if (BaseMath_ReadCallback(self) == -1) {
return NULL;
@@ -763,7 +763,7 @@ static PyObject *Color_channel_hsv_get(ColorObject *self, void *type)
static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
{
float hsv[3];
- int i = POINTER_AS_INT(type);
+ const int i = POINTER_AS_INT(type);
float f = PyFloat_AsDouble(value);
if (f == -1 && PyErr_Occurred()) {
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 236bb1de29d..0a524cbf24c 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -809,7 +809,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
else {
/* arbitrary plane */
- int vec_size = (matSize == 2 ? 2 : 3);
+ const int vec_size = (matSize == 2 ? 2 : 3);
float tvec[4];
if (mathutils_array_parse(tvec,
@@ -2156,7 +2156,8 @@ static PyObject *Matrix_str(MatrixObject *self)
for (col = 0; col < self->num_col; col++) {
maxsize[col] = 0;
for (row = 0; row < self->num_row; row++) {
- int size = BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
+ const int size = BLI_snprintf(
+ dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
maxsize[col] = max_ii(maxsize[col], size);
}
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 3ee6e766413..9bc8c0dffed 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -356,7 +356,7 @@ PyDoc_STRVAR(Vector_normalize_doc,
" however 4D Vectors w axis is left untouched.\n");
static PyObject *Vector_normalize(VectorObject *self)
{
- int size = (self->size == 4 ? 3 : self->size);
+ const int size = (self->size == 4 ? 3 : self->size);
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
return NULL;
}
@@ -2027,7 +2027,7 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
{
VectorObject *vecA = NULL, *vecB = NULL;
int result = 0;
- double epsilon = 0.000001f;
+ const double epsilon = 0.000001f;
double lenA, lenB;
if (!VectorObject_Check(objectA) || !VectorObject_Check(objectB)) {
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 16ea05771d0..1d477421e30 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -589,7 +589,7 @@ static PyObject *py_bvhtree_overlap(PyBVHTree *self, PyBVHTree *other)
/* pass */
}
else {
- bool use_unique = (self->orig_index || other->orig_index);
+ const bool use_unique = (self->orig_index || other->orig_index);
GSet *pair_test = use_unique ?
BLI_gset_new_ex(overlap_hash, overlap_cmp, __func__, overlap_len) :
NULL;
@@ -1037,7 +1037,7 @@ static Mesh *bvh_get_mesh(const char *funcname,
{
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
/* we only need minimum mesh data for topology and vertex locations */
- CustomData_MeshMasks data_masks = CD_MASK_BAREMESH;
+ const CustomData_MeshMasks data_masks = CD_MASK_BAREMESH;
const bool use_render = DEG_get_mode(depsgraph) == DAG_EVAL_RENDER;
*r_free_mesh = false;
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 37997e9f912..e89651e0671 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -315,7 +315,7 @@ static PyObject *M_Geometry_intersect_tri_tri_2d(PyObject *UNUSED(self), PyObjec
}
}
- bool ret = isect_tri_tri_v2(UNPACK3(tri_pair[0]), UNPACK3(tri_pair[1]));
+ const bool ret = isect_tri_tri_v2(UNPACK3(tri_pair[0]), UNPACK3(tri_pair[1]));
return PyBool_FromLong(ret);
}
@@ -492,7 +492,7 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec
PyObject *py_line_a, *py_line_b, *py_plane_co, *py_plane_no;
float line_a[3], line_b[3], plane_co[3], plane_no[3];
float isect[3];
- bool no_flip = false;
+ const bool no_flip = false;
if (!PyArg_ParseTuple(args,
"OOOO|O&:intersect_line_plane",
diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c
index c3e66546dae..1de3c23838f 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.c
+++ b/source/blender/python/mathutils/mathutils_kdtree.c
@@ -191,7 +191,7 @@ static int py_find_nearest_cb(void *user_data, int index, const float co[3], flo
if (result) {
bool use_node;
- int ok = PyC_ParseBool(result, &use_node);
+ const int ok = PyC_ParseBool(result, &use_node);
Py_DECREF(result);
if (ok) {
return (int)use_node;
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index efe600a846a..1dc45f58699 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -438,7 +438,10 @@ typedef struct wmNotifier {
/* subtype 3d view editing */
#define NS_VIEW3D_GPU (16 << 8)
-#define NS_VIEW3D_SHADING (16 << 9)
+#define NS_VIEW3D_SHADING (17 << 8)
+
+/* subtype layer editing */
+#define NS_LAYER_COLLECTION (24 << 8)
/* action classification */
#define NOTE_ACTION (0x000000FF)
@@ -448,7 +451,8 @@ typedef struct wmNotifier {
#define NA_REMOVED 4
#define NA_RENAME 5
#define NA_SELECTED 6
-#define NA_PAINTING 7
+#define NA_ACTIVATED 7
+#define NA_PAINTING 8
/* ************** Gesture Manager data ************** */
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index cecd324ff28..479768c3536 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -470,10 +470,10 @@ static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBas
}
else {
if (is_depth) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
else {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
is_depth_prev = is_depth;
}
@@ -492,7 +492,7 @@ static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBas
}
if (is_depth_prev) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
}
@@ -534,10 +534,10 @@ static void gizmo_draw_select_3d_loop(const bContext *C,
}
else {
if (is_depth) {
- GPU_depth_test(true);
+ GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
}
else {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
is_depth_prev = is_depth;
}
@@ -560,7 +560,7 @@ static void gizmo_draw_select_3d_loop(const bContext *C,
}
if (is_depth_prev) {
- GPU_depth_test(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
}
if (is_depth_skip_prev) {
GPU_depth_mask(true);
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 67733ffc673..b245bbe054d 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -353,7 +353,7 @@ static void draw_filled_lasso(wmGesture *gt)
draw_filled_lasso_px_cb,
&lasso_fill_data);
- GPU_blend(GPU_BLEND_ADDITIVE);
+ GPU_blend(GPU_BLEND_ADDITIVE_PREMULT);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_bind(state.shader);
@@ -361,7 +361,7 @@ static void draw_filled_lasso(wmGesture *gt)
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
immDrawPixelsTex(
- &state, rect.xmin, rect.ymin, w, h, GL_R8, false, pixel_buf, 1.0f, 1.0f, NULL);
+ &state, rect.xmin, rect.ymin, w, h, GPU_R8, false, pixel_buf, 1.0f, 1.0f, NULL);
GPU_shader_unbind();