diff options
author | Falk David <falkdavid@gmx.de> | 2020-08-21 12:04:13 +0300 |
---|---|---|
committer | Falk David <falkdavid@gmx.de> | 2020-08-21 12:04:13 +0300 |
commit | 9a89bb4d59731258bb68e149f3e62afdb97c539b (patch) | |
tree | 2e3f321450bfca08feda060b976b9abd95e84795 | |
parent | 2758e560a05f27da92becbc4ce1f3703067f5f01 (diff) | |
parent | 96a690c7ac7f34b3a42145c1d030d62164e22668 (diff) |
Merge branch 'greasepencil-edit-curve' into soc-2020-greasepencil-curve
143 files changed, 1972 insertions, 1684 deletions
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 83909a0cf66..0ef180435b3 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -590,6 +590,14 @@ endif() if(CMAKE_COMPILER_IS_GNUCC) set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") + # `maybe-uninitialized` is unreliable in release builds, but fine in debug builds. + set(GCC_EXTRA_FLAGS_RELEASE "-Wno-maybe-uninitialized") + set(CMAKE_C_FLAGS_RELEASE "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + set(CMAKE_CXX_FLAGS_RELEASE "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + unset(GCC_EXTRA_FLAGS_RELEASE) + if(WITH_LINKER_GOLD) execute_process( COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 673b33a1e93..f8562241ef9 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -42,6 +42,8 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), + ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), ("bpy.types.fluiddomainsettings.openvdb_cache_compress_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-cache-compress-type"), ("bpy.types.fluiddomainsettings.sndparticle_bubble_buoyancy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-buoyancy"), @@ -80,6 +82,7 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.sndparticle_boundary*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-boundary"), ("bpy.types.fluiddomainsettings.sndparticle_life_max*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-max"), ("bpy.types.fluiddomainsettings.sndparticle_life_min*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-min"), + ("bpy.types.fluiddomainsettings.sys_particle_maximum*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-sys-particle-maximum"), ("bpy.types.fluiddomainsettings.use_bubble_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-bubble-particles"), ("bpy.types.linestylegeometrymodifier_simplification*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/simplification.html#bpy-types-linestylegeometrymodifier-simplification"), ("bpy.types.materialgpencilstyle.use_overlap_strokes*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-overlap-strokes"), @@ -97,6 +100,8 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), + ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), + ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), ("bpy.types.fluiddomainsettings.cache_frame_offset*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-offset"), ("bpy.types.fluiddomainsettings.delete_in_obstacle*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-delete-in-obstacle"), @@ -205,6 +210,7 @@ url_manual_mapping = ( ("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/properties/sidebar.html#bpy-types-spaceview3d-use-local-collections"), ("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"), ("bpy.ops.object.vertex_group_copy_to_linked*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-linked"), + ("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"), ("bpy.types.cyclesobjectsettings.dicing_rate*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-dicing-rate"), ("bpy.types.fluiddomainsettings.adapt_margin*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-margin"), ("bpy.types.fluiddomainsettings.burning_rate*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-burning-rate"), @@ -226,6 +232,7 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-set-change-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing.html#bpy-ops-sculpt-face-sets-randomize-colors"), + ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), ("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"), ("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-pen-jitter"), ("bpy.types.fluiddomainsettings.domain_type*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-domain-type"), @@ -257,6 +264,7 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tool_settings/brushes/draw_brush.html#bpy-types-brushgpencilsettings-uv-random"), ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), + ("bpy.types.curve.bevel_factor_mapping_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-end"), ("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"), ("bpy.types.fluiddomainsettings.coba_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-coba-field"), ("bpy.types.fluiddomainsettings.flip_ratio*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flip-ratio"), @@ -380,7 +388,6 @@ url_manual_mapping = ( ("bpy.types.shadernodeambientocclusion*", "render/shader_nodes/input/ao.html#bpy-types-shadernodeambientocclusion"), ("bpy.types.shadernodevolumeabsorption*", "render/shader_nodes/shader/volume_absorption.html#bpy-types-shadernodevolumeabsorption"), ("bpy.types.shadernodevolumeprincipled*", "render/shader_nodes/shader/volume_principled.html#bpy-types-shadernodevolumeprincipled"), - ("bpy.types.toolsettings.use_uv_sculpt*", "modeling/meshes/uv/uv_sculpt.html#bpy-types-toolsettings-use-uv-sculpt"), ("bpy.ops.gpencil.interpolate_reverse*", "grease_pencil/animation/interpolation.html#bpy-ops-gpencil-interpolate-reverse"), ("bpy.ops.gpencil.select_vertex_color*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-vertex-color"), ("bpy.ops.gpencil.set_active_material*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-set-active-material"), @@ -402,6 +409,7 @@ url_manual_mapping = ( ("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"), ("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"), ("bpy.types.compositornodesplitviewer*", "compositing/types/output/split_viewer.html#bpy-types-compositornodesplitviewer"), + ("bpy.types.curve.render_resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-render-resolution-u"), ("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"), ("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"), ("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"), @@ -446,6 +454,7 @@ url_manual_mapping = ( ("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"), ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"), ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), + ("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"), ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"), ("bpy.types.camera.show_passepartout*", "render/cameras.html#bpy-types-camera-show-passepartout"), ("bpy.types.compositornodebokehimage*", "compositing/types/input/bokeh_image.html#bpy-types-compositornodebokehimage"), @@ -456,6 +465,7 @@ url_manual_mapping = ( ("bpy.types.compositornodeswitchview*", "compositing/types/converter/switch_view.html#bpy-types-compositornodeswitchview"), ("bpy.types.copytransformsconstraint*", "animation/constraints/transform/copy_transforms.html#bpy-types-copytransformsconstraint"), ("bpy.types.correctivesmoothmodifier*", "modeling/modifiers/deform/corrective_smooth.html#bpy-types-correctivesmoothmodifier"), + ("bpy.types.curve.bevel_factor_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-start"), ("bpy.types.cyclesvisibilitysettings*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesvisibilitysettings"), ("bpy.types.fluiddomainsettings.beta*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-beta"), ("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"), @@ -470,6 +480,7 @@ url_manual_mapping = ( ("bpy.types.shadernodebsdfrefraction*", "render/shader_nodes/shader/refraction.html#bpy-types-shadernodebsdfrefraction"), ("bpy.types.shadernodeoutputmaterial*", "render/shader_nodes/output/material.html#bpy-types-shadernodeoutputmaterial"), ("bpy.types.shadernodetexenvironment*", "render/shader_nodes/textures/environment.html#bpy-types-shadernodetexenvironment"), + ("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/display_panel.html#bpy-types-spaceuveditor-uv-opacity"), ("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"), ("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"), ("bpy.types.transformcacheconstraint*", "animation/constraints/transform/transform_cache.html#bpy-types-transformcacheconstraint"), @@ -501,6 +512,7 @@ url_manual_mapping = ( ("bpy.types.compositornodetransform*", "compositing/types/distort/transform.html#bpy-types-compositornodetransform"), ("bpy.types.compositornodetranslate*", "compositing/types/distort/translate.html#bpy-types-compositornodetranslate"), ("bpy.types.constraint.target_space*", "animation/constraints/interface/common.html#bpy-types-constraint-target-space"), + ("bpy.types.curve.use_deform_bounds*", "modeling/curves/properties/shape.html#bpy-types-curve-use-deform-bounds"), ("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"), ("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"), ("bpy.types.gpencillayer.mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-mask-layer"), @@ -519,6 +531,7 @@ url_manual_mapping = ( ("bpy.types.shadernodevolumescatter*", "render/shader_nodes/shader/volume_scatter.html#bpy-types-shadernodevolumescatter"), ("bpy.types.simplifygpencilmodifier*", "grease_pencil/modifiers/generate/simplify.html#bpy-types-simplifygpencilmodifier"), ("bpy.types.spacegrapheditor.cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-cursor"), + ("bpy.types.toolsettings.annotation*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer.html#bpy-types-viewlayer-use-freestyle"), ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), @@ -542,6 +555,7 @@ url_manual_mapping = ( ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), ("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/properties/modifiers.html#bpy-types-brightcontrastmodifier"), ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), + ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), ("bpy.types.brush.pose_ik_segments*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-ik-segments"), ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), @@ -560,6 +574,8 @@ url_manual_mapping = ( ("bpy.types.constraint.owner_space*", "animation/constraints/interface/common.html#bpy-types-constraint-owner-space"), ("bpy.types.copylocationconstraint*", "animation/constraints/transform/copy_location.html#bpy-types-copylocationconstraint"), ("bpy.types.copyrotationconstraint*", "animation/constraints/transform/copy_rotation.html#bpy-types-copyrotationconstraint"), + ("bpy.types.curve.bevel_factor_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-end"), + ("bpy.types.curve.bevel_resolution*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-resolution"), ("bpy.types.cyclesmaterialsettings*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings"), ("bpy.types.dopesheet.show_summary*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-summary"), ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), @@ -576,6 +592,7 @@ url_manual_mapping = ( ("bpy.types.shadernodeparticleinfo*", "render/shader_nodes/input/particle_info.html#bpy-types-shadernodeparticleinfo"), ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), + ("bpy.types.texturegpencilmodifier*", "grease_pencil/modifiers/color/texture_mapping.html#bpy-types-texturegpencilmodifier"), ("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"), ("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"), ("bpy.ops.armature.autoside_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-autoside-names"), @@ -618,6 +635,8 @@ url_manual_mapping = ( ("bpy.types.compositornodetexture*", "compositing/types/input/texture.html#bpy-types-compositornodetexture"), ("bpy.types.compositornodetonemap*", "compositing/types/color/tone_map.html#bpy-types-compositornodetonemap"), ("bpy.types.compositornodevecblur*", "compositing/types/filter/vector_blur.html#bpy-types-compositornodevecblur"), + ("bpy.types.curve.use_fill_deform*", "modeling/curves/properties/shape.html#bpy-types-curve-use-fill-deform"), + ("bpy.types.curve.use_path_follow*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-follow"), ("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"), ("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"), ("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), @@ -725,6 +744,7 @@ url_manual_mapping = ( ("bpy.ops.object.select_by_type*", "scene_layout/object/selecting.html#bpy-ops-object-select-by-type"), ("bpy.ops.object.select_grouped*", "scene_layout/object/selecting.html#bpy-ops-object-select-grouped"), ("bpy.ops.object.select_pattern*", "scene_layout/object/selecting.html#bpy-ops-object-select-pattern"), + ("bpy.ops.outliner.id_operation*", "editors/outliner.html#bpy-ops-outliner-id-operation"), ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/hide_mask.html#bpy-ops-paint-mask-flood-fill"), ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), @@ -751,6 +771,9 @@ url_manual_mapping = ( ("bpy.types.compositornodescale*", "compositing/types/distort/scale.html#bpy-types-compositornodescale"), ("bpy.types.compositornodevalue*", "compositing/types/input/value.html#bpy-types-compositornodevalue"), ("bpy.types.copyscaleconstraint*", "animation/constraints/transform/copy_scale.html#bpy-types-copyscaleconstraint"), + ("bpy.types.curve.path_duration*", "modeling/curves/properties/path_animation.html#bpy-types-curve-path-duration"), + ("bpy.types.curve.use_fill_caps*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-fill-caps"), + ("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"), ("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"), ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), ("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"), @@ -828,8 +851,11 @@ url_manual_mapping = ( ("bpy.types.compositornodemask*", "compositing/types/input/mask.html#bpy-types-compositornodemask"), ("bpy.types.compositornodemath*", "compositing/types/converter/math.html#bpy-types-compositornodemath"), ("bpy.types.compositornodetime*", "compositing/types/input/time.html#bpy-types-compositornodetime"), + ("bpy.types.curve.bevel_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-object"), ("bpy.types.curve.resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-resolution-u"), ("bpy.types.curve.resolution_v*", "modeling/surfaces/properties/shape.html#bpy-types-curve-resolution-v"), + ("bpy.types.curve.taper_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-taper-object"), + ("bpy.types.curve.twist_smooth*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-smooth"), ("bpy.types.curvepaintsettings*", "modeling/curves/tools/draw.html#bpy-types-curvepaintsettings"), ("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiergenerator"), ("bpy.types.freestylelinestyle*", "render/freestyle/parameter_editor/line_style/index.html#bpy-types-freestylelinestyle"), @@ -912,6 +938,8 @@ url_manual_mapping = ( ("bpy.types.collisionsettings*", "physics/collision.html#bpy-types-collisionsettings"), ("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"), ("bpy.types.compositornodesep*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodesep"), + ("bpy.types.curve.bevel_depth*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-depth"), + ("bpy.types.curve.use_stretch*", "modeling/curves/properties/shape.html#bpy-types-curve-use-stretch"), ("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"), ("bpy.types.fluidflowsettings*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings"), ("bpy.types.fmodifierenvelope*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelope"), @@ -957,6 +985,7 @@ url_manual_mapping = ( ("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"), ("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"), ("bpy.ops.mesh.edge_face_add*", "modeling/meshes/editing/vertex/make_face_edge.html#bpy-ops-mesh-edge-face-add"), + ("bpy.ops.mesh.extrude_indiv*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-mesh-extrude-indiv"), ("bpy.ops.mesh.knife_project*", "modeling/meshes/editing/mesh/knife_project.html#bpy-ops-mesh-knife-project"), ("bpy.ops.mesh.loopcut_slide*", "modeling/meshes/editing/edge/loopcut_slide.html#bpy-ops-mesh-loopcut-slide"), ("bpy.ops.mesh.merge_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-merge-normals"), @@ -979,10 +1008,14 @@ url_manual_mapping = ( ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), + ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), ("bpy.types.colormixsequence*", "video_editing/sequencer/strips/effects/color_mix.html#bpy-types-colormixsequence"), + ("bpy.types.curve.dimensions*", "modeling/curves/properties/shape.html#bpy-types-curve-dimensions"), + ("bpy.types.curve.twist_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-mode"), + ("bpy.types.curve.use_radius*", "modeling/curves/properties/shape.html#bpy-types-curve-use-radius"), ("bpy.types.decimatemodifier*", "modeling/modifiers/generate/decimate.html#bpy-types-decimatemodifier"), ("bpy.types.displacemodifier*", "modeling/modifiers/deform/displace.html#bpy-types-displacemodifier"), ("bpy.types.displaysafeareas*", "render/cameras.html#bpy-types-displaysafeareas"), @@ -1026,10 +1059,13 @@ url_manual_mapping = ( ("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"), ("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"), ("bpy.ops.font.style_toggle*", "modeling/texts/editing.html#bpy-ops-font-style-toggle"), + ("bpy.ops.gpencil.mesh_bake*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-mesh-bake"), ("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"), ("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"), ("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"), + ("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"), ("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"), + ("bpy.ops.mesh.face_shading*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-face-shading"), ("bpy.ops.mesh.flip_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-flip-normals"), ("bpy.ops.mesh.select_loose*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-loose"), ("bpy.ops.mesh.vert_connect*", "modeling/meshes/editing/vertex/connect_vertex_pairs.html#bpy-ops-mesh-vert-connect"), @@ -1053,6 +1089,8 @@ url_manual_mapping = ( ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), + ("bpy.types.curve.eval_time*", "modeling/curves/properties/path_animation.html#bpy-types-curve-eval-time"), + ("bpy.types.curve.fill_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-fill-mode"), ("bpy.types.explodemodifier*", "modeling/modifiers/physics/explode.html#bpy-types-explodemodifier"), ("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fcurvemodifiers"), ("bpy.types.floorconstraint*", "animation/constraints/relationship/floor.html#bpy-types-floorconstraint"), @@ -1148,6 +1186,7 @@ url_manual_mapping = ( ("bpy.ops.fluid.free_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-free-data"), ("bpy.ops.fluid.free_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-free-mesh"), ("bpy.ops.font.select_all*", "modeling/texts/selecting.html#bpy-ops-font-select-all"), + ("bpy.ops.gpencil.convert*", "grease_pencil/modes/object/convert_to_geometry.html#bpy-ops-gpencil-convert"), ("bpy.ops.mesh.customdata*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata"), ("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-edge-split"), ("bpy.ops.mesh.fill_holes*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-fill-holes"), @@ -1182,6 +1221,7 @@ url_manual_mapping = ( ("bpy.types.cloudstexture*", "render/materials/legacy_textures/types/clouds.html#bpy-types-cloudstexture"), ("bpy.types.colorsequence*", "video_editing/sequencer/strips/color.html#bpy-types-colorsequence"), ("bpy.types.crosssequence*", "video_editing/sequencer/strips/transitions/cross.html#bpy-types-crosssequence"), + ("bpy.types.curve.extrude*", "modeling/curves/properties/geometry.html#bpy-types-curve-extrude"), ("bpy.types.curvemodifier*", "modeling/modifiers/deform/curve.html#bpy-types-curvemodifier"), ("bpy.types.fieldsettings*", "physics/forces/force_fields/index.html#bpy-types-fieldsettings"), ("bpy.types.imagesequence*", "video_editing/sequencer/strips/movie_image.html#bpy-types-imagesequence"), @@ -1204,6 +1244,7 @@ url_manual_mapping = ( ("bpy.types.soundsequence*", "video_editing/sequencer/strips/sound.html#bpy-types-soundsequence"), ("bpy.types.spaceoutliner*", "editors/outliner.html#bpy-types-spaceoutliner"), ("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"), + ("bpy.types.spaceuveditor*", "editors/uv/index.html#bpy-types-spaceuveditor"), ("bpy.types.stuccitexture*", "render/materials/legacy_textures/types/stucci.html#bpy-types-stuccitexture"), ("bpy.types.view3doverlay*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay"), ("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"), @@ -1244,6 +1285,7 @@ url_manual_mapping = ( ("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"), ("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"), ("bpy.types.colormanaged*", "render/color_management.html#bpy-types-colormanaged"), + ("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"), ("bpy.types.glowsequence*", "video_editing/sequencer/strips/effects/glow.html#bpy-types-glowsequence"), ("bpy.types.gpencillayer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer"), ("bpy.types.hookmodifier*", "modeling/modifiers/deform/hooks.html#bpy-types-hookmodifier"), @@ -1292,6 +1334,7 @@ url_manual_mapping = ( ("bpy.types.addsequence*", "video_editing/sequencer/strips/effects/add.html#bpy-types-addsequence"), ("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"), ("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"), + ("bpy.types.curve.bevel*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel"), ("bpy.types.mesh.remesh*", "modeling/meshes/retopology.html#bpy-types-mesh-remesh"), ("bpy.types.meshstatvis*", "modeling/meshes/mesh_analysis.html#bpy-types-meshstatvis"), ("bpy.types.nodesetting*", "interface/controls/nodes/parts.html#bpy-types-nodesetting"), @@ -1346,6 +1389,7 @@ url_manual_mapping = ( ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), + ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), ("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"), @@ -1414,6 +1458,7 @@ url_manual_mapping = ( ("bpy.ops.uv.select*", "editors/uv/selecting.html#bpy-ops-uv-select"), ("bpy.ops.uv.stitch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-stitch"), ("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap"), + ("bpy.ops.wm.search*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search"), ("bpy.types.animviz*", "animation/motion_paths.html#bpy-types-animviz"), ("bpy.types.lattice*", "animation/lattice.html#bpy-types-lattice"), ("bpy.types.library*", "files/linked_libraries/index.html#bpy-types-library"), @@ -1479,6 +1524,7 @@ url_manual_mapping = ( ("bpy.ops.script*", "advanced/scripting/index.html#bpy-ops-script"), ("bpy.ops.sculpt*", "sculpt_paint/sculpting/index.html#bpy-ops-sculpt"), ("bpy.ops.uv.pin*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pin"), + ("bpy.ops.uv.rip*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip"), ("bpy.ops.view3d*", "editors/3dview/index.html#bpy-ops-view3d"), ("bpy.types.area*", "interface/window_system/areas.html#bpy-types-area"), ("bpy.types.boid*", "physics/particles/emitter/physics/boids.html#bpy-types-boid"), diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 1bc6d5cf71f..e336635a4ee 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1289,6 +1289,7 @@ class _defs_sculpt: layout.prop(props, "strength") row = layout.row(align=True) row.prop(props, "force_axis") + layout.prop(props, "orientation", expand=False) layout.prop(props, "cloth_mass") layout.prop(props, "cloth_damping") layout.prop(props, "use_face_sets") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f7070c46078..05aac191c2e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -5958,7 +5958,7 @@ class VIEW3D_PT_gizmo_display(Panel): layout.separator() col = layout.column() - col.active = view.show_gizmo_context + col.active = view.show_gizmo and view.show_gizmo_context col.label(text="Object Gizmos") col.prop(scene.transform_orientation_slots[1], "type", text="") col.prop(view, "show_gizmo_object_translate", text="Move") @@ -5969,6 +5969,7 @@ class VIEW3D_PT_gizmo_display(Panel): # Match order of object type visibility col = layout.column() + col.active = view.show_gizmo col.label(text="Empty") col.prop(view, "show_gizmo_empty_image", text="Image") col.prop(view, "show_gizmo_empty_force_field", text="Force Field") @@ -6127,8 +6128,12 @@ class VIEW3D_PT_overlay_motion_tracking(Panel): bl_label = "Motion Tracking" def draw_header(self, context): + layout = self.layout view = context.space_data - self.layout.prop(view, "show_reconstruction", text=self.bl_label) + overlay = view.overlay + display_all = overlay.show_overlays + layout.active = display_all + layout.prop(view, "show_reconstruction", text=self.bl_label) def draw(self, context): layout = self.layout @@ -6150,6 +6155,7 @@ class VIEW3D_PT_overlay_motion_tracking(Panel): sub.prop(view, "show_bundle_names", text="Marker Names") col = layout.column() + col.active = display_all col.label(text="Tracks:") row = col.row(align=True) row.prop(view, "tracks_display_type", text="") @@ -6585,6 +6591,8 @@ class VIEW3D_PT_proportional_edit(Panel): layout = self.layout tool_settings = context.tool_settings col = layout.column() + col.active = (tool_settings.use_proportional_edit_objects if context.mode == 'OBJECT' + else tool_settings.use_proportional_edit) if context.mode != 'OBJECT': col.prop(tool_settings, "use_proportional_connected") 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, ®ion->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, ®ion->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, ®ion->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, ®ion->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(®ion->v2d.cur) / (float)BLI_rcti_size_x(®ion->winrct); - dy *= (float)BLI_rctf_size_y(®ion->v2d.cur) / (float)BLI_rcti_size_y(®ion->winrct); + dx *= BLI_rctf_size_x(®ion->v2d.cur) / (float)BLI_rcti_size_x(®ion->winrct); + dy *= BLI_rctf_size_y(®ion->v2d.cur) / (float)BLI_rcti_size_y(®ion->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, ®ion->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, ®ion->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, ®ion->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, ®ion->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, ®ion->type->paneltypes, NULL, -1, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->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, ®ion->type->paneltypes, contexts, contextnr, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->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(®ion->v2d); /* draw all headers types */ - for (ht = region->type->headertypes.first; ht; ht = ht->next) { + LISTBASE_FOREACH (HeaderType *, ht, ®ion->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, ®ion->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, ®ion->type->paneltypes, contexts, sbuts->mainb, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->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, ®ion->type->paneltypes, contexts_base, -1, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->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(®ion->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, ®ion->type->paneltypes, contexts, U.space_data.section_active, true, NULL); + ED_region_panels_layout_ex(C, region, ®ion->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(); |