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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor')
-rw-r--r--source/blender/compositor/intern/COM_CPUDevice.cc2
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrder.cc2
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrder.h6
-rw-r--r--source/blender/compositor/intern/COM_ChunkOrderHotspot.cc4
-rw-r--r--source/blender/compositor/intern/COM_Debug.cc4
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cc68
-rw-r--r--source/blender/compositor/intern/COM_FullFrameExecutionModel.cc2
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cc12
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.cc2
-rw-r--r--source/blender/compositor/intern/COM_MetaData.cc2
-rw-r--r--source/blender/compositor/intern/COM_MultiThreadedOperation.h12
-rw-r--r--source/blender/compositor/intern/COM_Node.cc8
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cc12
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cc2
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cc6
-rw-r--r--source/blender/compositor/intern/COM_TiledExecutionModel.cc4
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cc6
-rw-r--r--source/blender/compositor/intern/COM_compositor.cc6
-rw-r--r--source/blender/compositor/nodes/COM_CombineColorNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_CombineXYZNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_CropNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_CryptomatteNode.cc7
-rw-r--r--source/blender/compositor/nodes/COM_MapUVNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_MaskNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_OutputFileNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_SceneTimeNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_SeparateColorNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_SeparateXYZNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.cc2
-rw-r--r--source/blender/compositor/operations/COM_AntiAliasOperation.cc26
-rw-r--r--source/blender/compositor/operations/COM_BilateralBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_BlurBaseOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_BoxMaskOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_BrightnessOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_CalculateMeanOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc11
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_ConstantOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_ConvertOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_CryptomatteOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_DenoiseOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_DespeckleOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_DirectionalBlurOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_DisplaceOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc222
-rw-r--r--source/blender/compositor/operations/COM_EllipseMaskOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc23
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_FlipOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc40
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cc69
-rw-r--r--source/blender/compositor/operations/COM_GlareGhostOperation.cc12
-rw-r--r--source/blender/compositor/operations/COM_GlareStreaksOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.cc20
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_MaskOperation.cc10
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_MovieDistortionOperation.cc16
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.cc11
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.cc8
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc24
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cc24
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc4
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc14
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.cc21
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.cc3
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cc18
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_SMAAOperation.cc22
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc30
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cc34
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.cc18
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_TransformOperation.cc2
-rw-r--r--source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc30
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cc39
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.cc8
-rw-r--r--source/blender/compositor/realtime_compositor/CMakeLists.txt144
-rw-r--r--source/blender/compositor/realtime_compositor/COM_context.hh11
-rw-r--r--source/blender/compositor/realtime_compositor/COM_conversion_operation.hh76
-rw-r--r--source/blender/compositor/realtime_compositor/COM_domain.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/COM_result.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/COM_scheduler.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh77
-rw-r--r--source/blender/compositor/realtime_compositor/COM_texture_pool.hh4
-rw-r--r--source/blender/compositor/realtime_compositor/COM_utilities.hh2
-rw-r--r--source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh103
-rw-r--r--source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc309
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh31
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh61
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh52
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh53
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc159
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc115
-rw-r--r--source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc93
-rw-r--r--source/blender/compositor/realtime_compositor/intern/context.cc11
-rw-r--r--source/blender/compositor/realtime_compositor/intern/conversion_operation.cc64
-rw-r--r--source/blender/compositor/realtime_compositor/intern/evaluator.cc1
-rw-r--r--source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc2
-rw-r--r--source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc4
-rw-r--r--source/blender/compositor/realtime_compositor/intern/result.cc8
-rw-r--r--source/blender/compositor/realtime_compositor/intern/scheduler.cc96
-rw-r--r--source/blender/compositor/realtime_compositor/intern/shader_operation.cc2
-rw-r--r--source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc74
-rw-r--r--source/blender/compositor/realtime_compositor/intern/texture_pool.cc18
-rw-r--r--source/blender/compositor/realtime_compositor/intern/utilities.cc4
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl11
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl31
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl66
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl71
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl118
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl27
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl8
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl70
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl21
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl31
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl27
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl20
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl15
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl7
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl24
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl101
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl88
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl19
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl10
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl98
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl16
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl29
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl151
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl8
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl77
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl53
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl22
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh15
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh35
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh69
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh35
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh11
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh21
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh22
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh22
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh12
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh149
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh11
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh24
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh20
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh11
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh22
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh16
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl48
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl32
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl38
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl52
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl43
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl34
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl87
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl27
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl10
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl7
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl39
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl16
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl7
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl56
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl9
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl132
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl9
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl35
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl29
-rw-r--r--source/blender/compositor/tests/COM_BuffersIterator_test.cc8
212 files changed, 4818 insertions, 697 deletions
diff --git a/source/blender/compositor/intern/COM_CPUDevice.cc b/source/blender/compositor/intern/COM_CPUDevice.cc
index 93c0b233752..916c7e1a411 100644
--- a/source/blender/compositor/intern/COM_CPUDevice.cc
+++ b/source/blender/compositor/intern/COM_CPUDevice.cc
@@ -16,7 +16,7 @@ void CPUDevice::execute(WorkPackage *work_package)
{
switch (work_package->type) {
case eWorkPackageType::Tile: {
- const unsigned int chunk_number = work_package->chunk_number;
+ const uint chunk_number = work_package->chunk_number;
ExecutionGroup *execution_group = work_package->execution_group;
execution_group->get_output_operation()->execute_region(&work_package->rect, chunk_number);
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.cc b/source/blender/compositor/intern/COM_ChunkOrder.cc
index 38298840bf0..acc19155049 100644
--- a/source/blender/compositor/intern/COM_ChunkOrder.cc
+++ b/source/blender/compositor/intern/COM_ChunkOrder.cc
@@ -7,7 +7,7 @@
namespace blender::compositor {
-void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots)
+void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots)
{
double new_distance = DBL_MAX;
for (int index = 0; index < len_hotspots; index++) {
diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h
index 927eab97ccd..ef65d90dd3a 100644
--- a/source/blender/compositor/intern/COM_ChunkOrder.h
+++ b/source/blender/compositor/intern/COM_ChunkOrder.h
@@ -7,20 +7,22 @@
# include "MEM_guardedalloc.h"
#endif
+#include "BLI_sys_types.h"
+
#include "COM_ChunkOrderHotspot.h"
namespace blender::compositor {
/** Helper to determine the order how chunks are prioritized during execution. */
struct ChunkOrder {
- unsigned int index = 0;
+ uint index = 0;
int x = 0;
int y = 0;
double distance = 0.0;
friend bool operator<(const ChunkOrder &a, const ChunkOrder &b);
- void update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots);
+ void update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ChunkOrderHotspot")
diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
index b9179c0a910..5b9d2fa2797 100644
--- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
+++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc
@@ -10,8 +10,8 @@ double ChunkOrderHotspot::calc_distance(int x, int y)
{
int dx = this->x - x;
int dy = this->y - y;
- double result = sqrt((double)(dx * dx + dy * dy));
- result += (double)this->addition;
+ double result = sqrt(double(dx * dx + dy * dy));
+ result += double(this->addition);
return result;
}
diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc
index d0f0be590f6..a670af5eaca 100644
--- a/source/blender/compositor/intern/COM_Debug.cc
+++ b/source/blender/compositor/intern/COM_Debug.cc
@@ -305,7 +305,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma
for (NodeOperation *operation : group->operations_) {
- sprintf(strbuf, "_%p", group);
+ BLI_snprintf(strbuf, sizeof(strbuf), "_%p", group);
op_groups[operation].push_back(std::string(strbuf));
len += graphviz_operation(
@@ -428,7 +428,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name)
else {
BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename));
}
- BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_session(), basename);
+ BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), basename);
file_index_++;
std::cout << "Writing compositor debug to: " << filepath << "\n";
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc
index 6f2d4faffb1..c9002b535ed 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cc
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc
@@ -126,7 +126,7 @@ void ExecutionGroup::init_work_packages()
work_packages_.clear();
if (chunks_len_ != 0) {
work_packages_.resize(chunks_len_);
- for (unsigned int index = 0; index < chunks_len_; index++) {
+ for (uint index = 0; index < chunks_len_; index++) {
work_packages_[index].type = eWorkPackageType::Tile;
work_packages_[index].state = eWorkPackageState::NotScheduled;
work_packages_[index].execution_group = this;
@@ -138,7 +138,7 @@ void ExecutionGroup::init_work_packages()
void ExecutionGroup::init_read_buffer_operations()
{
- unsigned int max_offset = 0;
+ uint max_offset = 0;
for (NodeOperation *operation : operations_) {
if (operation->get_flags().is_read_buffer_operation) {
ReadBufferOperation *read_operation = static_cast<ReadBufferOperation *>(operation);
@@ -167,7 +167,7 @@ void ExecutionGroup::deinit_execution()
bTree_ = nullptr;
}
-void ExecutionGroup::determine_resolution(unsigned int resolution[2])
+void ExecutionGroup::determine_resolution(uint resolution[2])
{
NodeOperation *operation = this->get_output_operation();
resolution[0] = operation->get_width();
@@ -193,9 +193,9 @@ void ExecutionGroup::init_number_of_chunks()
}
}
-blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
+blender::Array<uint> ExecutionGroup::get_execution_order() const
{
- blender::Array<unsigned int> chunk_order(chunks_len_);
+ blender::Array<uint> chunk_order(chunks_len_);
for (int chunk_index = 0; chunk_index < chunks_len_; chunk_index++) {
chunk_order[chunk_index] = chunk_index;
}
@@ -218,7 +218,7 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
switch (order_type) {
case ChunkOrdering::Random: {
static blender::RandomNumberGenerator rng;
- blender::MutableSpan<unsigned int> span = chunk_order.as_mutable_span();
+ blender::MutableSpan<uint> span = chunk_order.as_mutable_span();
/* Shuffle twice to make it more random. */
rng.shuffle(span);
rng.shuffle(span);
@@ -243,12 +243,12 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const
break;
}
case ChunkOrdering::RuleOfThirds: {
- unsigned int tx = border_width / 6;
- unsigned int ty = border_height / 6;
- unsigned int mx = border_width / 2;
- unsigned int my = border_height / 2;
- unsigned int bx = mx + 2 * tx;
- unsigned int by = my + 2 * ty;
+ uint tx = border_width / 6;
+ uint ty = border_height / 6;
+ uint mx = border_width / 2;
+ uint my = border_height / 2;
+ uint bx = mx + 2 * tx;
+ uint by = my + 2 * ty;
float addition = chunks_len_ / COM_RULE_OF_THIRDS_DIVIDER;
ChunkOrderHotspot hotspots[9]{
@@ -300,21 +300,21 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
if (chunks_len_ == 0) {
return;
} /** \note Early break out. */
- unsigned int chunk_index;
+ uint chunk_index;
execution_start_time_ = PIL_check_seconds_timer();
chunks_finished_ = 0;
bTree_ = bTree;
- blender::Array<unsigned int> chunk_order = get_execution_order();
+ blender::Array<uint> chunk_order = get_execution_order();
DebugInfo::execution_group_started(this);
DebugInfo::graphviz(graph);
bool breaked = false;
bool finished = false;
- unsigned int start_index = 0;
+ uint start_index = 0;
const int max_number_evaluated = BLI_system_thread_count() * 2;
while (!finished && !breaked) {
@@ -399,7 +399,7 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m
atomic_add_and_fetch_u(&chunks_finished_, 1);
if (memory_buffers) {
- for (unsigned int index = 0; index < max_read_buffer_offset_; index++) {
+ for (uint index = 0; index < max_read_buffer_offset_; index++) {
MemoryBuffer *buffer = memory_buffers[index];
if (buffer) {
if (buffer->is_temporarily()) {
@@ -424,8 +424,8 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m
}
inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
- const unsigned int x_chunk,
- const unsigned int y_chunk) const
+ const uint x_chunk,
+ const uint y_chunk) const
{
const int border_width = BLI_rcti_size_x(&viewer_border_);
const int border_height = BLI_rcti_size_y(&viewer_border_);
@@ -434,10 +434,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
BLI_rcti_init(r_rect, viewer_border_.xmin, border_width, viewer_border_.ymin, border_height);
}
else {
- const unsigned int minx = x_chunk * chunk_size_ + viewer_border_.xmin;
- const unsigned int miny = y_chunk * chunk_size_ + viewer_border_.ymin;
- const unsigned int width = MIN2((unsigned int)viewer_border_.xmax, width_);
- const unsigned int height = MIN2((unsigned int)viewer_border_.ymax, height_);
+ const uint minx = x_chunk * chunk_size_ + viewer_border_.xmin;
+ const uint miny = y_chunk * chunk_size_ + viewer_border_.ymin;
+ const uint width = MIN2(uint(viewer_border_.xmax), width_);
+ const uint height = MIN2(uint(viewer_border_.ymax), height_);
BLI_rcti_init(r_rect,
MIN2(minx, width_),
MIN2(minx + chunk_size_, width),
@@ -446,10 +446,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect,
}
}
-void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const unsigned int chunk_number) const
+void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const uint chunk_number) const
{
- const unsigned int y_chunk = chunk_number / x_chunks_len_;
- const unsigned int x_chunk = chunk_number - (y_chunk * x_chunks_len_);
+ const uint y_chunk = chunk_number / x_chunks_len_;
+ const uint x_chunk = chunk_number - (y_chunk * x_chunks_len_);
determine_chunk_rect(r_rect, x_chunk, y_chunk);
}
@@ -480,14 +480,14 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a
int maxx = min_ii(area->xmax - viewer_border_.xmin, viewer_border_.xmax - viewer_border_.xmin);
int miny = max_ii(area->ymin - viewer_border_.ymin, 0);
int maxy = min_ii(area->ymax - viewer_border_.ymin, viewer_border_.ymax - viewer_border_.ymin);
- int minxchunk = minx / (int)chunk_size_;
- int maxxchunk = (maxx + (int)chunk_size_ - 1) / (int)chunk_size_;
- int minychunk = miny / (int)chunk_size_;
- int maxychunk = (maxy + (int)chunk_size_ - 1) / (int)chunk_size_;
+ int minxchunk = minx / int(chunk_size_);
+ int maxxchunk = (maxx + int(chunk_size_) - 1) / int(chunk_size_);
+ int minychunk = miny / int(chunk_size_);
+ int maxychunk = (maxy + int(chunk_size_) - 1) / int(chunk_size_);
minxchunk = max_ii(minxchunk, 0);
minychunk = max_ii(minychunk, 0);
- maxxchunk = min_ii(maxxchunk, (int)x_chunks_len_);
- maxychunk = min_ii(maxychunk, (int)y_chunks_len_);
+ maxxchunk = min_ii(maxxchunk, int(x_chunks_len_));
+ maxychunk = min_ii(maxychunk, int(y_chunks_len_));
bool result = true;
for (indexx = minxchunk; indexx < maxxchunk; indexx++) {
@@ -501,7 +501,7 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a
return result;
}
-bool ExecutionGroup::schedule_chunk(unsigned int chunk_number)
+bool ExecutionGroup::schedule_chunk(uint chunk_number)
{
WorkPackage &work_package = work_packages_[chunk_number];
if (work_package.state == eWorkPackageState::NotScheduled) {
@@ -516,10 +516,10 @@ bool ExecutionGroup::schedule_chunk_when_possible(ExecutionSystem *graph,
const int chunk_x,
const int chunk_y)
{
- if (chunk_x < 0 || chunk_x >= (int)x_chunks_len_) {
+ if (chunk_x < 0 || chunk_x >= int(x_chunks_len_)) {
return true;
}
- if (chunk_y < 0 || chunk_y >= (int)y_chunks_len_) {
+ if (chunk_y < 0 || chunk_y >= int(y_chunks_len_)) {
return true;
}
diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
index ceb52feb9b4..11e3c1507d9 100644
--- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
@@ -271,7 +271,7 @@ void FullFrameExecutionModel::update_progress_bar()
{
const bNodeTree *tree = context_.get_bnodetree();
if (tree) {
- const float progress = num_operations_finished_ / static_cast<float>(operations_.size());
+ const float progress = num_operations_finished_ / float(operations_.size());
tree->progress(tree->prh, progress);
char buf[128];
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc
index ea2a85e8ea9..539e1179bc8 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cc
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc
@@ -133,8 +133,8 @@ MemoryBuffer *MemoryBuffer::inflate() const
float MemoryBuffer::get_max_value() const
{
float result = buffer_[0];
- const unsigned int size = this->buffer_len();
- unsigned int i;
+ const uint size = this->buffer_len();
+ uint i;
const float *fp_src = buffer_;
@@ -266,7 +266,7 @@ void MemoryBuffer::copy_from(const uchar *src,
const float *row_end = to_elem + width * this->elem_stride;
while (to_elem < row_end) {
for (int i = 0; i < elem_size; i++) {
- to_elem[i] = ((float)from_elem[i]) * (1.0f / 255.0f);
+ to_elem[i] = float(from_elem[i]) * (1.0f / 255.0f);
}
to_elem += this->elem_stride;
from_elem += elem_stride;
@@ -427,7 +427,7 @@ void MemoryBuffer::read_elem_filtered(
const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
- float inv_width = 1.0f / (float)this->get_width(), inv_height = 1.0f / (float)this->get_height();
+ float inv_width = 1.0f / float(this->get_width()), inv_height = 1.0f / float(this->get_height());
/* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
* but compositor uses pixel space. For now let's just divide the values and
* switch compositor to normalized space for EWA later.
@@ -463,8 +463,8 @@ void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivat
}
else {
BLI_assert(datatype_ == DataType::Color);
- float inv_width = 1.0f / (float)this->get_width(),
- inv_height = 1.0f / (float)this->get_height();
+ float inv_width = 1.0f / float(this->get_width()),
+ inv_height = 1.0f / float(this->get_height());
/* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
* but compositor uses pixel space. For now let's just divide the values and
* switch compositor to normalized space for EWA later.
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.cc b/source/blender/compositor/intern/COM_MemoryProxy.cc
index 42d0f86843d..723e8b3ab9b 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.cc
+++ b/source/blender/compositor/intern/COM_MemoryProxy.cc
@@ -14,7 +14,7 @@ MemoryProxy::MemoryProxy(DataType datatype)
datatype_ = datatype;
}
-void MemoryProxy::allocate(unsigned int width, unsigned int height)
+void MemoryProxy::allocate(uint width, uint height)
{
rcti result;
result.xmin = 0;
diff --git a/source/blender/compositor/intern/COM_MetaData.cc b/source/blender/compositor/intern/COM_MetaData.cc
index 9ee3d7e5c22..94a0bc8706b 100644
--- a/source/blender/compositor/intern/COM_MetaData.cc
+++ b/source/blender/compositor/intern/COM_MetaData.cc
@@ -72,7 +72,7 @@ void MetaDataExtractCallbackData::set_cryptomatte_keys(blender::StringRef crypto
void MetaDataExtractCallbackData::extract_cryptomatte_meta_data(void *_data,
const char *propname,
char *propvalue,
- int UNUSED(len))
+ int /*len*/)
{
MetaDataExtractCallbackData *data = static_cast<MetaDataExtractCallbackData *>(_data);
blender::StringRefNull key(propname);
diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.h b/source/blender/compositor/intern/COM_MultiThreadedOperation.h
index 9ec81fa834e..355081c374d 100644
--- a/source/blender/compositor/intern/COM_MultiThreadedOperation.h
+++ b/source/blender/compositor/intern/COM_MultiThreadedOperation.h
@@ -24,9 +24,9 @@ class MultiThreadedOperation : public NodeOperation {
/**
* Called before an update memory buffer pass is executed. Single-threaded calls.
*/
- virtual void update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
@@ -40,9 +40,9 @@ class MultiThreadedOperation : public NodeOperation {
/**
* Called after an update memory buffer pass is executed. Single-threaded calls.
*/
- virtual void update_memory_buffer_finished(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer_finished(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
diff --git a/source/blender/compositor/intern/COM_Node.cc b/source/blender/compositor/intern/COM_Node.cc
index a71c7868518..c1a8740d8ea 100644
--- a/source/blender/compositor/intern/COM_Node.cc
+++ b/source/blender/compositor/intern/COM_Node.cc
@@ -53,10 +53,10 @@ Node::Node(bNode *editor_node, bool create_sockets)
Node::~Node()
{
while (!outputs_.is_empty()) {
- delete (outputs_.pop_last());
+ delete outputs_.pop_last();
}
while (!inputs_.is_empty()) {
- delete (inputs_.pop_last());
+ delete inputs_.pop_last();
}
}
@@ -81,12 +81,12 @@ void Node::add_output_socket(DataType datatype, bNodeSocket *bSocket)
outputs_.append(socket);
}
-NodeOutput *Node::get_output_socket(unsigned int index) const
+NodeOutput *Node::get_output_socket(uint index) const
{
return outputs_[index];
}
-NodeInput *Node::get_input_socket(unsigned int index) const
+NodeInput *Node::get_input_socket(uint index) const
{
return inputs_[index];
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 3867b1d5c10..ab9b5ad1ad6 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -84,12 +84,12 @@ std::optional<NodeOperationHash> NodeOperation::generate_hash()
return hash;
}
-NodeOperationOutput *NodeOperation::get_output_socket(unsigned int index)
+NodeOperationOutput *NodeOperation::get_output_socket(uint index)
{
return &outputs_[index];
}
-NodeOperationInput *NodeOperation::get_input_socket(unsigned int index)
+NodeOperationInput *NodeOperation::get_input_socket(uint index)
{
return &inputs_[index];
}
@@ -106,7 +106,7 @@ void NodeOperation::add_output_socket(DataType datatype)
void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
- unsigned int used_canvas_index = 0;
+ uint used_canvas_index = 0;
if (canvas_input_index_ == RESOLUTION_INPUT_ANY) {
for (NodeOperationInput &input : inputs_) {
rcti any_area = COM_AREA_NONE;
@@ -130,7 +130,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
rcti unused_area = COM_AREA_NONE;
const rcti &local_preferred_area = r_area;
- for (unsigned int index = 0; index < inputs_.size(); index++) {
+ for (uint index = 0; index < inputs_.size(); index++) {
if (index == used_canvas_index) {
continue;
}
@@ -141,7 +141,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
}
}
-void NodeOperation::set_canvas_input_index(unsigned int index)
+void NodeOperation::set_canvas_input_index(uint index)
{
this->canvas_input_index_ = index;
}
@@ -197,7 +197,7 @@ void NodeOperation::unset_canvas()
flags_.is_canvas_set = false;
}
-SocketReader *NodeOperation::get_input_socket_reader(unsigned int index)
+SocketReader *NodeOperation::get_input_socket_reader(uint index)
{
return this->get_input_socket(index)->get_reader();
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index aa9e4329ab6..a00ac1352fe 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -628,9 +628,9 @@ class NodeOperation {
/**
* Executes operation updating output memory buffer. Single-threaded calls.
*/
- virtual void update_memory_buffer(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs))
+ virtual void update_memory_buffer(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/)
{
}
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
index 1fdec43eb3b..8212be5ec26 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
@@ -576,7 +576,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation,
/* try to find existing write buffer operation */
if (target->get_operation().get_flags().is_write_buffer_operation) {
BLI_assert(write_operation == nullptr); /* there should only be one write op connected */
- write_operation = (WriteBufferOperation *)(&target->get_operation());
+ write_operation = (WriteBufferOperation *)&target->get_operation();
}
else {
/* remove all links to other nodes */
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cc b/source/blender/compositor/intern/COM_OpenCLDevice.cc
index d951ebef172..188389b88c9 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cc
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cc
@@ -56,7 +56,7 @@ OpenCLDevice::~OpenCLDevice()
void OpenCLDevice::execute(WorkPackage *work_package)
{
- const unsigned int chunk_number = work_package->chunk_number;
+ const uint chunk_number = work_package->chunk_number;
ExecutionGroup *execution_group = work_package->execution_group;
MemoryBuffer **input_buffers = execution_group->get_input_buffers_opencl(chunk_number);
@@ -187,8 +187,8 @@ void OpenCLDevice::COM_cl_enqueue_range(cl_kernel kernel, MemoryBuffer *output_m
{
cl_int error;
const size_t size[] = {
- (size_t)output_memory_buffer->get_width(),
- (size_t)output_memory_buffer->get_height(),
+ size_t(output_memory_buffer->get_width()),
+ size_t(output_memory_buffer->get_height()),
};
error = clEnqueueNDRangeKernel(queue_, kernel, 2, nullptr, size, nullptr, 0, nullptr, nullptr);
diff --git a/source/blender/compositor/intern/COM_TiledExecutionModel.cc b/source/blender/compositor/intern/COM_TiledExecutionModel.cc
index cf8d3e9a084..54e8e8f315a 100644
--- a/source/blender/compositor/intern/COM_TiledExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_TiledExecutionModel.cc
@@ -23,7 +23,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context,
const bNodeTree *node_tree = context.get_bnodetree();
node_tree->stats_draw(node_tree->sdh, TIP_("Compositing | Determining resolution"));
- unsigned int resolution[2];
+ uint resolution[2];
for (ExecutionGroup *group : groups_) {
resolution[0] = 0;
resolution[1] = 0;
@@ -45,7 +45,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context,
static void update_read_buffer_offset(Span<NodeOperation *> operations)
{
- unsigned int order = 0;
+ uint order = 0;
for (NodeOperation *operation : operations) {
if (operation->get_flags().is_read_buffer_operation) {
ReadBufferOperation *read_operation = (ReadBufferOperation *)operation;
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc
index 1f93a3d9bfa..9067807d98c 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cc
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cc
@@ -185,7 +185,7 @@ static void opencl_initialize(const bool use_opencl)
cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(
sizeof(cl_platform_id) * number_of_platforms, __func__);
error = clGetPlatformIDs(number_of_platforms, platforms, nullptr);
- unsigned int index_platform;
+ uint index_platform;
for (index_platform = 0; index_platform < number_of_platforms; index_platform++) {
cl_platform_id platform = platforms[index_platform];
cl_uint number_of_devices = 0;
@@ -240,7 +240,7 @@ static void opencl_initialize(const bool use_opencl)
MEM_freeN(build_log);
}
else {
- unsigned int index_devices;
+ uint index_devices;
for (index_devices = 0; index_devices < number_of_devices; index_devices++) {
cl_device_id device = cldevices[index_devices];
cl_int vendorID = 0;
@@ -377,7 +377,7 @@ static void threading_model_queue_deinitialize()
/** \name Task Scheduling
* \{ */
-static void threading_model_task_execute(TaskPool *__restrict UNUSED(pool), void *task_data)
+static void threading_model_task_execute(TaskPool *__restrict /*pool*/, void *task_data)
{
WorkPackage *package = static_cast<WorkPackage *>(task_data);
CPUDevice device(BLI_task_parallel_thread_id(nullptr));
diff --git a/source/blender/compositor/intern/COM_compositor.cc b/source/blender/compositor/intern/COM_compositor.cc
index 519ad93bcaf..1ffc749ce64 100644
--- a/source/blender/compositor/intern/COM_compositor.cc
+++ b/source/blender/compositor/intern/COM_compositor.cc
@@ -25,15 +25,15 @@ static void compositor_init_node_previews(const RenderData *render_data, bNodeTr
/* We fit the aspect into COM_PREVIEW_SIZE x COM_PREVIEW_SIZE image to avoid
* insane preview resolution, which might even overflow preview dimensions. */
const float aspect = render_data->xsch > 0 ?
- (float)render_data->ysch / (float)render_data->xsch :
+ float(render_data->ysch) / float(render_data->xsch) :
1.0f;
int preview_width, preview_height;
if (aspect < 1.0f) {
preview_width = blender::compositor::COM_PREVIEW_SIZE;
- preview_height = (int)(blender::compositor::COM_PREVIEW_SIZE * aspect);
+ preview_height = int(blender::compositor::COM_PREVIEW_SIZE * aspect);
}
else {
- preview_width = (int)(blender::compositor::COM_PREVIEW_SIZE / aspect);
+ preview_width = int(blender::compositor::COM_PREVIEW_SIZE / aspect);
preview_height = blender::compositor::COM_PREVIEW_SIZE;
}
BKE_node_preview_init_tree(node_tree, preview_width, preview_height);
diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cc b/source/blender/compositor/nodes/COM_CombineColorNode.cc
index 36ff24cb9c3..7802a585c05 100644
--- a/source/blender/compositor/nodes/COM_CombineColorNode.cc
+++ b/source/blender/compositor/nodes/COM_CombineColorNode.cc
@@ -12,7 +12,7 @@ CombineColorNode::CombineColorNode(bNode *editor_node) : Node(editor_node)
}
void CombineColorNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *input_rsocket = this->get_input_socket(0);
NodeInput *input_gsocket = this->get_input_socket(1);
diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.cc b/source/blender/compositor/nodes/COM_CombineXYZNode.cc
index 0b46f7ba0d4..dd09dabef02 100644
--- a/source/blender/compositor/nodes/COM_CombineXYZNode.cc
+++ b/source/blender/compositor/nodes/COM_CombineXYZNode.cc
@@ -12,7 +12,7 @@ CombineXYZNode::CombineXYZNode(bNode *editor_node) : Node(editor_node)
}
void CombineXYZNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *input_x_socket = this->get_input_socket(0);
NodeInput *input_y_socket = this->get_input_socket(1);
diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
index 7d557de66e4..d26b649e30b 100644
--- a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
+++ b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc
@@ -25,7 +25,7 @@ ConvertColorSpaceNode::ConvertColorSpaceNode(bNode *editorNode) : Node(editorNod
}
void ConvertColorSpaceNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
const bNode *b_node = get_bnode();
diff --git a/source/blender/compositor/nodes/COM_CropNode.cc b/source/blender/compositor/nodes/COM_CropNode.cc
index 849fb80a8a8..80f345e8762 100644
--- a/source/blender/compositor/nodes/COM_CropNode.cc
+++ b/source/blender/compositor/nodes/COM_CropNode.cc
@@ -16,8 +16,8 @@ void CropNode::convert_to_operations(NodeConverter &converter,
{
const bNode *node = get_bnode();
NodeTwoXYs *crop_settings = (NodeTwoXYs *)node->storage;
- bool relative = (bool)node->custom2;
- bool crop_image = (bool)node->custom1;
+ bool relative = bool(node->custom2);
+ bool crop_image = bool(node->custom1);
CropBaseOperation *operation;
if (crop_image) {
operation = new CropImageOperation();
diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cc b/source/blender/compositor/nodes/COM_CryptomatteNode.cc
index 42d699af01b..ee31fce0ea8 100644
--- a/source/blender/compositor/nodes/COM_CryptomatteNode.cc
+++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cc
@@ -10,6 +10,7 @@
#include "COM_MultilayerImageOperation.h"
#include "COM_RenderLayersProg.h"
#include "COM_SetAlphaMultiplyOperation.h"
+#include "COM_SetAlphaReplaceOperation.h"
#include "COM_SetColorOperation.h"
namespace blender::compositor {
@@ -48,7 +49,7 @@ void CryptomatteBaseNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_image_socket, apply_mask_operation->get_output_socket(0));
NodeOutput *output_pick_socket = this->get_output_socket(2);
- SetAlphaMultiplyOperation *extract_pick_operation = new SetAlphaMultiplyOperation();
+ SetAlphaReplaceOperation *extract_pick_operation = new SetAlphaReplaceOperation();
converter.add_operation(extract_pick_operation);
converter.add_input_value(extract_pick_operation->get_input_socket(1), 1.0f);
converter.add_link(cryptomatte_operation->get_output_socket(0),
@@ -240,8 +241,8 @@ CryptomatteOperation *CryptomatteNode::create_cryptomatte_operation(
CryptomatteOperation *CryptomatteLegacyNode::create_cryptomatte_operation(
NodeConverter &converter,
- const CompositorContext &UNUSED(context),
- const bNode &UNUSED(node),
+ const CompositorContext & /*context*/,
+ const bNode & /*node*/,
const NodeCryptomatte *cryptomatte_settings) const
{
const int num_inputs = inputs_.size() - 1;
diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cc b/source/blender/compositor/nodes/COM_MapUVNode.cc
index ed9bff657f3..0ff86cabd4d 100644
--- a/source/blender/compositor/nodes/COM_MapUVNode.cc
+++ b/source/blender/compositor/nodes/COM_MapUVNode.cc
@@ -17,7 +17,7 @@ void MapUVNode::convert_to_operations(NodeConverter &converter,
const bNode *node = this->get_bnode();
MapUVOperation *operation = new MapUVOperation();
- operation->set_alpha((float)node->custom1);
+ operation->set_alpha(float(node->custom1));
operation->set_canvas_input_index(1);
converter.add_operation(operation);
diff --git a/source/blender/compositor/nodes/COM_MaskNode.cc b/source/blender/compositor/nodes/COM_MaskNode.cc
index f92e307328d..3c6812d606f 100644
--- a/source/blender/compositor/nodes/COM_MaskNode.cc
+++ b/source/blender/compositor/nodes/COM_MaskNode.cc
@@ -41,7 +41,7 @@ void MaskNode::convert_to_operations(NodeConverter &converter,
operation->set_mask(mask);
operation->set_framenumber(context.get_framenumber());
- operation->set_feather((bool)(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
+ operation->set_feather(bool(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
if ((editor_node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) && (editor_node->custom2 > 1) &&
(editor_node->custom3 > FLT_EPSILON)) {
diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cc b/source/blender/compositor/nodes/COM_OutputFileNode.cc
index c83bcf42efd..50989f73986 100644
--- a/source/blender/compositor/nodes/COM_OutputFileNode.cc
+++ b/source/blender/compositor/nodes/COM_OutputFileNode.cc
@@ -65,7 +65,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter,
if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16);
- /* single output operation for the multilayer file */
+ /* Single output operation for the multi-layer file. */
OutputOpenExrMultiLayerOperation *output_operation;
if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) {
@@ -104,7 +104,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter,
char path[FILE_MAX];
/* combine file path for the input */
- BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
+ BLI_path_join(path, FILE_MAX, storage->base_path, sockdata->path);
NodeOperation *output_operation = nullptr;
diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.cc b/source/blender/compositor/nodes/COM_SceneTimeNode.cc
index edd6efdb67b..dd5784f03ee 100644
--- a/source/blender/compositor/nodes/COM_SceneTimeNode.cc
+++ b/source/blender/compositor/nodes/COM_SceneTimeNode.cc
@@ -20,7 +20,7 @@ void SceneTimeNode::convert_to_operations(NodeConverter &converter,
const int frameNumber = context.get_framenumber();
const Scene *scene = context.get_scene();
- const double frameRate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
+ const double frameRate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base));
SecondOperation->set_value(float(frameNumber / frameRate));
converter.add_operation(SecondOperation);
diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cc b/source/blender/compositor/nodes/COM_SeparateColorNode.cc
index 28ebbb35e9a..6732396004f 100644
--- a/source/blender/compositor/nodes/COM_SeparateColorNode.cc
+++ b/source/blender/compositor/nodes/COM_SeparateColorNode.cc
@@ -12,7 +12,7 @@ SeparateColorNode::SeparateColorNode(bNode *editor_node) : Node(editor_node)
}
void SeparateColorNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *image_socket = this->get_input_socket(0);
NodeOutput *output_rsocket = this->get_output_socket(0);
diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
index 4e7704dcdc8..7aa8de04c34 100644
--- a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
+++ b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc
@@ -13,7 +13,7 @@ SeparateXYZNode::SeparateXYZNode(bNode *editor_node) : Node(editor_node)
}
void SeparateXYZNode::convert_to_operations(NodeConverter &converter,
- const CompositorContext &UNUSED(context)) const
+ const CompositorContext & /*context*/) const
{
NodeInput *vector_socket = this->get_input_socket(0);
NodeOutput *output_x_socket = this->get_output_socket(0);
diff --git a/source/blender/compositor/nodes/COM_TimeNode.cc b/source/blender/compositor/nodes/COM_TimeNode.cc
index 4f4f6f7bf8a..4004a5f718f 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.cc
+++ b/source/blender/compositor/nodes/COM_TimeNode.cc
@@ -31,7 +31,7 @@ void TimeNode::convert_to_operations(NodeConverter &converter,
fac = 1.0f;
}
else if (node->custom1 < node->custom2) {
- fac = (context.get_framenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
+ fac = (context.get_framenumber() - node->custom1) / float(node->custom2 - node->custom1);
}
BKE_curvemapping_init((CurveMapping *)node->storage);
diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cc b/source/blender/compositor/operations/COM_AntiAliasOperation.cc
index 0c297c20eef..e0083b702e1 100644
--- a/source/blender/compositor/operations/COM_AntiAliasOperation.cc
+++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cc
@@ -34,7 +34,7 @@ static int extrapolate9(float *E0,
do { \
*DST = *SRC; \
} while (0)
- if ((!PEQ(B, H)) && (!PEQ(D, F))) {
+ if (!PEQ(B, H) && !PEQ(D, F)) {
if (PEQ(D, B)) {
PCPY(E0, D);
}
@@ -144,12 +144,12 @@ void AntiAliasOperation::execute_pixel(float output[4], int x, int y, void *data
/* Some rounding magic to so make weighting correct with the
* original coefficients.
*/
- unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
- 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
- 3 * ninepix[8]) *
- 255.0f +
- 19.0f) /
- 38.0f;
+ uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
+ 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
+ 3 * ninepix[8]) *
+ 255.0f +
+ 19.0f) /
+ 38.0f;
output[0] = result / 255.0f;
}
else {
@@ -234,12 +234,12 @@ void AntiAliasOperation::update_memory_buffer_partial(MemoryBuffer *output,
&row_next[x_offset + input->elem_stride])) {
/* Some rounding magic to make weighting correct with the
* original coefficients. */
- unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] +
- 5 * ninepix[3] + 6 * ninepix[4] + 5 * ninepix[5] +
- 3 * ninepix[6] + 5 * ninepix[7] + 3 * ninepix[8]) *
- 255.0f +
- 19.0f) /
- 38.0f;
+ uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] +
+ 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] +
+ 3 * ninepix[8]) *
+ 255.0f +
+ 19.0f) /
+ 38.0f;
out[0] = result / 255.0f;
}
else {
diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
index 3711851e8f5..c808ec02690 100644
--- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc
@@ -95,7 +95,7 @@ bool BilateralBlurOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void BilateralBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
+void BilateralBlurOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cc b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
index b278997eced..53a5cebaf5d 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
@@ -71,7 +71,7 @@ float *BlurBaseOperation::make_gausstab(float rad, int size)
sum = 0.0f;
float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
- val = RE_filter_value(data_.filtertype, (float)i * fac);
+ val = RE_filter_value(data_.filtertype, float(i) * fac);
sum += val;
gausstab[i + size] = val;
}
@@ -107,7 +107,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff
float fac = (rad > 0.0f ? 1.0f / rad : 0.0f);
for (i = -size; i <= size; i++) {
- val = 1.0f - fabsf((float)i * fac);
+ val = 1.0f - fabsf(float(i) * fac);
/* keep in sync with rna_enum_proportional_falloff_curve_only_items */
switch (falloff) {
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cc b/source/blender/compositor/operations/COM_BokehImageOperation.cc
index 42caa7aa3c0..b74ac9dac64 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.cc
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.cc
@@ -16,13 +16,13 @@ void BokehImageOperation::init_execution()
center_[1] = get_height() / 2;
inverse_rounding_ = 1.0f - data_->rounding;
circular_distance_ = get_width() / 2;
- flap_rad_ = (float)(M_PI * 2) / data_->flaps;
+ flap_rad_ = float(M_PI * 2) / data_->flaps;
flap_rad_add_ = data_->angle;
while (flap_rad_add_ < 0.0f) {
- flap_rad_add_ += (float)(M_PI * 2.0);
+ flap_rad_add_ += float(M_PI * 2.0);
}
- while (flap_rad_add_ > (float)M_PI) {
- flap_rad_add_ -= (float)(M_PI * 2.0);
+ while (flap_rad_add_ > float(M_PI)) {
+ flap_rad_add_ -= float(M_PI * 2.0);
}
}
void BokehImageOperation::detemine_start_point_of_flap(float r[2], int flap_number, float distance)
@@ -43,8 +43,8 @@ float BokehImageOperation::is_inside_bokeh(float distance, float x, float y)
point[1] = y;
const float distance_to_center = len_v2v2(point, center_);
- const float bearing = (atan2f(deltaX, deltaY) + (float)(M_PI * 2.0));
- int flap_number = (int)((bearing - flap_rad_add_) / flap_rad_);
+ const float bearing = (atan2f(deltaX, deltaY) + float(M_PI * 2.0));
+ int flap_number = int((bearing - flap_rad_add_) / flap_rad_);
detemine_start_point_of_flap(line_p1, flap_number, distance);
detemine_start_point_of_flap(line_p2, flap_number + 1, distance);
@@ -96,7 +96,7 @@ void BokehImageOperation::execute_pixel_sampled(float output[4],
void BokehImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
const float shift = data_->lensshift;
const float shift2 = shift / 2.0f;
diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
index 5b3e00afe31..85ac9434647 100644
--- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc
@@ -19,10 +19,10 @@ void BoxMaskOperation::init_execution()
{
input_mask_ = this->get_input_socket_reader(0);
input_value_ = this->get_input_socket_reader(1);
- const double rad = (double)data_->rotation;
+ const double rad = double(data_->rotation);
cosine_ = cos(rad);
sine_ = sin(rad);
- aspect_ratio_ = ((float)this->get_width()) / this->get_height();
+ aspect_ratio_ = float(this->get_width()) / this->get_height();
}
void BoxMaskOperation::execute_pixel_sampled(float output[4],
diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cc b/source/blender/compositor/operations/COM_BrightnessOperation.cc
index 764d5d64046..07d8035e615 100644
--- a/source/blender/compositor/operations/COM_BrightnessOperation.cc
+++ b/source/blender/compositor/operations/COM_BrightnessOperation.cc
@@ -47,7 +47,7 @@ void BrightnessOperation::execute_pixel_sampled(float output[4],
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
if (contrast > 0) {
a = 1.0f - delta * 2.0f;
@@ -84,7 +84,7 @@ void BrightnessOperation::update_memory_buffer_partial(MemoryBuffer *output,
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
+ * Extracted of OpenCV `demhist.c`.
*/
float a, b;
if (contrast > 0) {
diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
index 4e5832a7d34..9dbeabafa5a 100644
--- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
+++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc
@@ -144,15 +144,15 @@ void CalculateMeanOperation::set_setting(int setting)
}
void CalculateMeanOperation::get_area_of_interest(int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
r_input_area = get_input_operation(input_idx)->get_canvas();
}
-void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!iscalculated_) {
@@ -164,7 +164,7 @@ void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(o
void CalculateMeanOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->fill(area, &result_);
}
diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
index 881b894d66d..709218297b7 100644
--- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
+++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc
@@ -74,15 +74,16 @@ void *CalculateStandardDeviationOperation::initialize_tile_data(rcti *rect)
}
}
}
- standard_deviation_ = sqrt(sum / (float)(pixels - 1));
+ standard_deviation_ = sqrt(sum / float(pixels - 1));
iscalculated_ = true;
}
unlock_mutex();
return nullptr;
}
-void CalculateStandardDeviationOperation::update_memory_buffer_started(
- MemoryBuffer *UNUSED(output), const rcti &UNUSED(area), Span<MemoryBuffer *> inputs)
+void CalculateStandardDeviationOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> inputs)
{
if (!iscalculated_) {
const MemoryBuffer *input = inputs[0];
@@ -98,13 +99,13 @@ void CalculateStandardDeviationOperation::update_memory_buffer_started(
join.num_pixels += chunk.num_pixels;
});
standard_deviation_ = total.num_pixels <= 1 ? 0.0f :
- sqrt(total.sum / (float)(total.num_pixels - 1));
+ sqrt(total.sum / float(total.num_pixels - 1));
iscalculated_ = true;
}
}
void CalculateStandardDeviationOperation::update_memory_buffer_partial(
- MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> UNUSED(inputs))
+ MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> /*inputs*/)
{
output->fill(area, &standard_deviation_);
}
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cc b/source/blender/compositor/operations/COM_CompositorOperation.cc
index c0cc3fa1ba4..1ff27607d09 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cc
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cc
@@ -113,7 +113,7 @@ void CompositorOperation::deinit_execution()
depth_input_ = nullptr;
}
-void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void CompositorOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
float color[8]; /* 7 is enough. */
float *buffer = output_buffer_;
@@ -197,7 +197,7 @@ void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number*
}
}
-void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void CompositorOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -213,7 +213,7 @@ void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(outp
depth_buf.copy_from(inputs[2], area);
}
-void CompositorOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void CompositorOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
int width, height;
BKE_render_resolution(rd_, false, &width, &height);
diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc
index 0977da5e37c..21c10f2b52a 100644
--- a/source/blender/compositor/operations/COM_ConstantOperation.cc
+++ b/source/blender/compositor/operations/COM_ConstantOperation.cc
@@ -19,7 +19,7 @@ bool ConstantOperation::can_get_constant_elem() const
void ConstantOperation::update_memory_buffer(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->is_a_single_elem());
const float *constant = get_constant_elem();
diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
index 89c1c7cb153..25d4b2d6a6c 100644
--- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
+++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc
@@ -46,8 +46,8 @@ void ConvertDepthToRadiusOperation::init_execution()
}
inverse_focal_distance_ = 1.0f / focal_distance;
aspect_ = (this->get_width() > this->get_height()) ?
- (this->get_height() / (float)this->get_width()) :
- (this->get_width() / (float)this->get_height());
+ (this->get_height() / float(this->get_width())) :
+ (this->get_width() / float(this->get_height()));
aperture_ = 0.5f * (cam_lens_ / (aspect_ * cam_sensor)) / f_stop_;
const float minsz = MIN2(get_width(), get_height());
dof_sp_ = minsz / ((cam_sensor / 2.0f) /
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h
index 16d1e2e6bb5..ffd02ed5a2f 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.h
+++ b/source/blender/compositor/operations/COM_ConvertOperation.h
@@ -98,7 +98,7 @@ class ConvertVectorToValueOperation : public ConvertBaseOperation {
class ConvertRGBToYCCOperation : public ConvertBaseOperation {
private:
- /** YCbCr mode (Jpeg, ITU601, ITU709) */
+ /** YCbCr mode (JPEG, ITU601, ITU709) */
int mode_;
public:
@@ -116,7 +116,7 @@ class ConvertRGBToYCCOperation : public ConvertBaseOperation {
class ConvertYCCToRGBOperation : public ConvertBaseOperation {
private:
- /** YCbCr mode (Jpeg, ITU601, ITU709) */
+ /** YCbCr mode (JPEG, ITU601, ITU709) */
int mode_;
public:
diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cc b/source/blender/compositor/operations/COM_CryptomatteOperation.cc
index 69218576237..71e892cb7f1 100644
--- a/source/blender/compositor/operations/COM_CryptomatteOperation.cc
+++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cc
@@ -42,8 +42,8 @@ void CryptomatteOperation::execute_pixel(float output[4], int x, int y, void *da
::memcpy(&m3hash, &input[0], sizeof(uint32_t));
/* Since the red channel is likely to be out of display range,
* setting green and blue gives more meaningful images. */
- output[1] = ((float)(m3hash << 8) / (float)UINT32_MAX);
- output[2] = ((float)(m3hash << 16) / (float)UINT32_MAX);
+ output[1] = (float(m3hash << 8) / float(UINT32_MAX));
+ output[2] = (float(m3hash << 16) / float(UINT32_MAX));
}
for (float hash : object_index_) {
if (input[0] == hash) {
@@ -71,8 +71,8 @@ void CryptomatteOperation::update_memory_buffer_partial(MemoryBuffer *output,
::memcpy(&m3hash, &input[0], sizeof(uint32_t));
/* Since the red channel is likely to be out of display range,
* setting green and blue gives more meaningful images. */
- it.out[1] = ((float)(m3hash << 8) / (float)UINT32_MAX);
- it.out[2] = ((float)(m3hash << 16) / (float)UINT32_MAX);
+ it.out[1] = (float(m3hash << 8) / float(UINT32_MAX));
+ it.out[2] = (float(m3hash << 16) / float(UINT32_MAX));
}
for (const float hash : object_index_) {
if (input[0] == hash) {
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cc b/source/blender/compositor/operations/COM_DenoiseOperation.cc
index 3f32eced0f8..5019c2bb158 100644
--- a/source/blender/compositor/operations/COM_DenoiseOperation.cc
+++ b/source/blender/compositor/operations/COM_DenoiseOperation.cc
@@ -89,7 +89,7 @@ class DenoiseFilter {
}
#else
- void init_and_lock_denoiser(MemoryBuffer *UNUSED(output))
+ void init_and_lock_denoiser(MemoryBuffer * /*output*/)
{
}
@@ -97,11 +97,11 @@ class DenoiseFilter {
{
}
- void set_image(const StringRef UNUSED(name), MemoryBuffer *UNUSED(buffer))
+ void set_image(const StringRef /*name*/, MemoryBuffer * /*buffer*/)
{
}
- template<typename T> void set(const StringRef UNUSED(option_name), T UNUSED(value))
+ template<typename T> void set(const StringRef /*option_name*/, T /*value*/)
{
}
@@ -132,8 +132,8 @@ bool DenoiseBaseOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void DenoiseBaseOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void DenoiseBaseOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
@@ -178,7 +178,7 @@ static bool are_guiding_passes_noise_free(const NodeDenoise *settings)
void DenoiseOperation::hash_output_params()
{
if (settings_) {
- hash_params((int)settings_->hdr, are_guiding_passes_noise_free(settings_));
+ hash_params(int(settings_->hdr), are_guiding_passes_noise_free(settings_));
}
}
@@ -251,7 +251,7 @@ void DenoiseOperation::generate_denoise(MemoryBuffer *output,
}
void DenoiseOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!output_rendered_) {
@@ -304,7 +304,7 @@ void DenoisePrefilterOperation::generate_denoise(MemoryBuffer *output, MemoryBuf
}
void DenoisePrefilterOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc
index cfc437a6324..a0c82ad531c 100644
--- a/source/blender/compositor/operations/COM_DespeckleOperation.cc
+++ b/source/blender/compositor/operations/COM_DespeckleOperation.cc
@@ -99,7 +99,7 @@ void DespeckleOperation::execute_pixel(float output[4], int x, int y, void * /*d
input_operation_->read(in1, x3, y3, nullptr);
COLOR_ADD(TOT_DIV_CNR)
- mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
+ mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2))));
// mul_v4_fl(color_mid, 1.0f / w);
if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) &&
@@ -214,7 +214,7 @@ void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output,
in1 = image->get_elem(x3, y3);
COLOR_ADD(TOT_DIV_CNR)
- mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2)));
+ mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2))));
// mul_v4_fl(color_mid, 1.0f / w);
if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) &&
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cc b/source/blender/compositor/operations/COM_DilateErodeOperation.cc
index a93571ebee4..9a2d5e09b33 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cc
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cc
@@ -181,8 +181,8 @@ static float get_min_distance(DilateErodeThresholdOperation::PixelData &p)
* true. */
const TCompare compare;
float min_dist = p.distance;
- const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride +
- ((intptr_t)p.xmin - p.x) * p.elem_stride;
+ const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride +
+ (intptr_t(p.xmin) - p.x) * p.elem_stride;
for (int yi = p.ymin; yi < p.ymax; yi++) {
const float dy = yi - p.y;
const float dist_y = dy * dy;
@@ -410,8 +410,8 @@ static float get_distance_value(DilateDistanceOperation::PixelData &p, const flo
const TCompare compare;
const float min_dist = p.min_distance;
float value = start_value;
- const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride +
- ((intptr_t)p.xmin - p.x) * p.elem_stride;
+ const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride +
+ (intptr_t(p.xmin) - p.x) * p.elem_stride;
for (int yi = p.ymin; yi < p.ymax; yi++) {
const float dy = yi - p.y;
const float dist_y = dy * dy;
diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
index 37e05de33db..5e292fa12c2 100644
--- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc
@@ -30,7 +30,7 @@ void DirectionalBlurOperation::init_execution()
const float height = get_height();
const float a = angle;
- const float itsc = 1.0f / powf(2.0f, (float)iterations);
+ const float itsc = 1.0f / powf(2.0f, float(iterations));
float D;
D = distance * sqrtf(width * width + height * height);
@@ -128,7 +128,7 @@ bool DirectionalBlurOperation::determine_depending_area_of_interest(
}
void DirectionalBlurOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc
index 198cca0482e..1aec8e12242 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cc
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cc
@@ -113,7 +113,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][0] *= numinv;
r_deriv[1][0] *= numinv;
}
@@ -130,7 +130,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][1] *= numinv;
r_deriv[1][1] *= numinv;
}
@@ -209,8 +209,8 @@ void DisplaceOperation::get_area_of_interest(const int input_idx,
}
}
-void DisplaceOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void DisplaceOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
MemoryBuffer *vector = inputs[1];
@@ -227,7 +227,7 @@ void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
{
const MemoryBuffer *input_color = inputs[0];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- const float xy[2] = {(float)it.x, (float)it.y};
+ const float xy[2] = {float(it.x), float(it.y)};
float uv[2];
float deriv[2][2];
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
index ea156cd19db..e120dd5f41a 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc
@@ -8,18 +8,13 @@
namespace blender::compositor {
/* This part has been copied from the double edge mask. */
-static void do_adjacentKeepBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_adjacentKeepBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -178,18 +173,13 @@ static void do_adjacentKeepBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_adjacentBleedBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_adjacentBleedBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -403,18 +393,13 @@ static void do_adjacentBleedBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allKeepBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_allKeepBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners. */
/* Upper left corner. */
x = t - rw + 1;
@@ -565,18 +550,13 @@ static void do_allKeepBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allBleedBorders(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
- float *res,
- unsigned int *rsize)
+static void do_allBleedBorders(
+ uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize)
{
int x;
- unsigned int isz = 0; /* Inner edge size. */
- unsigned int osz = 0; /* Outer edge size. */
- unsigned int gsz = 0; /* Gradient fill area size. */
+ uint isz = 0; /* Inner edge size. */
+ uint osz = 0; /* Outer edge size. */
+ uint gsz = 0; /* Gradient fill area size. */
/* Test the four corners */
/* Upper left corner. */
x = t - rw + 1;
@@ -782,16 +762,16 @@ static void do_allBleedBorders(unsigned int t,
rsize[2] = gsz;
}
-static void do_allEdgeDetection(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
+static void do_allEdgeDetection(uint t,
+ uint rw,
+ const uint *limask,
+ const uint *lomask,
+ uint *lres,
float *res,
- unsigned int *rsize,
- unsigned int in_isz,
- unsigned int in_osz,
- unsigned int in_gsz)
+ uint *rsize,
+ uint in_isz,
+ uint in_osz,
+ uint in_gsz)
{
int x; /* Pixel loop counter. */
int a; /* Pixel loop counter. */
@@ -812,7 +792,7 @@ static void do_allEdgeDetection(unsigned int t,
if (!limask[a]) { /* If the inner mask is empty. */
if (lomask[a]) { /* If the outer mask is full. */
/*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
+ * Next we test all 4 directions around the current pixel: next/previous/up/down
* The test ensures that the outer mask is empty and that the inner mask
* is also empty. If both conditions are true for any one of the 4 adjacent pixels
* then the current pixel is counted as being a true outer edge pixel.
@@ -853,16 +833,16 @@ static void do_allEdgeDetection(unsigned int t,
rsize[2] = in_gsz;
}
-static void do_adjacentEdgeDetection(unsigned int t,
- unsigned int rw,
- const unsigned int *limask,
- const unsigned int *lomask,
- unsigned int *lres,
+static void do_adjacentEdgeDetection(uint t,
+ uint rw,
+ const uint *limask,
+ const uint *lomask,
+ uint *lres,
float *res,
- unsigned int *rsize,
- unsigned int in_isz,
- unsigned int in_osz,
- unsigned int in_gsz)
+ uint *rsize,
+ uint in_isz,
+ uint in_osz,
+ uint in_gsz)
{
int x; /* Pixel loop counter. */
int a; /* Pixel loop counter. */
@@ -882,7 +862,7 @@ static void do_adjacentEdgeDetection(unsigned int t,
if (!limask[a]) { /* If the inner mask is empty. */
if (lomask[a]) { /* If the outer mask is full. */
/*
- * Next we test all 4 directions around the current pixel: next/prev/up/down
+ * Next we test all 4 directions around the current pixel: next/previous/up/down
* The test ensures that the outer mask is empty and that the inner mask
* is also empty. If both conditions are true for any one of the 4 adjacent pixels
* then the current pixel is counted as being a true outer edge pixel.
@@ -925,30 +905,30 @@ static void do_adjacentEdgeDetection(unsigned int t,
rsize[2] = in_gsz;
}
-static void do_createEdgeLocationBuffer(unsigned int t,
- unsigned int rw,
- const unsigned int *lres,
+static void do_createEdgeLocationBuffer(uint t,
+ uint rw,
+ const uint *lres,
float *res,
- unsigned short *gbuf,
- unsigned int *inner_edge_offset,
- unsigned int *outer_edge_offset,
- unsigned int isz,
- unsigned int gsz)
+ ushort *gbuf,
+ uint *inner_edge_offset,
+ uint *outer_edge_offset,
+ uint isz,
+ uint gsz)
{
- int x; /* Pixel loop counter. */
- int a; /* Temporary pixel index buffer loop counter. */
- unsigned int ud; /* Unscaled edge distance. */
- unsigned int dmin; /* Minimum edge distance. */
+ int x; /* Pixel loop counter. */
+ int a; /* Temporary pixel index buffer loop counter. */
+ uint ud; /* Unscaled edge distance. */
+ uint dmin; /* Minimum edge distance. */
- unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */
- unsigned int gradient_fill_offset;
+ uint rsl; /* Long used for finding fast `1.0/sqrt`. */
+ uint gradient_fill_offset;
/* For looping inner edge pixel indexes, represents current position from offset. */
- unsigned int inner_accum = 0;
+ uint inner_accum = 0;
/* For looping outer edge pixel indexes, represents current position from offset. */
- unsigned int outer_accum = 0;
+ uint outer_accum = 0;
/* For looping gradient pixel indexes, represents current position from offset. */
- unsigned int gradient_accum = 0;
+ uint gradient_accum = 0;
/* Disable clang-format to prevent line-wrapping. */
/* clang-format off */
@@ -958,12 +938,12 @@ static void do_createEdgeLocationBuffer(unsigned int t,
* or outer edge.
*
* Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even
- * though gbuf[] is declared as (unsigned short *) (2 bytes) because we don't
+ * though gbuf[] is declared as `(ushort *)` (2 bytes) because we don't
* store the pixel indexes, we only store x,y location of pixel in buffer.
*
* This does make the assumption that x and y can fit in 16 unsigned bits
* so if Blender starts doing renders greater than 65536 in either direction
- * this will need to allocate gbuf[] as unsigned int *and allocate 8 bytes
+ * this will need to allocate gbuf[] as uint *and allocate 8 bytes
* per flagged pixel.
*
* In general, the buffer on-screen:
@@ -1028,20 +1008,20 @@ static void do_createEdgeLocationBuffer(unsigned int t,
for (rsl = 0; rsl < rw; rsl++) {
a = x + rsl;
if (lres[a] == 2) { /* It is a gradient pixel flagged by 2. */
- ud = gradient_accum << 1; /* Double the index to reach correct unsigned short location. */
+ ud = gradient_accum << 1; /* Double the index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into gradient pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into gradient pixel location buffer. */
gradient_accum++; /* Increment gradient index buffer pointer. */
}
else if (lres[a] == 3) { /* It is an outer edge pixel flagged by 3. */
- ud = outer_accum << 1; /* Double the index to reach correct unsigned short location. */
+ ud = outer_accum << 1; /* Double the index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into outer edge pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into outer edge pixel location buffer. */
outer_accum++; /* Increment outer edge index buffer pointer. */
res[a] = 0.0f; /* Set output pixel intensity now since it won't change later. */
}
else if (lres[a] == 4) { /* It is an inner edge pixel flagged by 4. */
- ud = inner_accum << 1; /* Double int index to reach correct unsigned short location. */
+ ud = inner_accum << 1; /* Double int index to reach correct ushort location. */
gbuf[ud] = dmin; /* Insert pixel's row into inner edge pixel location buffer. */
gbuf[ud + 1] = rsl; /* Insert pixel's column into inner edge pixel location buffer. */
inner_accum++; /* Increment inner edge index buffer pointer. */
@@ -1051,30 +1031,30 @@ static void do_createEdgeLocationBuffer(unsigned int t,
}
}
-static void do_fillGradientBuffer(unsigned int rw,
+static void do_fillGradientBuffer(uint rw,
float *res,
- const unsigned short *gbuf,
- unsigned int isz,
- unsigned int osz,
- unsigned int gsz,
- unsigned int inner_edge_offset,
- unsigned int outer_edge_offset)
+ const ushort *gbuf,
+ uint isz,
+ uint osz,
+ uint gsz,
+ uint inner_edge_offset,
+ uint outer_edge_offset)
{
int x; /* Pixel loop counter. */
int a; /* Temporary pixel index buffer loop counter. */
int fsz; /* Size of the frame. */
- unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */
+ uint rsl; /* Long used for finding fast `1.0/sqrt`. */
float rsf; /* Float used for finding fast `1.0/sqrt`. */
const float rsopf = 1.5f; /* Constant float used for finding fast `1.0/sqrt`. */
- unsigned int gradient_fill_offset;
- unsigned int t;
- unsigned int ud; /* Unscaled edge distance. */
- unsigned int dmin; /* Minimum edge distance. */
- float odist; /* Current outer edge distance. */
- float idist; /* Current inner edge distance. */
- int dx; /* X-delta (used for distance proportion calculation) */
- int dy; /* Y-delta (used for distance proportion calculation) */
+ uint gradient_fill_offset;
+ uint t;
+ uint ud; /* Unscaled edge distance. */
+ uint dmin; /* Minimum edge distance. */
+ float odist; /* Current outer edge distance. */
+ float idist; /* Current inner edge distance. */
+ int dx; /* X-delta (used for distance proportion calculation) */
+ int dy; /* Y-delta (used for distance proportion calculation) */
/*
* The general algorithm used to color each gradient pixel is:
@@ -1150,10 +1130,10 @@ static void do_fillGradientBuffer(unsigned int rw,
dmin = ud; /* Set a new minimum equal to the new lower value. */
}
}
- odist = (float)(dmin); /* Cast outer min to a float. */
+ odist = float(dmin); /* Cast outer min to a float. */
rsf = odist * 0.5f;
- rsl = *(unsigned int *)&odist; /* Use some peculiar properties of the way bits are stored. */
- rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. unsigned ints to compute an approximate. */
+ rsl = *(uint *)&odist; /* Use some peculiar properties of the way bits are stored. */
+ rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. uints to compute an approximate. */
odist = *(float *)&rsl; /* Reciprocal square root. */
odist = odist * (rsopf - (rsf * odist *
odist)); /* -- This line can be iterated for more accuracy. -- */
@@ -1171,9 +1151,9 @@ static void do_fillGradientBuffer(unsigned int rw,
}
/* Cast inner min to a float. */
- idist = (float)(dmin);
+ idist = float(dmin);
rsf = idist * 0.5f;
- rsl = *(unsigned int *)&idist;
+ rsl = *(uint *)&idist;
/* See notes above. */
rsl = 0x5f3759df - (rsl >> 1);
@@ -1195,24 +1175,22 @@ static void do_fillGradientBuffer(unsigned int rw,
void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, float *res)
{
- unsigned int *lres; /* Pointer to output pixel buffer (for bit operations). */
- unsigned int *limask; /* Pointer to inner mask (for bit operations). */
- unsigned int *lomask; /* Pointer to outer mask (for bit operations). */
+ uint *lres; /* Pointer to output pixel buffer (for bit operations). */
+ uint *limask; /* Pointer to inner mask (for bit operations). */
+ uint *lomask; /* Pointer to outer mask (for bit operations). */
int rw; /* Pixel row width. */
int t; /* Total number of pixels in buffer - 1 (used for loop starts). */
int fsz; /* Size of the frame. */
- unsigned int isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */
- unsigned int osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */
- unsigned int gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */
- unsigned int rsize[3]; /* Size storage to pass to helper functions. */
- unsigned int inner_edge_offset =
- 0; /* Offset into final buffer where inner edge pixel indexes start. */
- unsigned int outer_edge_offset =
- 0; /* Offset into final buffer where outer edge pixel indexes start. */
+ uint isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */
+ uint osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */
+ uint gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */
+ uint rsize[3]; /* Size storage to pass to helper functions. */
+ uint inner_edge_offset = 0; /* Offset into final buffer where inner edge pixel indexes start. */
+ uint outer_edge_offset = 0; /* Offset into final buffer where outer edge pixel indexes start. */
- unsigned short *gbuf; /* Gradient/inner/outer pixel location index buffer. */
+ ushort *gbuf; /* Gradient/inner/outer pixel location index buffer. */
if (true) { /* If both input sockets have some data coming in... */
@@ -1223,9 +1201,9 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl
sizeof(float) *
(t + 1)); /* Clear output buffer (not all pixels will be written later). */
- lres = (unsigned int *)res; /* Pointer to output buffer (for bit level ops).. */
- limask = (unsigned int *)imask; /* Pointer to input mask (for bit level ops).. */
- lomask = (unsigned int *)omask; /* Pointer to output mask (for bit level ops).. */
+ lres = (uint *)res; /* Pointer to output buffer (for bit level ops).. */
+ limask = (uint *)imask; /* Pointer to input mask (for bit level ops).. */
+ lomask = (uint *)omask; /* Pointer to output mask (for bit level ops).. */
/*
* The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the
@@ -1291,7 +1269,7 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl
/* Calculate size of pixel index buffer needed. */
fsz = gsz + isz + osz;
/* Allocate edge/gradient pixel index buffer. */
- gbuf = (unsigned short *)MEM_callocN(sizeof(unsigned short) * fsz * 2, "DEM");
+ gbuf = (ushort *)MEM_callocN(sizeof(ushort) * fsz * 2, "DEM");
do_createEdgeLocationBuffer(
t, rw, lres, res, gbuf, &inner_edge_offset, &outer_edge_offset, isz, gsz);
@@ -1376,15 +1354,15 @@ void DoubleEdgeMaskOperation::deinit_execution()
}
}
-void DoubleEdgeMaskOperation::get_area_of_interest(int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void DoubleEdgeMaskOperation::get_area_of_interest(int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
}
void DoubleEdgeMaskOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!is_output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
index 508e5ea5712..064163801ea 100644
--- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
+++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc
@@ -19,10 +19,10 @@ void EllipseMaskOperation::init_execution()
{
input_mask_ = this->get_input_socket_reader(0);
input_value_ = this->get_input_socket_reader(1);
- const double rad = (double)data_->rotation;
+ const double rad = double(data_->rotation);
cosine_ = cos(rad);
sine_ = sin(rad);
- aspect_ratio_ = ((float)this->get_width()) / this->get_height();
+ aspect_ratio_ = float(this->get_width()) / this->get_height();
}
void EllipseMaskOperation::execute_pixel_sampled(float output[4],
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
index 725751d15af..7557d1bc4bd 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
@@ -102,18 +102,15 @@ void *FastGaussianBlurOperation::initialize_tile_data(rcti *rect)
return iirgaus_;
}
-void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
- float sigma,
- unsigned int chan,
- unsigned int xy)
+void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, uint chan, uint xy)
{
BLI_assert(!src->is_a_single_elem());
double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
double *X, *Y, *W;
- const unsigned int src_width = src->get_width();
- const unsigned int src_height = src->get_height();
- unsigned int x, y, src_dim_max;
- unsigned int i;
+ const uint src_width = src->get_width();
+ const uint src_height = src->get_height();
+ uint x, y, src_dim_max;
+ uint i;
float *buffer = src->get_buffer();
const uint8_t num_channels = src->get_num_channels();
@@ -194,7 +191,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src,
Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \
Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \
Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \
- /* 'i != UINT_MAX' is really 'i >= 0', but necessary for unsigned int wrapping */ \
+ /* `i != UINT_MAX` is really `i >= 0`, but necessary for `uint` wrapping. */ \
for (i = L - 4; i != UINT_MAX; i--) { \
Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \
} \
@@ -387,15 +384,15 @@ void *FastGaussianBlurValueOperation::initialize_tile_data(rcti *rect)
return iirgaus_;
}
-void FastGaussianBlurValueOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void FastGaussianBlurValueOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
}
-void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (iirgaus_ == nullptr) {
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
index 157d3c7f32f..0f7064c19a5 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
@@ -31,9 +31,9 @@ class FastGaussianBlurOperation : public BlurBaseOperation {
void update_memory_buffer_started(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
- void update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
- Span<MemoryBuffer *> UNUSED(inputs)) override
+ void update_memory_buffer_partial(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
+ Span<MemoryBuffer *> /*inputs*/) override
{
}
};
diff --git a/source/blender/compositor/operations/COM_FlipOperation.cc b/source/blender/compositor/operations/COM_FlipOperation.cc
index 369f124622a..3d9d574b89d 100644
--- a/source/blender/compositor/operations/COM_FlipOperation.cc
+++ b/source/blender/compositor/operations/COM_FlipOperation.cc
@@ -26,8 +26,8 @@ void FlipOperation::deinit_execution()
void FlipOperation::execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler)
{
- float nx = flip_x_ ? ((int)this->get_width() - 1) - x : x;
- float ny = flip_y_ ? ((int)this->get_height() - 1) - y : y;
+ float nx = flip_x_ ? (int(this->get_width()) - 1) - x : x;
+ float ny = flip_y_ ? (int(this->get_height()) - 1) - y : y;
input_operation_->read_sampled(output, nx, ny, sampler);
}
@@ -39,7 +39,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input,
rcti new_input;
if (flip_x_) {
- const int w = (int)this->get_width() - 1;
+ const int w = int(this->get_width()) - 1;
new_input.xmax = (w - input->xmin) + 1;
new_input.xmin = (w - input->xmax) - 1;
}
@@ -48,7 +48,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input,
new_input.xmax = input->xmax;
}
if (flip_y_) {
- const int h = (int)this->get_height() - 1;
+ const int h = int(this->get_height()) - 1;
new_input.ymax = (h - input->ymin) + 1;
new_input.ymin = (h - input->ymax) - 1;
}
@@ -85,7 +85,7 @@ void FlipOperation::get_area_of_interest(const int input_idx,
BLI_assert(input_idx == 0);
UNUSED_VARS_NDEBUG(input_idx);
if (flip_x_) {
- const int w = (int)this->get_width() - 1;
+ const int w = int(this->get_width()) - 1;
r_input_area.xmax = (w - output_area.xmin) + 1;
r_input_area.xmin = (w - output_area.xmax) + 1;
}
@@ -94,7 +94,7 @@ void FlipOperation::get_area_of_interest(const int input_idx,
r_input_area.xmax = output_area.xmax;
}
if (flip_y_) {
- const int h = (int)this->get_height() - 1;
+ const int h = int(this->get_height()) - 1;
r_input_area.ymax = (h - output_area.ymin) + 1;
r_input_area.ymin = (h - output_area.ymax) + 1;
}
@@ -112,8 +112,8 @@ void FlipOperation::update_memory_buffer_partial(MemoryBuffer *output,
const int input_offset_x = input_img->get_rect().xmin;
const int input_offset_y = input_img->get_rect().ymin;
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- const int nx = flip_x_ ? ((int)this->get_width() - 1) - it.x : it.x;
- const int ny = flip_y_ ? ((int)this->get_height() - 1) - it.y : it.y;
+ const int nx = flip_x_ ? (int(this->get_width()) - 1) - it.x : it.x;
+ const int ny = flip_y_ ? (int(this->get_height()) - 1) - it.y : it.y;
input_img->read_elem(input_offset_x + nx, input_offset_y + ny, it.out);
}
}
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
index f380abf42f0..75b2249b6a7 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
@@ -114,7 +114,7 @@ void GaussianAlphaBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *
float distfacinv_max = 1.0f; /* 0 to 1 */
const int step = QualityStepHelper::get_step();
- const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride;
+ const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
const int in_stride = elem_stride * step;
int index = (coord_min - coord) + filtersize_;
const int index_end = index + (coord_max - coord_min);
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
index 49669d70177..4a589d45275 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
@@ -73,7 +73,7 @@ void GaussianAlphaXBlurOperation::execute_pixel(float output[4], int x, int y, v
/* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
int step = get_step();
- int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
+ int bufferindex = (xmin - bufferstartx) + ((ymin - bufferstarty) * bufferwidth);
/* gauss */
float alpha_accum = 0.0f;
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
index 0e73299f58e..e9ff756093c 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
@@ -86,7 +86,7 @@ void GaussianAlphaYBlurOperation::execute_pixel(float output[4], int x, int y, v
float distfacinv_max = 1.0f; /* 0 to 1 */
for (int ny = ymin; ny < ymax; ny += step) {
- int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth);
+ int bufferindex = (xmin - bufferstartx) + ((ny - bufferstarty) * bufferwidth);
const int index = (ny - y) + filtersize_;
float value = finv_test(buffer[bufferindex], do_invert);
diff --git a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
index 3c66f74f284..b2b10e77012 100644
--- a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
@@ -112,7 +112,7 @@ void GaussianBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *outpu
float multiplier_accum = 0.0f;
const int step = QualityStepHelper::get_step();
- const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride;
+ const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
const int in_stride = elem_stride * step;
int gauss_idx = (coord_min - coord) + filtersize_;
const int gauss_end = gauss_idx + (coord_max - coord_min);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
index fa45034b00c..039e6a9bcc0 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
@@ -35,11 +35,11 @@ void GaussianBokehBlurOperation::init_data()
}
}
- radxf_ = size_ * (float)data_.sizex;
+ radxf_ = size_ * float(data_.sizex);
CLAMP(radxf_, 0.0f, width / 2.0f);
/* Vertical. */
- radyf_ = size_ * (float)data_.sizey;
+ radyf_ = size_ * float(data_.sizey);
CLAMP(radyf_, 0.0f, height / 2.0f);
radx_ = ceil(radxf_);
@@ -71,8 +71,8 @@ void GaussianBokehBlurOperation::update_gauss()
float facy = (radyf_ > 0.0f ? 1.0f / radyf_ : 0.0f);
for (int j = -rady_; j <= rady_; j++) {
for (int i = -radx_; i <= radx_; i++, dgauss++) {
- float fj = (float)j * facy;
- float fi = (float)i * facx;
+ float fj = float(j) * facy;
+ float fi = float(i) * facx;
float dist = sqrt(fj * fj + fi * fi);
*dgauss = RE_filter_value(data_.filtertype, dist);
@@ -105,10 +105,10 @@ void GaussianBokehBlurOperation::execute_pixel(float output[4], int x, int y, vo
const float width = this->get_width();
const float height = this->get_height();
- radxf_ = size_ * (float)data_.sizex;
+ radxf_ = size_ * float(data_.sizex);
CLAMP(radxf_, 0.0f, width / 2.0f);
- radyf_ = size_ * (float)data_.sizey;
+ radyf_ = size_ * float(data_.sizey);
CLAMP(radyf_, 0.0f, height / 2.0f);
radx_ = ceil(radxf_);
@@ -265,22 +265,22 @@ void GaussianBlurReferenceOperation::init_data()
if (data_.relative) {
switch (data_.aspect) {
case CMP_NODE_BLUR_ASPECT_NONE:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height);
break;
case CMP_NODE_BLUR_ASPECT_Y:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_width);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_width);
break;
case CMP_NODE_BLUR_ASPECT_X:
- data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_height);
- data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height);
+ data_.sizex = int(data_.percentx * 0.01f * data_.image_in_height);
+ data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height);
break;
}
}
/* Horizontal. */
- filtersizex_ = (float)data_.sizex;
+ filtersizex_ = float(data_.sizex);
int imgx = get_width() / 2;
if (filtersizex_ > imgx) {
filtersizex_ = imgx;
@@ -288,10 +288,10 @@ void GaussianBlurReferenceOperation::init_data()
else if (filtersizex_ < 1) {
filtersizex_ = 1;
}
- radx_ = (float)filtersizex_;
+ radx_ = float(filtersizex_);
/* Vertical. */
- filtersizey_ = (float)data_.sizey;
+ filtersizey_ = float(data_.sizey);
int imgy = get_height() / 2;
if (filtersizey_ > imgy) {
filtersizey_ = imgy;
@@ -299,7 +299,7 @@ void GaussianBlurReferenceOperation::init_data()
else if (filtersizey_ < 1) {
filtersizey_ = 1;
}
- rady_ = (float)filtersizey_;
+ rady_ = float(filtersizey_);
}
void *GaussianBlurReferenceOperation::initialize_tile_data(rcti * /*rect*/)
@@ -340,8 +340,8 @@ void GaussianBlurReferenceOperation::execute_pixel(float output[4], int x, int y
float temp_size[4];
input_size_->read(temp_size, x, y, data);
float ref_size = temp_size[0];
- int refradx = (int)(ref_size * radx_);
- int refrady = (int)(ref_size * rady_);
+ int refradx = int(ref_size * radx_);
+ int refrady = int(ref_size * rady_);
if (refradx > filtersizex_) {
refradx = filtersizex_;
}
@@ -447,8 +447,8 @@ void GaussianBlurReferenceOperation::update_memory_buffer_partial(MemoryBuffer *
MemoryBuffer *size_input = inputs[SIZE_INPUT_INDEX];
for (BuffersIterator<float> it = output->iterate_with({size_input}, area); !it.is_end(); ++it) {
const float ref_size = *it.in(0);
- int ref_radx = (int)(ref_size * radx_);
- int ref_rady = (int)(ref_size * rady_);
+ int ref_radx = int(ref_size * radx_);
+ int ref_rady = int(ref_size * rady_);
if (ref_radx > filtersizex_) {
ref_radx = filtersizex_;
}
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cc b/source/blender/compositor/operations/COM_GlareBaseOperation.cc
index 13f55b5909c..93d3c2063ae 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cc
@@ -56,7 +56,7 @@ bool GlareBaseOperation::determine_depending_area_of_interest(rcti * /*input*/,
}
void GlareBaseOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
@@ -68,7 +68,7 @@ void GlareBaseOperation::get_area_of_interest(const int input_idx,
}
void GlareBaseOperation::update_memory_buffer(MemoryBuffer *output,
- const rcti &UNUSED(area),
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (!is_output_rendered_) {
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
index ade3f11a8b3..4f7b1be9057 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc
@@ -12,9 +12,9 @@ namespace blender::compositor {
using fREAL = float;
/* Returns next highest power of 2 of x, as well its log2 in L2. */
-static unsigned int next_pow2(unsigned int x, unsigned int *L2)
+static uint next_pow2(uint x, uint *L2)
{
- unsigned int pw, x_notpow2 = x & (x - 1);
+ uint pw, x_notpow2 = x & (x - 1);
*L2 = 0;
while (x >>= 1) {
++(*L2);
@@ -31,7 +31,7 @@ static unsigned int next_pow2(unsigned int x, unsigned int *L2)
/* From FXT library by Joerg Arndt, faster in order bit-reversal
* use: `r = revbin_upd(r, h)` where `h = N>>1`. */
-static unsigned int revbin_upd(unsigned int r, unsigned int h)
+static uint revbin_upd(uint r, uint h)
{
while (!((r ^= h) & h)) {
h >>= 1;
@@ -39,14 +39,14 @@ static unsigned int revbin_upd(unsigned int r, unsigned int h)
return r;
}
//------------------------------------------------------------------------------
-static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
+static void FHT(fREAL *data, uint M, uint inverse)
{
double tt, fc, dc, fs, ds, a = M_PI;
fREAL t1, t2;
int n2, bd, bl, istep, k, len = 1 << M, n = 1;
int i, j = 0;
- unsigned int Nh = len >> 1;
+ uint Nh = len >> 1;
for (i = 1; i < (len - 1); i++) {
j = revbin_upd(j, Nh);
if (j > i) {
@@ -75,8 +75,8 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
fREAL *data_nbd = &data_n[bd];
fREAL *data_bd = &data[bd];
for (k = bl; k < len; k += istep) {
- t1 = fc * (double)data_n[k] + fs * (double)data_nbd[k];
- t2 = fs * (double)data_n[k] - fc * (double)data_nbd[k];
+ t1 = fc * double(data_n[k]) + fs * double(data_nbd[k]);
+ t2 = fs * double(data_n[k]) - fc * double(data_nbd[k]);
data_n[k] = data[k] - t1;
data_nbd[k] = data_bd[k] - t2;
data[k] += t1;
@@ -112,10 +112,9 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse)
/* 2D Fast Hartley Transform, Mx/My -> log2 of width/height,
* nzp -> the row where zero pad data starts,
* inverse -> see above. */
-static void FHT2D(
- fREAL *data, unsigned int Mx, unsigned int My, unsigned int nzp, unsigned int inverse)
+static void FHT2D(fREAL *data, uint Mx, uint My, uint nzp, uint inverse)
{
- unsigned int i, j, Nx, Ny, maxy;
+ uint i, j, Nx, Ny, maxy;
Nx = 1 << Mx;
Ny = 1 << My;
@@ -130,13 +129,13 @@ static void FHT2D(
if (Nx == Ny) { /* Square. */
for (j = 0; j < Ny; j++) {
for (i = j + 1; i < Nx; i++) {
- unsigned int op = i + (j << Mx), np = j + (i << My);
+ uint op = i + (j << Mx), np = j + (i << My);
SWAP(fREAL, data[op], data[np]);
}
}
}
else { /* Rectangular. */
- unsigned int k, Nym = Ny - 1, stm = 1 << (Mx + My);
+ uint k, Nym = Ny - 1, stm = 1 << (Mx + My);
for (i = 0; stm > 0; i++) {
#define PRED(k) (((k & Nym) << Mx) + (k >> My))
for (j = PRED(i); j > i; j = PRED(j)) {
@@ -153,8 +152,8 @@ static void FHT2D(
}
}
- SWAP(unsigned int, Nx, Ny);
- SWAP(unsigned int, Mx, My);
+ SWAP(uint, Nx, Ny);
+ SWAP(uint, Mx, My);
/* Now columns == transposed rows. */
for (j = 0; j < Ny; j++) {
@@ -163,11 +162,11 @@ static void FHT2D(
/* Finalize. */
for (j = 0; j <= (Ny >> 1); j++) {
- unsigned int jm = (Ny - j) & (Ny - 1);
- unsigned int ji = j << Mx;
- unsigned int jmi = jm << Mx;
+ uint jm = (Ny - j) & (Ny - 1);
+ uint ji = j << Mx;
+ uint jmi = jm << Mx;
for (i = 0; i <= (Nx >> 1); i++) {
- unsigned int im = (Nx - i) & (Nx - 1);
+ uint im = (Nx - i) & (Nx - 1);
fREAL A = data[ji + i];
fREAL B = data[jmi + i];
fREAL C = data[ji + im];
@@ -184,13 +183,13 @@ static void FHT2D(
//------------------------------------------------------------------------------
/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height. */
-static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned int N)
+static void fht_convolve(fREAL *d1, const fREAL *d2, uint M, uint N)
{
fREAL a, b;
- unsigned int i, j, k, L, mj, mL;
- unsigned int m = 1 << M, n = 1 << N;
- unsigned int m2 = 1 << (M - 1), n2 = 1 << (N - 1);
- unsigned int mn2 = m << (N - 1);
+ uint i, j, k, L, mj, mL;
+ uint m = 1 << M, n = 1 << N;
+ uint m2 = 1 << (M - 1), n2 = 1 << (N - 1);
+ uint mn2 = m << (N - 1);
d1[0] *= d2[0];
d1[mn2] *= d2[mn2];
@@ -242,15 +241,15 @@ static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned in
static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
{
fREAL *data1, *data2, *fp;
- unsigned int w2, h2, hw, hh, log2_w, log2_h;
+ uint w2, h2, hw, hh, log2_w, log2_h;
fRGB wt, *colp;
int x, y, ch;
int xbl, ybl, nxb, nyb, xbsz, ybsz;
bool in2done = false;
- const unsigned int kernel_width = in2->get_width();
- const unsigned int kernel_height = in2->get_height();
- const unsigned int image_width = in1->get_width();
- const unsigned int image_height = in1->get_height();
+ const uint kernel_width = in2->get_width();
+ const uint kernel_height = in2->get_height();
+ const uint image_width = in1->get_width();
+ const uint image_height = in1->get_height();
float *kernel_buffer = in2->get_buffer();
float *image_buffer = in1->get_buffer();
@@ -361,14 +360,14 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
/* Data again transposed, so in order again. */
/* Overlap-add result. */
- for (y = 0; y < (int)h2; y++) {
+ for (y = 0; y < int(h2); y++) {
const int yy = ybl * ybsz + y - hh;
if ((yy < 0) || (yy >= image_height)) {
continue;
}
fp = &data2[y * w2];
colp = (fRGB *)&rdst->get_buffer()[yy * image_width * COM_DATA_TYPE_COLOR_CHANNELS];
- for (x = 0; x < (int)w2; x++) {
+ for (x = 0; x < int(w2); x++) {
const int xx = xbl * xbsz + x - hw;
if ((xx < 0) || (xx >= image_width)) {
continue;
@@ -397,7 +396,7 @@ void GlareFogGlowOperation::generate_glare(float *data,
float scale, u, v, r, w, d;
fRGB fcol;
MemoryBuffer *ckrn;
- unsigned int sz = 1 << settings->size;
+ uint sz = 1 << settings->size;
const float cs_r = 1.0f, cs_g = 1.0f, cs_b = 1.0f;
/* Temp. src image
@@ -406,12 +405,12 @@ void GlareFogGlowOperation::generate_glare(float *data,
BLI_rcti_init(&kernel_rect, 0, sz, 0, sz);
ckrn = new MemoryBuffer(DataType::Color, kernel_rect);
- scale = 0.25f * sqrtf((float)(sz * sz));
+ scale = 0.25f * sqrtf(float(sz * sz));
for (y = 0; y < sz; y++) {
- v = 2.0f * (y / (float)sz) - 1.0f;
+ v = 2.0f * (y / float(sz)) - 1.0f;
for (x = 0; x < sz; x++) {
- u = 2.0f * (x / (float)sz) - 1.0f;
+ u = 2.0f * (x / float(sz)) - 1.0f;
r = (u * u + v * v) * scale;
d = -sqrtf(sqrtf(sqrtf(r))) * 9.0f;
fcol[0] = expf(d * cs_r);
@@ -420,7 +419,7 @@ void GlareFogGlowOperation::generate_glare(float *data,
/* Linear window good enough here, visual result counts, not scientific analysis:
* `w = (1.0f-fabs(u))*(1.0f-fabs(v));`
* actually, Hanning window is ok, `cos^2` for some reason is slower. */
- w = (0.5f + 0.5f * cosf(u * (float)M_PI)) * (0.5f + 0.5f * cosf(v * (float)M_PI));
+ w = (0.5f + 0.5f * cosf(u * float(M_PI))) * (0.5f + 0.5f * cosf(v * float(M_PI)));
mul_v3_fl(fcol, w);
ckrn->write_pixel(x, y, fcol);
}
diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cc b/source/blender/compositor/operations/COM_GlareGhostOperation.cc
index 13b7af2329e..5ba0901231d 100644
--- a/source/blender/compositor/operations/COM_GlareGhostOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cc
@@ -23,7 +23,7 @@ void GlareGhostOperation::generate_glare(float *data,
const NodeGlare *settings)
{
const int qt = 1 << settings->quality;
- const float s1 = 4.0f / (float)qt, s2 = 2.0f * s1;
+ const float s1 = 4.0f / float(qt), s2 = 2.0f * s1;
int x, y, n, p, np;
fRGB c, tc, cm[64];
float sc, isc, u, v, sm, s, t, ofs, scalef[64];
@@ -79,7 +79,7 @@ void GlareGhostOperation::generate_glare(float *data,
if (y == 3) {
fRGB_rgbmult(cm[x], cmo, 1.0f, cmo);
}
- scalef[x] = 2.1f * (1.0f - (x + ofs) / (float)(settings->iter * 4));
+ scalef[x] = 2.1f * (1.0f - (x + ofs) / float(settings->iter * 4));
if (x & 1) {
scalef[x] = -0.99f / scalef[x];
}
@@ -88,9 +88,9 @@ void GlareGhostOperation::generate_glare(float *data,
sc = 2.13;
isc = -0.97;
for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
- v = ((float)y + 0.5f) / (float)gbuf.get_height();
+ v = (float(y) + 0.5f) / float(gbuf.get_height());
for (x = 0; x < gbuf.get_width(); x++) {
- u = ((float)x + 0.5f) / (float)gbuf.get_width();
+ u = (float(x) + 0.5f) / float(gbuf.get_width());
s = (u - 0.5f) * sc + 0.5f;
t = (v - 0.5f) * sc + 0.5f;
tbuf1.read_bilinear(c, s * gbuf.get_width(), t * gbuf.get_height());
@@ -114,9 +114,9 @@ void GlareGhostOperation::generate_glare(float *data,
tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf.get_height() && (!breaked); y++) {
- v = ((float)y + 0.5f) / (float)gbuf.get_height();
+ v = (float(y) + 0.5f) / float(gbuf.get_height());
for (x = 0; x < gbuf.get_width(); x++) {
- u = ((float)x + 0.5f) / (float)gbuf.get_width();
+ u = (float(x) + 0.5f) / float(gbuf.get_width());
tc[0] = tc[1] = tc[2] = 0.0f;
for (p = 0; p < 4; p++) {
np = (n << 2) + p;
diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
index e4f06eb0e50..c544e13cf34 100644
--- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
+++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc
@@ -10,9 +10,9 @@ void GlareStreaksOperation::generate_glare(float *data,
const NodeGlare *settings)
{
int x, y, n;
- unsigned int nump = 0;
+ uint nump = 0;
float c1[4], c2[4], c3[4], c4[4];
- float a, ang = DEG2RADF(360.0f) / (float)settings->streaks;
+ float a, ang = DEG2RADF(360.0f) / float(settings->streaks);
int size = input_tile->get_width() * input_tile->get_height();
int size4 = size * 4;
@@ -26,14 +26,14 @@ void GlareStreaksOperation::generate_glare(float *data,
for (a = 0.0f; a < DEG2RADF(360.0f) && (!breaked); a += ang) {
const float an = a + settings->angle_ofs;
- const float vx = cos((double)an), vy = sin((double)an);
+ const float vx = cos(double(an)), vy = sin(double(an));
for (n = 0; n < settings->iter && (!breaked); n++) {
- const float p4 = pow(4.0, (double)n);
+ const float p4 = pow(4.0, double(n));
const float vxp = vx * p4, vyp = vy * p4;
- const float wt = pow((double)settings->fade, (double)p4);
+ const float wt = pow(double(settings->fade), double(p4));
/* Color-modulation amount relative to current pass. */
- const float cmo = 1.0f - (float)pow((double)settings->colmod, (double)n + 1);
+ const float cmo = 1.0f - float(pow(double(settings->colmod), double(n) + 1));
float *tdstcol = tdst.get_buffer();
for (y = 0; y < tsrc.get_height() && (!breaked); y++) {
@@ -72,7 +72,7 @@ void GlareStreaksOperation::generate_glare(float *data,
}
float *sourcebuffer = tsrc.get_buffer();
- float factor = 1.0f / (float)(6 - settings->iter);
+ float factor = 1.0f / float(6 - settings->iter);
for (int i = 0; i < size4; i += 4) {
madd_v3_v3fl(&data[i], &sourcebuffer[i], factor);
data[i + 3] = 1.0f;
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc
index a9ab414670f..e1ac5e42be3 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cc
+++ b/source/blender/compositor/operations/COM_ImageOperation.cc
@@ -90,7 +90,7 @@ void BaseImageOperation::deinit_execution()
}
}
-void BaseImageOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
ImBuf *stackbuf = get_im_buf();
@@ -120,7 +120,7 @@ static void sample_image_at_location(
}
}
else {
- unsigned char byte_color[4];
+ uchar byte_color[4];
switch (sampler) {
case PixelSampler::Nearest:
nearest_interpolation_color(ibuf, byte_color, nullptr, x, y);
@@ -155,7 +155,7 @@ void ImageOperation::execute_pixel_sampled(float output[4], float x, float y, Pi
void ImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area, true);
}
@@ -179,7 +179,7 @@ void ImageAlphaOperation::execute_pixel_sampled(float output[4],
void ImageAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
}
@@ -205,7 +205,7 @@ void ImageDepthOperation::execute_pixel_sampled(float output[4],
void ImageDepthOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (depth_buffer_) {
output->copy_from(depth_buffer_, area);
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cc b/source/blender/compositor/operations/COM_InpaintOperation.cc
index 12533c26a53..a2e02e9f045 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cc
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cc
@@ -267,7 +267,7 @@ bool InpaintSimpleOperation::determine_depending_area_of_interest(
}
void InpaintSimpleOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
index 71699f23a4b..a63789f06c3 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc
@@ -48,7 +48,7 @@ void KeyingBlurOperation::execute_pixel(float output[4], int x, int y, void *dat
}
}
- average /= (float)count;
+ average /= float(count);
output[0] = average;
}
@@ -75,7 +75,7 @@ bool KeyingBlurOperation::determine_depending_area_of_interest(rcti *input,
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void KeyingBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
+void KeyingBlurOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
index bb951aaa938..2cbdfaa6a01 100644
--- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cc
@@ -47,7 +47,7 @@ void KeyingClipOperation::execute_pixel(float output[4], int x, int y, void *dat
end_y = min_ff(y + delta - 1, buffer_height - 1);
int count = 0, total_count = (end_x - start_x + 1) * (end_y - start_y + 1) - 1;
- int threshold_count = ceil((float)total_count * 0.9f);
+ int threshold_count = ceil(float(total_count) * 0.9f);
if (delta == 0) {
ok = true;
@@ -147,7 +147,7 @@ void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output,
const int y_len = end_y - start_y;
const int total_count = x_len * y_len - 1;
- const int threshold_count = ceil((float)total_count * 0.9f);
+ const int threshold_count = ceil(float(total_count) * 0.9f);
bool ok = false;
if (delta == 0) {
ok = true;
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
index 0db9b7e6a04..5c5bf5534a7 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc
@@ -150,11 +150,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t
add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
}
else {
- unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;
+ uchar *rrgb = (uchar *)pattern_ibuf->rect;
- site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
- site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
- site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
+ site->color[0] += srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f);
+ site->color[1] += srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f);
+ site->color[2] += srgb_to_linearrgb(float(rrgb[4 * j + 2]) / 255.0f);
}
}
@@ -204,11 +204,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t
minmax_v2v2_v2(min, max, b->co);
minmax_v2v2_v2(min, max, c->co);
- rect->xmin = (int)min[0];
- rect->ymin = (int)min[1];
+ rect->xmin = int(min[0]);
+ rect->ymin = int(min[1]);
- rect->xmax = (int)max[0] + 1;
- rect->ymax = (int)max[1] + 1;
+ rect->xmax = int(max[0]) + 1;
+ rect->ymax = int(max[1]) + 1;
}
}
@@ -311,7 +311,7 @@ void KeyingScreenOperation::execute_pixel(float output[4], int x, int y, void *d
TriangulationData *triangulation = cached_triangulation_;
TileData *tile_data = (TileData *)data;
int i;
- float co[2] = {(float)x, (float)y};
+ float co[2] = {float(x), float(y)};
for (i = 0; i < tile_data->triangles_total; i++) {
int triangle_idx = tile_data->triangles[i];
@@ -356,7 +356,7 @@ void KeyingScreenOperation::update_memory_buffer_partial(MemoryBuffer *output,
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
copy_v4_v4(it.out, COM_COLOR_BLACK);
- const float co[2] = {(float)it.x, (float)it.y};
+ const float co[2] = {float(it.x), float(it.y)};
for (int i = 0; i < num_triangles; i++) {
const int triangle_idx = triangles[i];
const rcti *rect = &triangulation->triangles_AABB[triangle_idx];
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cc b/source/blender/compositor/operations/COM_MapUVOperation.cc
index 40f91a04134..c300508268e 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cc
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cc
@@ -124,7 +124,7 @@ void MapUVOperation::pixel_transform(const float xy[2],
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][0] *= numinv;
r_deriv[1][0] *= numinv;
}
@@ -141,7 +141,7 @@ void MapUVOperation::pixel_transform(const float xy[2],
num++;
}
if (num > 0) {
- float numinv = 1.0f / (float)num;
+ float numinv = 1.0f / float(num);
r_deriv[0][1] *= numinv;
r_deriv[1][1] *= numinv;
}
@@ -201,8 +201,8 @@ void MapUVOperation::get_area_of_interest(const int input_idx,
}
}
-void MapUVOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void MapUVOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
const MemoryBuffer *uv_input = inputs[UV_INPUT_INDEX];
@@ -217,7 +217,7 @@ void MapUVOperation::update_memory_buffer_partial(MemoryBuffer *output,
{
const MemoryBuffer *input_image = inputs[IMAGE_INPUT_INDEX];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- float xy[2] = {(float)it.x, (float)it.y};
+ float xy[2] = {float(it.x), float(it.y)};
float uv[2];
float deriv[2][2];
float alpha;
diff --git a/source/blender/compositor/operations/COM_MaskOperation.cc b/source/blender/compositor/operations/COM_MaskOperation.cc
index 29d0c0c2b9c..53f59f831db 100644
--- a/source/blender/compositor/operations/COM_MaskOperation.cc
+++ b/source/blender/compositor/operations/COM_MaskOperation.cc
@@ -33,7 +33,7 @@ void MaskOperation::init_execution()
}
else {
/* make a throw away copy of the mask */
- const float frame = (float)frame_number_ - frame_shutter_;
+ const float frame = float(frame_number_) - frame_shutter_;
const float frame_step = (frame_shutter_ * 2.0f) / raster_mask_handle_tot_;
float frame_iter = frame;
@@ -52,7 +52,7 @@ void MaskOperation::init_execution()
}
}
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
raster_mask_handles_[i] = BKE_maskrasterize_handle_new();
/* re-eval frame info */
@@ -76,7 +76,7 @@ void MaskOperation::init_execution()
void MaskOperation::deinit_execution()
{
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
if (raster_mask_handles_[i]) {
BKE_maskrasterize_handle_free(raster_mask_handles_[i]);
raster_mask_handles_[i] = nullptr;
@@ -118,7 +118,7 @@ void MaskOperation::execute_pixel_sampled(float output[4],
/* In case loop below fails. */
output[0] = 0.0f;
- for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) {
+ for (uint i = 0; i < raster_mask_handle_tot_; i++) {
if (raster_mask_handles_[i]) {
output[0] += BKE_maskrasterize_handle_sample(raster_mask_handles_[i], xy);
}
@@ -131,7 +131,7 @@ void MaskOperation::execute_pixel_sampled(float output[4],
void MaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
Vector<MaskRasterHandle *> handles = get_non_null_handles();
if (handles.size() == 0) {
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cc b/source/blender/compositor/operations/COM_MovieClipOperation.cc
index b62d972e807..bbc762bf667 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cc
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cc
@@ -53,7 +53,7 @@ void MovieClipBaseOperation::deinit_execution()
}
}
-void MovieClipBaseOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void MovieClipBaseOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
r_area = COM_AREA_NONE;
if (movie_clip_) {
@@ -94,7 +94,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4],
void MovieClipBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (movie_clip_buffer_) {
output->copy_from(movie_clip_buffer_, area);
@@ -126,7 +126,7 @@ void MovieClipAlphaOperation::execute_pixel_sampled(float output[4],
void MovieClipAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
if (movie_clip_buffer_) {
output->copy_from(movie_clip_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0);
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
index ea3aad20792..b89a48f2a39 100644
--- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc
@@ -81,10 +81,10 @@ void MovieDistortionOperation::execute_pixel_sampled(float output[4],
if (distortion_ != nullptr) {
/* float overscan = 0.0f; */
const float pixel_aspect = pixel_aspect_;
- const float w = (float)this->get_width() /* / (1 + overscan) */;
- const float h = (float)this->get_height() /* / (1 + overscan) */;
- const float aspx = w / (float)calibration_width_;
- const float aspy = h / (float)calibration_height_;
+ const float w = float(this->get_width()) /* / (1 + overscan) */;
+ const float h = float(this->get_height()) /* / (1 + overscan) */;
+ const float aspx = w / float(calibration_width_);
+ const float aspy = h / float(calibration_height_);
float in[2];
float out[2];
@@ -143,10 +143,10 @@ void MovieDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output
/* `float overscan = 0.0f;` */
const float pixel_aspect = pixel_aspect_;
- const float w = (float)this->get_width() /* `/ (1 + overscan)` */;
- const float h = (float)this->get_height() /* `/ (1 + overscan)` */;
- const float aspx = w / (float)calibration_width_;
- const float aspy = h / (float)calibration_height_;
+ const float w = float(this->get_width()) /* `/ (1 + overscan)` */;
+ const float h = float(this->get_height()) /* `/ (1 + overscan)` */;
+ const float aspx = w / float(calibration_width_);
+ const float aspy = h / float(calibration_height_);
float xy[2];
float distorted_xy[2];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
index 11f80c16c2f..9a825939deb 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc
@@ -37,7 +37,7 @@ ImBuf *MultilayerBaseOperation::get_im_buf()
void MultilayerBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
output->copy_from(buffer_, area);
}
@@ -93,8 +93,7 @@ void MultilayerColorOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
zero_v4(output);
}
else {
@@ -116,8 +115,7 @@ void MultilayerValueOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
output[0] = 0.0f;
}
else {
@@ -138,8 +136,7 @@ void MultilayerVectorOperation::execute_pixel_sampled(float output[4],
else {
int yi = y;
int xi = x;
- if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() ||
- (unsigned int)yi >= this->get_height()) {
+ if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) {
output[0] = 0.0f;
}
else {
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cc b/source/blender/compositor/operations/COM_NormalizeOperation.cc
index 1131fc28439..b408964c35f 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.cc
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.cc
@@ -114,15 +114,15 @@ void NormalizeOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/
/* pass */
}
-void NormalizeOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void NormalizeOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = get_input_operation(0)->get_canvas();
}
-void NormalizeOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void NormalizeOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (cached_instance_ == nullptr) {
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
index 760ed94f882..7650746e3ed 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc
@@ -74,8 +74,8 @@ void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filenam
void OutputOpenExrSingleLayerMultiViewOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
@@ -132,8 +132,8 @@ OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOpera
void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename)
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
@@ -158,7 +158,7 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename
IMB_exr_add_view(exrhandle, srv->name);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
add_exr_channels(exrhandle,
layers_[i].name,
layers_[i].datatype,
@@ -189,8 +189,8 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename
void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
@@ -207,7 +207,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
exrhandle = this->get_handle(filename);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
add_exr_channels(exrhandle,
layers_[i].name,
layers_[i].datatype,
@@ -217,7 +217,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
layers_[i].output_buffer);
}
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
/* memory can only be freed after we write all views to the file */
layers_[i].output_buffer = nullptr;
layers_[i].image_input = nullptr;
@@ -228,7 +228,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution()
IMB_exr_write_channels(exrhandle);
/* free buffer memory for all the views */
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
free_exr_channels(exrhandle, rd_, layers_[i].name, layers_[i].datatype);
}
@@ -284,8 +284,8 @@ void *OutputStereoOperation::get_handle(const char *filename)
void OutputStereoOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
void *exrhandle;
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
index e36999e5cf1..70773c1a559 100644
--- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
@@ -31,7 +31,7 @@ class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOpera
void deinit_execution() override;
};
-/* Writes inputs into OpenEXR multilayer channels. */
+/** Writes inputs into OpenEXR multi-layer channels. */
class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation {
private:
public:
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cc b/source/blender/compositor/operations/COM_OutputFileOperation.cc
index 1d22f3e8cd2..711ea787c41 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cc
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cc
@@ -150,7 +150,7 @@ int get_datatype_size(DataType datatype)
}
}
-static float *init_buffer(unsigned int width, unsigned int height, DataType datatype)
+static float *init_buffer(uint width, uint height, DataType datatype)
{
/* When initializing the tree during initial load the width and height can be zero. */
if (width != 0 && height != 0) {
@@ -165,7 +165,7 @@ static void write_buffer_rect(rcti *rect,
const bNodeTree *tree,
SocketReader *reader,
float *buffer,
- unsigned int width,
+ uint width,
DataType datatype)
{
float color[4];
@@ -242,7 +242,7 @@ void OutputSingleLayerOperation::init_execution()
output_buffer_ = init_buffer(this->get_width(), this->get_height(), datatype_);
}
-void OutputSingleLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void OutputSingleLayerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
write_buffer_rect(rect, tree_, image_input_, output_buffer_, this->get_width(), datatype_);
}
@@ -287,7 +287,7 @@ void OutputSingleLayerOperation::deinit_execution()
image_input_ = nullptr;
}
-void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -369,7 +369,7 @@ StampData *OutputOpenExrMultiLayerOperation::create_stamp_data() const
void OutputOpenExrMultiLayerOperation::init_execution()
{
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
if (layers_[i].use_layer) {
SocketReader *reader = get_input_socket_reader(i);
layers_[i].image_input = reader;
@@ -379,9 +379,9 @@ void OutputOpenExrMultiLayerOperation::init_execution()
}
}
-void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
OutputOpenExrLayer &layer = layers_[i];
if (layer.image_input) {
write_buffer_rect(
@@ -392,8 +392,8 @@ void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int /
void OutputOpenExrMultiLayerOperation::deinit_execution()
{
- unsigned int width = this->get_width();
- unsigned int height = this->get_height();
+ uint width = this->get_width();
+ uint height = this->get_height();
if (width != 0 && height != 0) {
char filename[FILE_MAX];
const char *suffix;
@@ -410,7 +410,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
suffix);
BLI_make_existing_file(filename);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
OutputOpenExrLayer &layer = layers_[i];
if (!layer.image_input) {
continue; /* skip unconnected sockets */
@@ -437,7 +437,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
}
IMB_exr_close(exrhandle);
- for (unsigned int i = 0; i < layers_.size(); i++) {
+ for (uint i = 0; i < layers_.size(); i++) {
if (layers_[i].output_buffer) {
MEM_freeN(layers_[i].output_buffer);
layers_[i].output_buffer = nullptr;
@@ -449,7 +449,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution()
}
}
-void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index df1d68838d9..716bede8035 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -71,7 +71,7 @@ struct OutputOpenExrLayer {
SocketReader *image_input;
};
-/* Writes inputs into OpenEXR multilayer channels. */
+/* Writes inputs into OpenEXR multi-layer channels. */
class OutputOpenExrMultiLayerOperation : public MultiThreadedOperation {
protected:
const Scene *scene_;
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
index 006f1f919ba..fcd37f2a179 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc
@@ -195,8 +195,8 @@ void PlaneCornerPinMaskOperation::determine_canvas(const rcti &preferred_area, r
r_area = preferred_area;
}
-void PlaneCornerPinMaskOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void PlaneCornerPinMaskOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
/* All corner inputs are used as constants. */
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
index 9c19f55e04f..59e924311e3 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc
@@ -82,7 +82,7 @@ void PlaneDistortWarpImageOperation::calculate_corners(const float corners[4][2]
}
float frame_corners[4][2] = {
- {0.0f, 0.0f}, {(float)width, 0.0f}, {(float)width, (float)height}, {0.0f, (float)height}};
+ {0.0f, 0.0f}, {float(width), 0.0f}, {float(width), float(height)}, {0.0f, float(height)}};
BKE_tracking_homography_between_two_quads(
sample_data->frame_space_corners, frame_corners, sample_data->perspective_matrix);
}
@@ -116,7 +116,7 @@ void PlaneDistortWarpImageOperation::execute_pixel_sampled(float output[4],
pixel_reader_->read_filtered(color, uv[0], uv[1], deriv[0], deriv[1]);
add_v4_v4(output, color);
}
- mul_v4_fl(output, 1.0f / (float)motion_blur_samples_);
+ mul_v4_fl(output, 1.0f / float(motion_blur_samples_));
}
}
@@ -143,7 +143,7 @@ void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer *
input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], color);
add_v4_v4(it.out, color);
}
- mul_v4_fl(it.out, 1.0f / (float)motion_blur_samples_);
+ mul_v4_fl(it.out, 1.0f / float(motion_blur_samples_));
}
}
}
@@ -258,7 +258,7 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4],
inside_counter++;
}
}
- output[0] = (float)inside_counter / osa_;
+ output[0] = float(inside_counter) / osa_;
}
else {
for (int motion_sample = 0; motion_sample < motion_blur_samples_; motion_sample++) {
@@ -278,13 +278,13 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4],
}
}
}
- output[0] = (float)inside_counter / (osa_ * motion_blur_samples_);
+ output[0] = float(inside_counter) / (osa_ * motion_blur_samples_);
}
}
void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
int inside_count = 0;
@@ -292,7 +292,7 @@ void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *outpu
MotionSample &sample = samples_[motion_sample];
inside_count += get_jitter_samples_inside_count(it.x, it.y, sample);
}
- *it.out = (float)inside_count / (osa_ * motion_blur_samples_);
+ *it.out = float(inside_count) / (osa_ * motion_blur_samples_);
}
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
index 7d515284737..f5922d54fc9 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc
@@ -28,7 +28,7 @@ void PlaneTrackCommon::read_and_calculate_corners(PlaneDistortBaseOperation *dis
distort_op->calculate_corners(corners, true, 0);
}
else {
- const float frame = (float)framenumber_ - distort_op->motion_blur_shutter_;
+ const float frame = float(framenumber_) - distort_op->motion_blur_shutter_;
const float frame_step = (distort_op->motion_blur_shutter_ * 2.0f) /
distort_op->motion_blur_samples_;
float frame_iter = frame;
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cc b/source/blender/compositor/operations/COM_PreviewOperation.cc
index dbc544896e3..2b9fc7ddc8c 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.cc
+++ b/source/blender/compositor/operations/COM_PreviewOperation.cc
@@ -10,8 +10,8 @@ namespace blender::compositor {
PreviewOperation::PreviewOperation(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- const unsigned int default_width,
- const unsigned int default_height)
+ const uint default_width,
+ const uint default_height)
{
this->add_input_socket(DataType::Color, ResizeMode::Align);
@@ -39,14 +39,13 @@ void PreviewOperation::init_execution()
{
input_ = get_input_socket_reader(0);
- if (this->get_width() == (unsigned int)preview_->xsize &&
- this->get_height() == (unsigned int)preview_->ysize) {
+ if (this->get_width() == uint(preview_->xsize) && this->get_height() == uint(preview_->ysize)) {
output_buffer_ = preview_->rect;
}
if (output_buffer_ == nullptr) {
- output_buffer_ = (unsigned char *)MEM_callocN(
- sizeof(unsigned char) * 4 * get_width() * get_height(), "PreviewOperation");
+ output_buffer_ = (uchar *)MEM_callocN(sizeof(uchar) * 4 * get_width() * get_height(),
+ "PreviewOperation");
if (preview_->rect) {
MEM_freeN(preview_->rect);
}
@@ -62,7 +61,7 @@ void PreviewOperation::deinit_execution()
input_ = nullptr;
}
-void PreviewOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void PreviewOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
int offset;
float color[4];
@@ -102,7 +101,7 @@ bool PreviewOperation::determine_depending_area_of_interest(rcti *input,
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void PreviewOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
/* Use default preview resolution as preferred ensuring it has size so that
* generated inputs (which don't have resolution on their own) are displayed */
@@ -125,10 +124,10 @@ void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti
divider_ = 0.0f;
if (width > 0 && height > 0) {
if (width > height) {
- divider_ = (float)COM_PREVIEW_SIZE / (width);
+ divider_ = float(COM_PREVIEW_SIZE) / (width);
}
else {
- divider_ = (float)COM_PREVIEW_SIZE / (height);
+ divider_ = float(COM_PREVIEW_SIZE) / (height);
}
}
width = width * divider_;
@@ -155,7 +154,7 @@ void PreviewOperation::get_area_of_interest(const int input_idx,
r_input_area.ymax = output_area.ymax / divider_;
}
-void PreviewOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void PreviewOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cc b/source/blender/compositor/operations/COM_ReadBufferOperation.cc
index 81f046af1b9..224d2ea0f41 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.cc
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cc
@@ -31,8 +31,7 @@ void ReadBufferOperation::determine_canvas(const rcti &preferred_area, rcti &r_a
/** \todo may not occur! But does with blur node. */
if (memory_proxy_->get_executor()) {
- uint resolution[2] = {static_cast<uint>(BLI_rcti_size_x(&r_area)),
- static_cast<uint>(BLI_rcti_size_y(&r_area))};
+ uint resolution[2] = {uint(BLI_rcti_size_x(&r_area)), uint(BLI_rcti_size_y(&r_area))};
memory_proxy_->get_executor()->set_resolution(resolution);
}
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cc b/source/blender/compositor/operations/COM_RenderLayersProg.cc
index 40f2187b27b..d95ee2a5e1a 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cc
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cc
@@ -52,7 +52,7 @@ void RenderLayersProg::init_execution()
void RenderLayersProg::do_interpolation(float output[4], float x, float y, PixelSampler sampler)
{
- unsigned int offset;
+ uint offset;
int width = this->get_width(), height = this->get_height();
int ix = x, iy = y;
@@ -169,7 +169,7 @@ void RenderLayersProg::deinit_execution()
}
}
-void RenderLayersProg::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area)
+void RenderLayersProg::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
Scene *sce = this->get_scene();
Render *re = (sce) ? RE_GetSceneRender(sce) : nullptr;
@@ -235,7 +235,7 @@ std::unique_ptr<MetaData> RenderLayersProg::get_meta_data()
void RenderLayersProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() >= elementsize_);
if (layer_buffer_) {
@@ -266,7 +266,7 @@ void RenderLayersAOOperation::execute_pixel_sampled(float output[4],
void RenderLayersAOOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_COLOR_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS);
@@ -300,7 +300,7 @@ void RenderLayersAlphaProg::execute_pixel_sampled(float output[4],
void RenderLayersAlphaProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS);
@@ -323,19 +323,19 @@ void RenderLayersDepthProg::execute_pixel_sampled(float output[4],
int iy = y;
float *input_buffer = this->get_input_buffer();
- if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= (int)this->get_width() ||
- iy >= (int)this->get_height()) {
+ if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= int(this->get_width()) ||
+ iy >= int(this->get_height())) {
output[0] = 10e10f;
}
else {
- unsigned int offset = (iy * this->get_width() + ix);
+ uint offset = (iy * this->get_width() + ix);
output[0] = input_buffer[offset];
}
}
void RenderLayersDepthProg::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
- Span<MemoryBuffer *> UNUSED(inputs))
+ Span<MemoryBuffer *> /*inputs*/)
{
BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS);
BLI_assert(elementsize_ == COM_DATA_TYPE_VALUE_CHANNELS);
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index 79f8cf5fc51..b0854cace52 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cc
+++ b/source/blender/compositor/operations/COM_RotateOperation.cc
@@ -143,7 +143,7 @@ inline void RotateOperation::ensure_degree()
double rad;
if (do_degree2_rad_conversion_) {
- rad = DEG2RAD((double)degree[0]);
+ rad = DEG2RAD(double(degree[0]));
}
else {
rad = degree[0];
diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc
index 261426b31e2..8f4ed844b9f 100644
--- a/source/blender/compositor/operations/COM_SMAAOperation.cc
+++ b/source/blender/compositor/operations/COM_SMAAOperation.cc
@@ -65,7 +65,7 @@ static void sample_bilinear_vertical(T *reader, int x, int y, float yoffset, flo
{
float iy = floorf(yoffset);
float fy = yoffset - iy;
- y += (int)iy;
+ y += int(iy);
float color00[4], color01[4];
@@ -83,7 +83,7 @@ static void sample_bilinear_horizontal(T *reader, int x, int y, float xoffset, f
{
float ix = floorf(xoffset);
float fx = xoffset - ix;
- x += (int)ix;
+ x += int(ix);
float color00[4], color10[4];
@@ -113,12 +113,12 @@ static inline const float *areatex_sample_internal(const float *areatex, int x,
static void area(int d1, int d2, int e1, int e2, float weights[2])
{
/* The areas texture is compressed quadratically: */
- float x = (float)(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf((float)d1);
- float y = (float)(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf((float)d2);
+ float x = float(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf(float(d1));
+ float y = float(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf(float(d2));
float ix = floorf(x), iy = floorf(y);
float fx = x - ix, fy = y - iy;
- int X = (int)ix, Y = (int)iy;
+ int X = int(ix), Y = int(iy);
const float *weights00 = areatex_sample_internal(areatex, X + 0, Y + 0);
const float *weights10 = areatex_sample_internal(areatex, X + 1, Y + 0);
@@ -196,7 +196,7 @@ bool SMAAEdgeDetectionOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAAEdgeDetectionOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAAEdgeDetectionOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
@@ -404,7 +404,7 @@ void SMAABlendingWeightCalculationOperation::init_execution()
void SMAABlendingWeightCalculationOperation::set_corner_rounding(float rounding)
{
/* UI values are between 0 and 1 for simplicity but algorithm expects values between 0 and 100 */
- corner_rounding_ = static_cast<int>(scalenorm(0, 100, rounding));
+ corner_rounding_ = int(scalenorm(0, 100, rounding));
}
void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4],
@@ -505,14 +505,14 @@ void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4],
}
void SMAABlendingWeightCalculationOperation::update_memory_buffer_started(
- MemoryBuffer *UNUSED(output), const rcti &UNUSED(out_area), Span<MemoryBuffer *> inputs)
+ MemoryBuffer * /*output*/, const rcti & /*out_area*/, Span<MemoryBuffer *> inputs)
{
const MemoryBuffer *image = inputs[0];
sample_image_fn_ = [=](int x, int y, float *out) { image->read_elem_checked(x, y, out); };
}
void SMAABlendingWeightCalculationOperation::update_memory_buffer_partial(
- MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> UNUSED(inputs))
+ MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> /*inputs*/)
{
for (BuffersIterator<float> it = output->iterate_with({}, out_area); !it.is_end(); ++it) {
const int x = it.x;
@@ -631,7 +631,7 @@ bool SMAABlendingWeightCalculationOperation::determine_depending_area_of_interes
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
@@ -1123,7 +1123,7 @@ bool SMAANeighborhoodBlendingOperation::determine_depending_area_of_interest(
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
-void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int UNUSED(input_idx),
+void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int /*input_idx*/,
const rcti &output_area,
rcti &r_input_area)
{
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc
index 2a2aff31893..cc914239caf 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.cc
+++ b/source/blender/compositor/operations/COM_ScaleOperation.cc
@@ -16,7 +16,7 @@ namespace blender::compositor {
BaseScaleOperation::BaseScaleOperation()
{
#ifdef USE_FORCE_BILINEAR
- sampler_ = (int)PixelSampler::Bilinear;
+ sampler_ = int(PixelSampler::Bilinear);
#else
sampler_ = -1;
#endif
@@ -372,8 +372,8 @@ void ScaleFixedSizeOperation::init_data(const rcti &input_canvas)
{
const int input_width = BLI_rcti_size_x(&input_canvas);
const int input_height = BLI_rcti_size_y(&input_canvas);
- rel_x_ = input_width / (float)new_width_;
- rel_y_ = input_height / (float)new_height_;
+ rel_x_ = input_width / float(new_width_);
+ rel_y_ = input_height / float(new_height_);
/* *** all the options below are for a fairly special case - camera framing *** */
if (offset_x_ != 0.0f || offset_y_ != 0.0f) {
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h
index 4cd50f3ead3..ba291342e96 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.h
+++ b/source/blender/compositor/operations/COM_ScaleOperation.h
@@ -112,12 +112,12 @@ class ScaleRelativeOperation : public ScaleOperation {
rcti *output) override;
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
- float get_relative_scale_x_factor(float UNUSED(width)) override
+ float get_relative_scale_x_factor(float /*width*/) override
{
return 1.0f;
}
- float get_relative_scale_y_factor(float UNUSED(height)) override
+ float get_relative_scale_y_factor(float /*height*/) override
{
return 1.0f;
}
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
index 0fc5589a3df..a62977c3280 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
@@ -40,8 +40,8 @@ void ScreenLensDistortionOperation::set_dispersion(float dispersion)
void ScreenLensDistortionOperation::init_data()
{
- cx_ = 0.5f * (float)get_width();
- cy_ = 0.5f * (float)get_height();
+ cx_ = 0.5f * float(get_width());
+ cy_ = 0.5f * float(get_height());
switch (execution_model_) {
case eExecutionModel::FullFrame: {
@@ -72,8 +72,8 @@ void ScreenLensDistortionOperation::init_execution()
input_program_ = this->get_input_socket_reader(0);
this->init_mutex();
- uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
- rng_seed ^= (uint)POINTER_AS_INT(input_program_);
+ uint rng_seed = uint(PIL_check_seconds_timer_i() & UINT_MAX);
+ rng_seed ^= uint(POINTER_AS_INT(input_program_));
rng_ = BLI_rng_new(rng_seed);
}
@@ -147,8 +147,8 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer,
float color[4];
float dsf = len_v2v2(delta[a], delta[b]) + 1.0f;
- int ds = jitter_ ? (dsf < 4.0f ? 2 : (int)sqrtf(dsf)) : (int)dsf;
- float sd = 1.0f / (float)ds;
+ int ds = jitter_ ? (dsf < 4.0f ? 2 : int(sqrtf(dsf))) : int(dsf);
+ float sd = 1.0f / float(ds);
float k4 = k4_[a];
float dk4 = dk4_[a];
@@ -178,7 +178,7 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer,
void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y, void *data)
{
MemoryBuffer *buffer = (MemoryBuffer *)data;
- float xy[2] = {(float)x, (float)y};
+ float xy[2] = {float(x), float(y)};
float uv[2];
get_uv(xy, uv);
float uv_dot = len_squared_v2(uv);
@@ -196,13 +196,13 @@ void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y,
accumulate(buffer, 1, 2, uv_dot, uv, delta, sum, count);
if (count[0]) {
- output[0] = 2.0f * sum[0] / (float)count[0];
+ output[0] = 2.0f * sum[0] / float(count[0]);
}
if (count[1]) {
- output[1] = 2.0f * sum[1] / (float)count[1];
+ output[1] = 2.0f * sum[1] / float(count[1]);
}
if (count[2]) {
- output[2] = 2.0f * sum[2] / (float)count[2];
+ output[2] = 2.0f * sum[2] / float(count[2]);
}
/* set alpha */
@@ -384,7 +384,7 @@ void ScreenLensDistortionOperation::determine_canvas(const rcti &preferred_area,
}
void ScreenLensDistortionOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
if (input_idx != 0) {
@@ -485,7 +485,7 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o
{
const MemoryBuffer *input_image = inputs[0];
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- float xy[2] = {(float)it.x, (float)it.y};
+ float xy[2] = {float(it.x), float(it.y)};
float uv[2];
get_uv(xy, uv);
const float uv_dot = len_squared_v2(uv);
@@ -505,13 +505,13 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o
accumulate(input_image, 1, 2, uv_dot, uv, delta, sum, count);
if (count[0]) {
- it.out[0] = 2.0f * sum[0] / (float)count[0];
+ it.out[0] = 2.0f * sum[0] / float(count[0]);
}
if (count[1]) {
- it.out[1] = 2.0f * sum[1] / (float)count[1];
+ it.out[1] = 2.0f * sum[1] / float(count[1]);
}
if (count[2]) {
- it.out[2] = 2.0f * sum[2] / (float)count[2];
+ it.out[2] = 2.0f * sum[2] / float(count[2]);
}
/* Set alpha. */
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cc b/source/blender/compositor/operations/COM_SunBeamsOperation.cc
index 1628c0fa1f8..94674c8fd6c 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cc
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cc
@@ -52,18 +52,18 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v)
{
- int x0 = (int)source[0];
- int y0 = (int)source[1];
- x -= (float)x0;
- y -= (float)y0;
+ int x0 = int(source[0]);
+ int y0 = int(source[1]);
+ x -= float(x0);
+ y -= float(y0);
u = x * fxu + y * fyu;
v = x * fxv + y * fyv;
}
static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y)
{
- int x0 = (int)source[0];
- int y0 = (int)source[1];
+ int x0 = int(source[0]);
+ int y0 = int(source[1]);
x = x0 + u * fxu + v * fxv;
y = y0 + u * fyu + v * fyv;
}
@@ -95,7 +95,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
buffer_to_sector(source, co[0], co[1], pu, pv);
/* line angle */
- double tan_phi = pv / (double)pu;
+ double tan_phi = pv / double(pu);
double dr = sqrt(tan_phi * tan_phi + 1.0);
double cos_phi = 1.0 / dr;
@@ -105,13 +105,13 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
v = umin * tan_phi;
dv = tan_phi;
- int start = (int)floorf(umax);
- int end = (int)ceilf(umin);
+ int start = int(floorf(umax));
+ int end = int(ceilf(umin));
num = end - start;
- sector_to_buffer(source, end, (int)ceilf(v), x, y);
+ sector_to_buffer(source, end, int(ceilf(v)), x, y);
- falloff_factor = dist_max > dist_min ? dr / (double)(dist_max - dist_min) : 0.0f;
+ falloff_factor = dist_max > dist_min ? dr / double(dist_max - dist_min) : 0.0f;
float *iter = input->get_buffer() + input->get_coords_offset(x, y);
return iter;
@@ -139,7 +139,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
zero_v4(output);
- if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) {
+ if (int(co[0] - source[0]) == 0 && int(co[1] - source[1]) == 0) {
copy_v4_v4(output, input->get_elem(source[0], source[1]));
return;
}
@@ -154,7 +154,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
float v_local = v - floorf(v);
for (int i = 0; i < num; i++) {
- float weight = 1.0f - (float)i * falloff_factor;
+ float weight = 1.0f - float(i) * falloff_factor;
weight *= weight;
/* range check, use last valid color when running beyond the image border */
@@ -195,7 +195,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
/* normalize */
if (num > 0) {
- mul_v4_fl(output, 1.0f / (float)num);
+ mul_v4_fl(output, 1.0f / float(num));
}
}
};
@@ -288,14 +288,14 @@ void *SunBeamsOperation::initialize_tile_data(rcti * /*rect*/)
void SunBeamsOperation::execute_pixel(float output[4], int x, int y, void *data)
{
- const float co[2] = {(float)x, (float)y};
+ const float co[2] = {float(x), float(y)};
accumulate_line((MemoryBuffer *)data, output, co, source_px_, 0.0f, ray_length_px_);
}
static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
{
- float co[2] = {(float)x, (float)y};
+ float co[2] = {float(x), float(y)};
float dir[2], dist;
/* move (x,y) vector toward the source by ray_length distance */
@@ -304,7 +304,7 @@ static void calc_ray_shift(rcti *rect, float x, float y, const float source[2],
mul_v2_fl(dir, min_ff(dist, ray_length));
sub_v2_v2(co, dir);
- int ico[2] = {(int)co[0], (int)co[1]};
+ int ico[2] = {int(co[0]), int(co[1])};
BLI_rcti_do_minmax_v(rect, ico);
}
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc
index 714625e483d..6f560eafc67 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.cc
+++ b/source/blender/compositor/operations/COM_TonemapOperation.cc
@@ -120,11 +120,11 @@ void *TonemapOperation::initialize_tile_data(rcti *rect)
}
data->lav = Lav * sc;
mul_v3_v3fl(data->cav, cav, sc);
- maxl = log((double)maxl + 1e-5);
- minl = log((double)minl + 1e-5);
+ maxl = log(double(maxl) + 1e-5);
+ minl = log(double(minl) + 1e-5);
avl = lsum * sc;
data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f;
- float al = exp((double)avl);
+ float al = exp(double(avl));
data->al = (al == 0.0f) ? 0.0f : (data_->key / al);
data->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma);
cached_instance_ = data;
@@ -139,7 +139,7 @@ void TonemapOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/)
}
void TonemapOperation::get_area_of_interest(const int input_idx,
- const rcti &UNUSED(output_area),
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
@@ -170,8 +170,8 @@ static Luminance calc_area_luminance(const MemoryBuffer *input, const rcti &area
return lum;
}
-void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
- const rcti &UNUSED(area),
+void TonemapOperation::update_memory_buffer_started(MemoryBuffer * /*output*/,
+ const rcti & /*area*/,
Span<MemoryBuffer *> inputs)
{
if (cached_instance_ == nullptr) {
@@ -193,11 +193,11 @@ void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output)
AvgLogLum *avg = new AvgLogLum();
avg->lav = lum.sum / lum.num_pixels;
mul_v3_v3fl(avg->cav, lum.color_sum, 1.0f / lum.num_pixels);
- const float max_log = log((double)lum.max + 1e-5);
- const float min_log = log((double)lum.min + 1e-5);
+ const float max_log = log(double(lum.max) + 1e-5);
+ const float min_log = log(double(lum.min) + 1e-5);
const float avg_log = lum.log_sum / lum.num_pixels;
avg->auto_key = (max_log > min_log) ? ((max_log - avg_log) / (max_log - min_log)) : 1.0f;
- const float al = exp((double)avg_log);
+ const float al = exp(double(avg_log));
avg->al = (al == 0.0f) ? 0.0f : (data_->key / al);
avg->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma);
cached_instance_ = avg;
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h
index 8071470b3f4..4e68d432985 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.h
+++ b/source/blender/compositor/operations/COM_TonemapOperation.h
@@ -21,7 +21,7 @@ typedef struct AvgLogLum {
} AvgLogLum;
/**
- * \brief base class of tonemap, implementing the simple tonemap
+ * \brief base class of tone-map, implementing the simple tone-map
* \ingroup operation
*/
class TonemapOperation : public MultiThreadedOperation {
@@ -32,7 +32,7 @@ class TonemapOperation : public MultiThreadedOperation {
SocketReader *image_reader_;
/**
- * \brief settings of the Tonemap
+ * \brief settings of the Tone-map
*/
const NodeTonemap *data_;
diff --git a/source/blender/compositor/operations/COM_TransformOperation.cc b/source/blender/compositor/operations/COM_TransformOperation.cc
index 36a4899ef53..0db018a3dc0 100644
--- a/source/blender/compositor/operations/COM_TransformOperation.cc
+++ b/source/blender/compositor/operations/COM_TransformOperation.cc
@@ -38,7 +38,7 @@ void TransformOperation::init_data()
translate_factor_y_;
const float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f);
- const double rad = convert_degree_to_rad_ ? DEG2RAD((double)degree) : degree;
+ const double rad = convert_degree_to_rad_ ? DEG2RAD(double(degree)) : degree;
rotate_cosine_ = cos(rad);
rotate_sine_ = sin(rad);
diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
index d4365af4860..bf6ee64c73f 100644
--- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
@@ -61,7 +61,7 @@ void *VariableSizeBokehBlurOperation::initialize_tile_data(rcti *rect)
const float max_dim = MAX2(this->get_width(), this->get_height());
const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- data->max_blur_scalar = (int)(data->size->get_max_value(rect2) * scalar);
+ data->max_blur_scalar = int(data->size->get_max_value(rect2) * scalar);
CLAMP(data->max_blur_scalar, 1.0f, max_blur_);
return data;
}
@@ -106,8 +106,8 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y
#else
int minx = MAX2(x - max_blur_scalar, 0);
int miny = MAX2(y - max_blur_scalar, 0);
- int maxx = MIN2(x + max_blur_scalar, (int)get_width());
- int maxy = MIN2(y + max_blur_scalar, (int)get_height());
+ int maxx = MIN2(x + max_blur_scalar, int(get_width()));
+ int maxy = MIN2(y + max_blur_scalar, int(get_height()));
#endif
{
input_size_buffer->read_no_check(temp_size, x, y);
@@ -134,10 +134,10 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y
float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) {
float uv[2] = {
- (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
- (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
+ float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1),
+ float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1),
};
input_bokeh_buffer->read(bokeh, uv[0], uv[1]);
madd_v4_v4v4(color_accum, bokeh, &input_program_float_buffer[offset_color_nx_ny]);
@@ -185,7 +185,7 @@ void VariableSizeBokehBlurOperation::execute_opencl(
const float max_dim = MAX2(get_width(), get_height());
cl_float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, (float)max_blur_);
+ max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, float(max_blur_));
device->COM_cl_attach_memory_buffer_to_kernel_parameter(
defocus_kernel, 0, -1, cl_mem_to_clean_up, input_memory_buffers, input_program_);
@@ -358,10 +358,10 @@ static void blur_pixel(int x, int y, PixelData &p)
/* XXX: There is no way to ensure bokeh input is an actual bokeh with #COM_BLUR_BOKEH_PIXELS
* size, anything may be connected. Use the real input size and remove asserts? */
- const float u = (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1);
- const float v = (float)(COM_BLUR_BOKEH_PIXELS / 2) +
- (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1);
+ const float u = float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1);
+ const float v = float(COM_BLUR_BOKEH_PIXELS / 2) +
+ (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1);
float bokeh[4];
p.bokeh_input->read_elem_checked(u, v, bokeh);
madd_v4_v4v4(p.color_accum, bokeh, color);
@@ -390,7 +390,7 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
const float max_dim = MAX2(this->get_width(), this->get_height());
p.scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
- p.max_blur_scalar = static_cast<int>(max_size * p.scalar);
+ p.max_blur_scalar = int(max_size * p.scalar);
CLAMP(p.max_blur_scalar, 1, max_blur_);
for (BuffersIterator<float> it = output->iterate_with({p.image_input, p.size_input}, area);
@@ -510,8 +510,8 @@ void InverseSearchRadiusOperation::deinit_execution()
input_radius_ = nullptr;
}
-void InverseSearchRadiusOperation::determine_resolution(unsigned int resolution[2],
- unsigned int preferred_resolution[2])
+void InverseSearchRadiusOperation::determine_resolution(uint resolution[2],
+ uint preferred_resolution[2])
{
NodeOperation::determine_resolution(resolution, preferred_resolution);
resolution[0] = resolution[0] / DIVIDER;
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc
index 71c61a6e588..1330557c06f 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cc
@@ -103,8 +103,8 @@ bool VectorBlurOperation::determine_depending_area_of_interest(rcti * /*input*/,
return false;
}
-void VectorBlurOperation::get_area_of_interest(const int UNUSED(input_idx),
- const rcti &UNUSED(output_area),
+void VectorBlurOperation::get_area_of_interest(const int /*input_idx*/,
+ const rcti & /*output_area*/,
rcti &r_input_area)
{
r_input_area = this->get_canvas();
@@ -190,7 +190,10 @@ struct ZSpan {
float clipcrop;
};
-/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
+/**
+ * Each Z-buffer has coordinates transformed to local rectangle coordinates,
+ * so we can simply clip.
+ */
void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
{
memset(zspan, 0, sizeof(ZSpan));
@@ -385,9 +388,9 @@ static void zbuf_fill_in_rgba(
xx1 = (x0 * v1[0] + y0 * v1[1]) / z0 + v1[2];
- zxd = -(double)x0 / (double)z0;
- zyd = -(double)y0 / (double)z0;
- zy0 = ((double)my2) * zyd + (double)xx1;
+ zxd = -double(x0) / double(z0);
+ zyd = -double(y0) / double(z0);
+ zy0 = double(my2) * zyd + double(xx1);
/* start-offset in rect */
rectx = zspan->rectx;
@@ -419,13 +422,13 @@ static void zbuf_fill_in_rgba(
}
if (sn2 >= sn1) {
- zverg = (double)sn1 * zxd + zy0;
+ zverg = double(sn1) * zxd + zy0;
rz = rectzofs + sn1;
rp = rectpofs + sn1;
x = sn2 - sn1;
while (x >= 0) {
- if (zverg < (double)*rz) {
+ if (zverg < double(*rz)) {
*rz = zverg;
*rp = *col;
}
@@ -528,7 +531,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove)
}
}
- /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */
+ /* last: pixels with 0 we fill in Z-buffer, with 1 we skip for mask */
for (y = 2; y < ysize; y++) {
/* setup rows */
row1 = rectmove + (y - 2) * xsize;
@@ -590,15 +593,15 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
const float *dimg, *dz, *ro;
float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz;
float *minvecbufrect = nullptr, *rectweight, *rw, *rectmax, *rm;
- float maxspeedsq = (float)nbd->maxspeed * nbd->maxspeed;
+ float maxspeedsq = float(nbd->maxspeed) * nbd->maxspeed;
int y, x, step, maxspeed = nbd->maxspeed, samples = nbd->samples;
int tsktsk = 0;
static int firsttime = 1;
char *rectmove, *dm;
zbuf_alloc_span(&zspan, xsize, ysize, 1.0f);
- zspan.zmulx = ((float)xsize) / 2.0f;
- zspan.zmuly = ((float)ysize) / 2.0f;
+ zspan.zmulx = float(xsize) / 2.0f;
+ zspan.zmuly = float(ysize) / 2.0f;
zspan.zofsx = 0.0f;
zspan.zofsy = 0.0f;
@@ -627,7 +630,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
/* Min speed? then copy speed-buffer to recalculate speed vectors. */
if (nbd->minspeed) {
- float minspeed = (float)nbd->minspeed;
+ float minspeed = float(nbd->minspeed);
float minspeedsq = minspeed * minspeed;
minvecbufrect = (float *)MEM_callocN(sizeof(float[4]) * xsize * ysize, "minspeed buf");
@@ -726,7 +729,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
if (maxspeed) {
float speedsq = dvz[0] * dvz[0] + dvz[1] * dvz[1];
if (speedsq > maxspeedsq) {
- speedsq = (float)maxspeed / sqrtf(speedsq);
+ speedsq = float(maxspeed) / sqrtf(speedsq);
dvz[0] *= speedsq;
dvz[1] *= speedsq;
}
@@ -757,7 +760,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
dm = rectmove;
dvec1 = vecbufrect;
for (x = xsize * ysize; x > 0; x--, dm++, dvec1 += 4) {
- if ((dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f)) {
+ if (dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f) {
*dm = 255;
}
}
@@ -776,7 +779,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
/* accumulate */
samples /= 2;
for (step = 1; step <= samples; step++) {
- float speedfac = 0.5f * nbd->fac * (float)step / (float)(samples + 1);
+ float speedfac = 0.5f * nbd->fac * float(step) / float(samples + 1);
int side;
for (side = 0; side < 2; side++) {
@@ -864,7 +867,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
col.alpha = 0.0f;
}
else {
- col.alpha = ((float)*dm) / 255.0f;
+ col.alpha = float(*dm) / 255.0f;
}
col.colpoin = dimg;
@@ -882,7 +885,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd,
* we don't know what is behind it so we don't do that. this hack
* overestimates the contribution of foreground pixels but looks a
* bit better without a sudden cutoff. */
- blendfac = ((samples - step) / (float)samples);
+ blendfac = ((samples - step) / float(samples));
/* Smooth-step to make it look a bit nicer as well. */
blendfac = 3.0f * pow(blendfac, 2.0f) - 2.0f * pow(blendfac, 3.0f);
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc
index 3bd5fa4ad14..b4ff6878784 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cc
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cc
@@ -60,7 +60,7 @@ void ViewerOperation::deinit_execution()
output_buffer_ = nullptr;
}
-void ViewerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void ViewerOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
float *buffer = output_buffer_;
float *depthbuffer = depth_buffer_;
@@ -216,7 +216,7 @@ eCompositorPriority ViewerOperation::get_render_priority() const
return eCompositorPriority::Low;
}
-void ViewerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output),
+void ViewerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
@@ -264,7 +264,7 @@ void ViewerOperation::clear_display_buffer()
return;
}
- size_t buf_bytes = (size_t)ibuf_->y * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
+ size_t buf_bytes = size_t(ibuf_->y) * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
if (buf_bytes > 0) {
memset(output_buffer_, 0, buf_bytes);
rcti display_area;
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cc b/source/blender/compositor/operations/COM_WriteBufferOperation.cc
index 9073c92b154..56261bfc660 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.cc
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cc
@@ -42,7 +42,7 @@ void WriteBufferOperation::deinit_execution()
memory_proxy_->free();
}
-void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number*/)
+void WriteBufferOperation::execute_region(rcti *rect, uint /*tile_number*/)
{
MemoryBuffer *memory_buffer = memory_proxy_->get_buffer();
float *buffer = memory_buffer->get_buffer();
@@ -95,7 +95,7 @@ void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number
void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device,
rcti * /*rect*/,
- unsigned int /*chunk_number*/,
+ uint /*chunk_number*/,
MemoryBuffer **input_memory_buffers,
MemoryBuffer *output_buffer)
{
@@ -110,8 +110,8 @@ void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device,
* NOTE: list of cl_mem will be filled by 2, and needs to be cleaned up by 4
*/
/* STEP 1 */
- const unsigned int output_buffer_width = output_buffer->get_width();
- const unsigned int output_buffer_height = output_buffer->get_height();
+ const uint output_buffer_width = output_buffer->get_width();
+ const uint output_buffer_height = output_buffer->get_height();
const cl_image_format *image_format = OpenCLDevice::determine_image_format(output_buffer);
diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt
index 1f1333332f5..b4352248b5b 100644
--- a/source/blender/compositor/realtime_compositor/CMakeLists.txt
+++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt
@@ -2,6 +2,8 @@
set(INC
.
+ algorithms
+ cached_resources
../../blenkernel
../../blenlib
../../gpu
@@ -9,6 +11,7 @@ set(INC
../../makesdna
../../makesrna
../../nodes
+ ../../render
../../gpu/intern
../../../../intern/guardedalloc
)
@@ -30,6 +33,7 @@ set(SRC
intern/shader_node.cc
intern/shader_operation.cc
intern/simple_operation.cc
+ intern/static_cache_manager.cc
intern/static_shader_manager.cc
intern/texture_pool.cc
intern/utilities.cc
@@ -50,17 +54,157 @@ set(SRC
COM_shader_node.hh
COM_shader_operation.hh
COM_simple_operation.hh
+ COM_static_cache_manager.hh
COM_static_shader_manager.hh
COM_texture_pool.hh
COM_utilities.hh
+
+ algorithms/intern/algorithm_parallel_reduction.cc
+
+ algorithms/COM_algorithm_parallel_reduction.hh
+
+ cached_resources/intern/morphological_distance_feather_weights.cc
+ cached_resources/intern/symmetric_blur_weights.cc
+ cached_resources/intern/symmetric_separable_blur_weights.cc
+
+ cached_resources/COM_cached_resource.hh
+ cached_resources/COM_morphological_distance_feather_weights.hh
+ cached_resources/COM_symmetric_blur_weights.hh
+ cached_resources/COM_symmetric_separable_blur_weights.hh
)
set(LIB
bf_gpu
bf_nodes
bf_imbuf
+ bf_render
bf_blenlib
bf_blenkernel
)
+set(GLSL_SRC
+ shaders/compositor_alpha_crop.glsl
+ shaders/compositor_bilateral_blur.glsl
+ shaders/compositor_blur.glsl
+ shaders/compositor_blur_variable_size.glsl
+ shaders/compositor_bokeh_image.glsl
+ shaders/compositor_box_mask.glsl
+ shaders/compositor_convert.glsl
+ shaders/compositor_despeckle.glsl
+ shaders/compositor_directional_blur.glsl
+ shaders/compositor_edge_filter.glsl
+ shaders/compositor_ellipse_mask.glsl
+ shaders/compositor_filter.glsl
+ shaders/compositor_flip.glsl
+ shaders/compositor_image_crop.glsl
+ shaders/compositor_morphological_distance.glsl
+ shaders/compositor_morphological_distance_feather.glsl
+ shaders/compositor_morphological_distance_threshold.glsl
+ shaders/compositor_morphological_step.glsl
+ shaders/compositor_normalize.glsl
+ shaders/compositor_parallel_reduction.glsl
+ shaders/compositor_projector_lens_distortion.glsl
+ shaders/compositor_realize_on_domain.glsl
+ shaders/compositor_screen_lens_distortion.glsl
+ shaders/compositor_set_alpha.glsl
+ shaders/compositor_split_viewer.glsl
+ shaders/compositor_symmetric_blur.glsl
+ shaders/compositor_symmetric_separable_blur.glsl
+ shaders/compositor_tone_map_photoreceptor.glsl
+ shaders/compositor_tone_map_simple.glsl
+
+ shaders/library/gpu_shader_compositor_alpha_over.glsl
+ shaders/library/gpu_shader_compositor_blur_common.glsl
+ shaders/library/gpu_shader_compositor_bright_contrast.glsl
+ shaders/library/gpu_shader_compositor_channel_matte.glsl
+ shaders/library/gpu_shader_compositor_chroma_matte.glsl
+ shaders/library/gpu_shader_compositor_color_balance.glsl
+ shaders/library/gpu_shader_compositor_color_correction.glsl
+ shaders/library/gpu_shader_compositor_color_matte.glsl
+ shaders/library/gpu_shader_compositor_color_spill.glsl
+ shaders/library/gpu_shader_compositor_color_to_luminance.glsl
+ shaders/library/gpu_shader_compositor_difference_matte.glsl
+ shaders/library/gpu_shader_compositor_distance_matte.glsl
+ shaders/library/gpu_shader_compositor_exposure.glsl
+ shaders/library/gpu_shader_compositor_gamma.glsl
+ shaders/library/gpu_shader_compositor_hue_correct.glsl
+ shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
+ shaders/library/gpu_shader_compositor_invert.glsl
+ shaders/library/gpu_shader_compositor_luminance_matte.glsl
+ shaders/library/gpu_shader_compositor_main.glsl
+ shaders/library/gpu_shader_compositor_map_value.glsl
+ shaders/library/gpu_shader_compositor_normal.glsl
+ shaders/library/gpu_shader_compositor_posterize.glsl
+ shaders/library/gpu_shader_compositor_separate_combine.glsl
+ shaders/library/gpu_shader_compositor_set_alpha.glsl
+ shaders/library/gpu_shader_compositor_store_output.glsl
+ shaders/library/gpu_shader_compositor_texture_utilities.glsl
+ shaders/library/gpu_shader_compositor_type_conversion.glsl
+)
+
+set(GLSL_C)
+foreach(GLSL_FILE ${GLSL_SRC})
+ data_to_c_simple(${GLSL_FILE} GLSL_C)
+endforeach()
+
+blender_add_lib(bf_compositor_shaders "${GLSL_C}" "" "" "")
+
+list(APPEND LIB
+ bf_compositor_shaders
+)
+
+set(GLSL_SOURCE_CONTENT "")
+foreach(GLSL_FILE ${GLSL_SRC})
+ get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME)
+ string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME})
+ string(APPEND GLSL_SOURCE_CONTENT "SHADER_SOURCE\(datatoc_${GLSL_FILE_NAME_UNDERSCORES}, \"${GLSL_FILE_NAME}\", \"${GLSL_FILE}\"\)\n")
+endforeach()
+
+set(glsl_source_list_file "${CMAKE_CURRENT_BINARY_DIR}/glsl_compositor_source_list.h")
+file(GENERATE OUTPUT ${glsl_source_list_file} CONTENT "${GLSL_SOURCE_CONTENT}")
+list(APPEND SRC ${glsl_source_list_file})
+list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR})
+
+target_include_directories(bf_compositor_shaders PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
+
+set(SRC_SHADER_CREATE_INFOS
+ shaders/infos/compositor_alpha_crop_info.hh
+ shaders/infos/compositor_bilateral_blur_info.hh
+ shaders/infos/compositor_blur_info.hh
+ shaders/infos/compositor_blur_variable_size_info.hh
+ shaders/infos/compositor_bokeh_image_info.hh
+ shaders/infos/compositor_box_mask_info.hh
+ shaders/infos/compositor_convert_info.hh
+ shaders/infos/compositor_despeckle_info.hh
+ shaders/infos/compositor_directional_blur_info.hh
+ shaders/infos/compositor_edge_filter_info.hh
+ shaders/infos/compositor_ellipse_mask_info.hh
+ shaders/infos/compositor_filter_info.hh
+ shaders/infos/compositor_flip_info.hh
+ shaders/infos/compositor_image_crop_info.hh
+ shaders/infos/compositor_morphological_distance_feather_info.hh
+ shaders/infos/compositor_morphological_distance_info.hh
+ shaders/infos/compositor_morphological_distance_threshold_info.hh
+ shaders/infos/compositor_morphological_step_info.hh
+ shaders/infos/compositor_normalize_info.hh
+ shaders/infos/compositor_parallel_reduction_info.hh
+ shaders/infos/compositor_projector_lens_distortion_info.hh
+ shaders/infos/compositor_realize_on_domain_info.hh
+ shaders/infos/compositor_screen_lens_distortion_info.hh
+ shaders/infos/compositor_set_alpha_info.hh
+ shaders/infos/compositor_split_viewer_info.hh
+ shaders/infos/compositor_symmetric_blur_info.hh
+ shaders/infos/compositor_symmetric_separable_blur_info.hh
+ shaders/infos/compositor_tone_map_photoreceptor_info.hh
+ shaders/infos/compositor_tone_map_simple_info.hh
+)
+
+set(SHADER_CREATE_INFOS_CONTENT "")
+foreach(DESCRIPTOR_FILE ${SRC_SHADER_CREATE_INFOS})
+ string(APPEND SHADER_CREATE_INFOS_CONTENT "#include \"${DESCRIPTOR_FILE}\"\n")
+endforeach()
+
+set(shader_create_info_list_file "${CMAKE_CURRENT_BINARY_DIR}/compositor_shader_create_info_list.hh")
+file(GENERATE OUTPUT ${shader_create_info_list_file} CONTENT "${SHADER_CREATE_INFOS_CONTENT}")
+
blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh
index b5c8cea641f..80fb4f70ca4 100644
--- a/source/blender/compositor/realtime_compositor/COM_context.hh
+++ b/source/blender/compositor/realtime_compositor/COM_context.hh
@@ -9,6 +9,7 @@
#include "GPU_texture.h"
+#include "COM_static_cache_manager.hh"
#include "COM_static_shader_manager.hh"
#include "COM_texture_pool.hh"
@@ -22,14 +23,17 @@ namespace blender::realtime_compositor {
* providing input data like render passes and the active scene, as well as references to the data
* where the output of the evaluator will be written. The class also provides a reference to the
* texture pool which should be implemented by the caller and provided during construction.
- * Finally, the class have an instance of a static shader manager for convenient shader
- * acquisition. */
+ * Finally, the class have an instance of a static shader manager and a static resource manager
+ * for acquiring cached shaders and resources efficiently. */
class Context {
private:
/* A texture pool that can be used to allocate textures for the compositor efficiently. */
TexturePool &texture_pool_;
/* A static shader manager that can be used to acquire shaders for the compositor efficiently. */
StaticShaderManager shader_manager_;
+ /* A static cache manager that can be used to acquire cached resources for the compositor
+ * efficiently. */
+ StaticCacheManager cache_manager_;
public:
Context(TexturePool &texture_pool);
@@ -67,6 +71,9 @@ class Context {
/* Get a reference to the static shader manager of this context. */
StaticShaderManager &shader_manager();
+
+ /* Get a reference to the static cache manager of this context. */
+ StaticCacheManager &cache_manager();
};
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
index 15e1d0722ea..310333aea5a 100644
--- a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
+++ b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh
@@ -11,11 +11,13 @@
namespace blender::realtime_compositor {
-/* -------------------------------------------------------------------------------------------------
- * Conversion Operation
+/* -------------------------------------------------------------------- */
+/** \name Conversion Operation
*
* A simple operation that converts a result from a certain type to another. See the derived
- * classes for more details. */
+ * classes for more details.
+ * \{ */
+
class ConversionOperation : public SimpleOperation {
public:
using SimpleOperation::SimpleOperation;
@@ -37,13 +39,18 @@ class ConversionOperation : public SimpleOperation {
/* Get the shader the will be used for conversion. */
virtual GPUShader *get_conversion_shader() const = 0;
-};
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Vector Operation
+ /** \} */
+
+}; // namespace blender::realtime_compositorclassConversionOperation:publicSimpleOperation
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Vector Operation
*
* Takes a float result and outputs a vector result. All three components of the output are filled
- * with the input float. */
+ * with the input float.
+ * \{ */
+
class ConvertFloatToVectorOperation : public ConversionOperation {
public:
ConvertFloatToVectorOperation(Context &context);
@@ -53,11 +60,15 @@ class ConvertFloatToVectorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Color Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Color Operation
*
* Takes a float result and outputs a color result. All three color channels of the output are
- * filled with the input float and the alpha channel is set to 1. */
+ * filled with the input float and the alpha channel is set to 1.
+ * \{ */
+
class ConvertFloatToColorOperation : public ConversionOperation {
public:
ConvertFloatToColorOperation(Context &context);
@@ -67,11 +78,15 @@ class ConvertFloatToColorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Float Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Float Operation
*
* Takes a color result and outputs a float result. The output is the average of the three color
- * channels, the alpha channel is ignored. */
+ * channels, the alpha channel is ignored.
+ * \{ */
+
class ConvertColorToFloatOperation : public ConversionOperation {
public:
ConvertColorToFloatOperation(Context &context);
@@ -81,11 +96,15 @@ class ConvertColorToFloatOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Vector Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Vector Operation
*
* Takes a color result and outputs a vector result. The output is a copy of the three color
- * channels to the three vector components. */
+ * channels to the three vector components.
+ * \{ */
+
class ConvertColorToVectorOperation : public ConversionOperation {
public:
ConvertColorToVectorOperation(Context &context);
@@ -95,11 +114,18 @@ class ConvertColorToVectorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Float Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Float Operation
*
* Takes a vector result and outputs a float result. The output is the average of the three
- * components. */
+ * components.
+ * \{ */
+
+/*
+ *
+ * */
class ConvertVectorToFloatOperation : public ConversionOperation {
public:
ConvertVectorToFloatOperation(Context &context);
@@ -109,11 +135,15 @@ class ConvertVectorToFloatOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Color Operation
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Color Operation
*
* Takes a vector result and outputs a color result. The output is a copy of the three vector
- * components to the three color channels with the alpha channel set to 1. */
+ * components to the three color channels with the alpha channel set to 1.
+ * \{ */
+
class ConvertVectorToColorOperation : public ConversionOperation {
public:
ConvertVectorToColorOperation(Context &context);
@@ -123,4 +153,6 @@ class ConvertVectorToColorOperation : public ConversionOperation {
GPUShader *get_conversion_shader() const override;
};
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_domain.hh b/source/blender/compositor/realtime_compositor/COM_domain.hh
index 54d712f7578..99b40ae61cf 100644
--- a/source/blender/compositor/realtime_compositor/COM_domain.hh
+++ b/source/blender/compositor/realtime_compositor/COM_domain.hh
@@ -28,7 +28,7 @@ struct RealizationOptions {
* result involves projecting it on a different domain, which in turn, involves sampling the
* result at arbitrary locations, the interpolation identifies the method used for computing the
* value at those arbitrary locations. */
- Interpolation interpolation = Interpolation::Nearest;
+ Interpolation interpolation = Interpolation::Bilinear;
/* If true, the result will be repeated infinitely along the horizontal axis when realizing the
* result. If false, regions outside of bounds of the result along the horizontal axis will be
* filled with zeros. */
diff --git a/source/blender/compositor/realtime_compositor/COM_result.hh b/source/blender/compositor/realtime_compositor/COM_result.hh
index a16d68bb92d..f5ecc4c2112 100644
--- a/source/blender/compositor/realtime_compositor/COM_result.hh
+++ b/source/blender/compositor/realtime_compositor/COM_result.hh
@@ -14,7 +14,9 @@
namespace blender::realtime_compositor {
/* Possible data types that operations can operate on. They either represent the base type of the
- * result texture or a single value result. */
+ * result texture or a single value result. The color type represents an RGBA color. And the vector
+ * type represents a generic 4-component vector, which can encode two 2D vectors, one 3D vector
+ * with the last component ignored, or other dimensional data. */
enum class ResultType : uint8_t {
Float,
Vector,
@@ -85,7 +87,7 @@ class Result {
* is a texture. */
union {
float float_value_;
- float3 vector_value_;
+ float4 vector_value_;
float4 color_value_;
};
/* The domain of the result. This only matters if the result was a texture. See the discussion in
@@ -157,7 +159,7 @@ class Result {
/* If the result is a single value result of type vector, return its vector value. Otherwise, an
* uninitialized value is returned. */
- float3 get_vector_value() const;
+ float4 get_vector_value() const;
/* If the result is a single value result of type color, return its color value. Otherwise, an
* uninitialized value is returned. */
@@ -167,7 +169,7 @@ class Result {
float get_float_value_default(float default_value) const;
/* Same as get_vector_value but returns a default value if the result is not a single value. */
- float3 get_vector_value_default(const float3 &default_value) const;
+ float4 get_vector_value_default(const float4 &default_value) const;
/* Same as get_color_value but returns a default value if the result is not a single value. */
float4 get_color_value_default(const float4 &default_value) const;
@@ -178,7 +180,7 @@ class Result {
/* If the result is a single value result of type vector, set its vector value and upload it to
* the texture. Otherwise, an undefined behavior is invoked. */
- void set_vector_value(const float3 &value);
+ void set_vector_value(const float4 &value);
/* If the result is a single value result of type color, set its color value and upload it to the
* texture. Otherwise, an undefined behavior is invoked. */
diff --git a/source/blender/compositor/realtime_compositor/COM_scheduler.hh b/source/blender/compositor/realtime_compositor/COM_scheduler.hh
index 4f778b32145..9f3bc14ae17 100644
--- a/source/blender/compositor/realtime_compositor/COM_scheduler.hh
+++ b/source/blender/compositor/realtime_compositor/COM_scheduler.hh
@@ -16,6 +16,6 @@ using Schedule = VectorSet<DNode>;
/* Computes the execution schedule of the node tree. This is essentially a post-order depth first
* traversal of the node tree from the output node to the leaf input nodes, with informed order of
* traversal of dependencies based on a heuristic estimation of the number of needed buffers. */
-Schedule compute_schedule(DerivedNodeTree &tree);
+Schedule compute_schedule(const DerivedNodeTree &tree);
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh
new file mode 100644
index 00000000000..20fbb156879
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <memory>
+
+#include "BLI_map.hh"
+#include "BLI_math_vec_types.hh"
+
+#include "COM_morphological_distance_feather_weights.hh"
+#include "COM_symmetric_blur_weights.hh"
+#include "COM_symmetric_separable_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* -------------------------------------------------------------------------------------------------
+ * Static Cache Manager
+ *
+ * A static cache manager is a collection of cached resources that can be retrieved when needed and
+ * created if not already available. In particular, each cached resource type has its own Map in
+ * the class, where all instances of that cached resource type are stored and tracked. See the
+ * CachedResource class for more information.
+ *
+ * The manager deletes the cached resources that are no longer needed. A cached resource is said to
+ * be not needed when it was not used in the previous evaluation. This is done through the
+ * following mechanism:
+ *
+ * - Before every evaluation, do the following:
+ * 1. All resources whose CachedResource::needed flag is false are deleted.
+ * 2. The CachedResource::needed flag of all remaining resources is set to false.
+ * - During evaluation, when retrieving any cached resource, set its CachedResource::needed flag to
+ * true.
+ *
+ * In effect, any resource that was used in the previous evaluation but was not used in the current
+ * evaluation will be deleted before the next evaluation. This mechanism is implemented in the
+ * reset() method of the class, which should be called before every evaluation. */
+class StaticCacheManager {
+ private:
+ /* A map that stores all SymmetricBlurWeights cached resources. */
+ Map<SymmetricBlurWeightsKey, std::unique_ptr<SymmetricBlurWeights>> symmetric_blur_weights_;
+
+ /* A map that stores all SymmetricSeparableBlurWeights cached resources. */
+ Map<SymmetricSeparableBlurWeightsKey, std::unique_ptr<SymmetricSeparableBlurWeights>>
+ symmetric_separable_blur_weights_;
+
+ /* A map that stores all MorphologicalDistanceFeatherWeights cached resources. */
+ Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
+ morphological_distance_feather_weights_;
+
+ public:
+ /* Reset the cache manager by deleting the cached resources that are no longer needed because
+ * they weren't used in the last evaluation and prepare the remaining cached resources to track
+ * their needed status in the next evaluation. See the class description for more information.
+ * This should be called before every evaluation. */
+ void reset();
+
+ /* Check if there is an available SymmetricBlurWeights cached resource with the given parameters
+ * in the manager, if one exists, return it, otherwise, return a newly created one and add it to
+ * the manager. In both cases, tag the cached resource as needed to keep it cached for the next
+ * evaluation. */
+ SymmetricBlurWeights &get_symmetric_blur_weights(int type, float2 radius);
+
+ /* Check if there is an available SymmetricSeparableBlurWeights cached resource with the given
+ * parameters in the manager, if one exists, return it, otherwise, return a newly created one and
+ * add it to the manager. In both cases, tag the cached resource as needed to keep it cached for
+ * the next evaluation. */
+ SymmetricSeparableBlurWeights &get_symmetric_separable_blur_weights(int type, float radius);
+
+ /* Check if there is an available MorphologicalDistanceFeatherWeights cached resource with the
+ * given parameters in the manager, if one exists, return it, otherwise, return a newly created
+ * one and add it to the manager. In both cases, tag the cached resource as needed to keep it
+ * cached for the next evaluation. */
+ MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
+ int radius);
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
index cc6641d288f..c68219b0279 100644
--- a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
+++ b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh
@@ -60,8 +60,8 @@ class TexturePool {
/* Shorthand for acquire with GPU_RGBA16F format. */
GPUTexture *acquire_color(int2 size);
- /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors
- * are stored in RGBA textures, due to the limited support for RGB textures. */
+ /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors are
+ * 4D, and are thus stored in RGBA textures. */
GPUTexture *acquire_vector(int2 size);
/* Shorthand for acquire with GPU_R16F format. */
diff --git a/source/blender/compositor/realtime_compositor/COM_utilities.hh b/source/blender/compositor/realtime_compositor/COM_utilities.hh
index 25f9fd0c1b6..efd1bc2b6b0 100644
--- a/source/blender/compositor/realtime_compositor/COM_utilities.hh
+++ b/source/blender/compositor/realtime_compositor/COM_utilities.hh
@@ -17,7 +17,7 @@ namespace blender::realtime_compositor {
using namespace nodes::derived_node_tree_types;
/**
- Get the origin socket of the given node input. If the input is not linked, the socket itself is
+ * Get the origin socket of the given node input. If the input is not linked, the socket itself is
* returned. If the input is linked, the socket that is linked to it is returned, which could
* either be an input or an output. An input socket is returned when the given input is connected
* to an unlinked input of a group input node.
diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh
new file mode 100644
index 00000000000..f6d479f9bbe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_texture.h"
+
+#include "COM_context.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+/* Computes the sum of the red channel of all pixels in the given texture. */
+float sum_red(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the green channel of all pixels in the given texture. */
+float sum_green(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the blue channel of all pixels in the given texture. */
+float sum_blue(Context &context, GPUTexture *texture);
+
+/* Computes the sum of the luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the sum of the logarithm of the luminance of all pixels in the given texture, using the
+ * given luminance coefficients to compute the luminance. */
+float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the sum of the colors of all pixels in the given texture. */
+float4 sum_color(Context &context, GPUTexture *texture);
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+/* Computes the sum of the squared difference between the red channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the green channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the blue channel of all pixels in the given
+ * texture and the given subtrahend. This can be used to compute the standard deviation if the
+ * given subtrahend is the mean. */
+float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend);
+
+/* Computes the sum of the squared difference between the luminance of all pixels in the given
+ * texture and the given subtrahend, using the given luminance coefficients to compute the
+ * luminance. This can be used to compute the standard deviation if the given subtrahend is the
+ * mean. */
+float sum_luminance_squared_difference(Context &context,
+ GPUTexture *texture,
+ float3 luminance_coefficients,
+ float subtrahend);
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+/* Computes the maximum luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the maximum float of all pixels in the given float texture, limited to the given range.
+ * Values outside of the given range are ignored. If non of the pixel values are in the range, the
+ * lower bound of the range is returned. For instance, if the given range is [-10, 10] and the
+ * image contains the values {2, 5, 11}, the maximum will be 5, since 11 is outside of the range.
+ * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite
+ * values, so enforcing an upper bound is beneficial. */
+float maximum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound);
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+/* Computes the minimum luminance of all pixels in the given texture, using the given luminance
+ * coefficients to compute the luminance. */
+float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients);
+
+/* Computes the minimum float of all pixels in the given float texture, limited to the given range.
+ * Values outside of the given range are ignored. If non of the pixel values are in the range, the
+ * upper bound of the range is returned. For instance, if the given range is [-10, 10] and the
+ * image contains the values {-11, 2, 5}, the minimum will be 2, since -11 is outside of the range.
+ * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite
+ * values, so enforcing a lower bound is beneficial. */
+float minimum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound);
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc
new file mode 100644
index 00000000000..9672431992d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "MEM_guardedalloc.h"
+
+#include "GPU_compute.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_context.hh"
+#include "COM_utilities.hh"
+
+#include "COM_algorithm_parallel_reduction.hh"
+
+namespace blender::realtime_compositor {
+
+/* Reduces the given texture into a single value and returns it. The return value should be freed
+ * by a call to MEM_freeN. The return value is either a pointer to a float, or a pointer to an
+ * array of floats that represents a vector. This depends on the given format, which should be
+ * compatible with the reduction shader.
+ *
+ * The given reduction shader should be bound when calling the function and the shader is expected
+ * to be derived from the compositor_parallel_reduction.glsl shader, see that file for more
+ * information. Also see the compositor_parallel_reduction_info.hh file for example shader
+ * definitions. */
+static float *parallel_reduction_dispatch(Context &context,
+ GPUTexture *texture,
+ GPUShader *shader,
+ eGPUTextureFormat format)
+{
+ GPU_shader_uniform_1b(shader, "is_initial_reduction", true);
+
+ GPUTexture *texture_to_reduce = texture;
+ int2 size_to_reduce = int2(GPU_texture_width(texture), GPU_texture_height(texture));
+
+ /* Dispatch the reduction shader until the texture reduces to a single pixel. */
+ while (size_to_reduce != int2(1)) {
+ const int2 reduced_size = math::divide_ceil(size_to_reduce, int2(16));
+ GPUTexture *reduced_texture = context.texture_pool().acquire(reduced_size, format);
+
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx");
+ GPU_texture_bind(texture_to_reduce, texture_image_unit);
+
+ const int image_unit = GPU_shader_get_texture_binding(shader, "output_img");
+ GPU_texture_image_bind(reduced_texture, image_unit);
+
+ GPU_compute_dispatch(shader, reduced_size.x, reduced_size.y, 1);
+
+ GPU_texture_image_unbind(reduced_texture);
+ GPU_texture_unbind(texture_to_reduce);
+
+ /* Release the input texture only if it is not the source texture, since the source texture is
+ * not acquired or owned by the function. */
+ if (texture_to_reduce != texture) {
+ context.texture_pool().release(texture_to_reduce);
+ }
+
+ texture_to_reduce = reduced_texture;
+ size_to_reduce = reduced_size;
+
+ GPU_shader_uniform_1b(shader, "is_initial_reduction", false);
+ }
+
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
+ float *pixel = static_cast<float *>(GPU_texture_read(texture_to_reduce, GPU_DATA_FLOAT, 0));
+
+ /* Release the final texture only if it is not the source texture, since the source texture is
+ * not acquired or owned by the function. */
+ if (texture_to_reduce != texture) {
+ context.texture_pool().release(texture_to_reduce);
+ }
+
+ return pixel;
+}
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+float sum_red(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_red");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_green(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_green");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_blue(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_blue");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_log_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float4 sum_color(Context &context, GPUTexture *texture)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_color");
+ GPU_shader_bind(shader);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_RGBA32F);
+ const float4 sum = float4(reduced_value);
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_red_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_green_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_blue_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+float sum_luminance_squared_difference(Context &context,
+ GPUTexture *texture,
+ float3 luminance_coefficients,
+ float subtrahend)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_sum_luminance_squared_difference");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+ GPU_shader_uniform_1f(shader, "subtrahend", subtrahend);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float sum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return sum;
+}
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_maximum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float maximum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return maximum;
+}
+
+float maximum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_maximum_float_in_range");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "lower_bound", lower_bound);
+ GPU_shader_uniform_1f(shader, "upper_bound", upper_bound);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float maximum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return maximum;
+}
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_minimum_luminance");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float minimum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return minimum;
+}
+
+float minimum_float_in_range(Context &context,
+ GPUTexture *texture,
+ float lower_bound,
+ float upper_bound)
+{
+ GPUShader *shader = context.shader_manager().get("compositor_minimum_float_in_range");
+ GPU_shader_bind(shader);
+
+ GPU_shader_uniform_1f(shader, "lower_bound", lower_bound);
+ GPU_shader_uniform_1f(shader, "upper_bound", upper_bound);
+
+ float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F);
+ const float minimum = *reduced_value;
+ MEM_freeN(reduced_value);
+ GPU_shader_unbind();
+
+ return minimum;
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh
new file mode 100644
index 00000000000..fe3158ef52d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+namespace blender::realtime_compositor {
+
+/* -------------------------------------------------------------------------------------------------
+ * Cached Resource.
+ *
+ * A cached resource is any resource that can be cached across compositor evaluations and across
+ * multiple operations. Cached resources are managed by an instance of a StaticCacheManager and are
+ * freed when they are no longer needed, a state which is represented by the `needed` member in the
+ * class. For more information on the caching mechanism, see the StaticCacheManager class.
+ *
+ * To add a new cached resource:
+ *
+ * - Create a derived class from CachedResource to represent the resource.
+ * - Create a key class that can be used in a Map to identify the resource.
+ * - Add a new Map to StaticCacheManager mapping the key to the resource.
+ * - Reset the contents of the added map in StaticCacheManager::reset.
+ * - Add an appropriate getter method in StaticCacheManager.
+ *
+ * See the existing cached resources for reference. */
+class CachedResource {
+ public:
+ /* A flag that represents the needed status of the cached resource. See the StaticCacheManager
+ * class for more information on how this member is utilized in the caching mechanism. */
+ bool needed = true;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh
new file mode 100644
index 00000000000..cd6827bdd6b
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Morphological Distance Feather Key.
+ */
+class MorphologicalDistanceFeatherWeightsKey {
+ public:
+ int type;
+ float radius;
+
+ MorphologicalDistanceFeatherWeightsKey(int type, float radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const MorphologicalDistanceFeatherWeightsKey &a,
+ const MorphologicalDistanceFeatherWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Morphological Distance Feather Weights.
+ *
+ * A cached resource that computes and caches 1D GPU textures containing the weights of the
+ * separable Gaussian filter of the given radius as well as an inverse distance falloff of the
+ * given type and radius. The weights and falloffs are symmetric, because the Gaussian and falloff
+ * functions are all even functions. Consequently, only the positive half of the filter is computed
+ * and the shader takes that into consideration. */
+class MorphologicalDistanceFeatherWeights : public CachedResource {
+ private:
+ GPUTexture *weights_texture_ = nullptr;
+ GPUTexture *distance_falloffs_texture_ = nullptr;
+
+ public:
+ MorphologicalDistanceFeatherWeights(int type, int radius);
+
+ ~MorphologicalDistanceFeatherWeights();
+
+ void compute_weights(int radius);
+
+ void compute_distance_falloffs(int type, int radius);
+
+ void bind_weights_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_weights_as_texture() const;
+
+ void bind_distance_falloffs_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_distance_falloffs_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh
new file mode 100644
index 00000000000..05d3c7c6f3e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Symmetric Blur Weights Key.
+ */
+class SymmetricBlurWeightsKey {
+ public:
+ int type;
+ float2 radius;
+
+ SymmetricBlurWeightsKey(int type, float2 radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Symmetric Blur Weights.
+ *
+ * A cached resource that computes and caches a 2D GPU texture containing the weights of the filter
+ * of the given type and radius. The filter is assumed to be symmetric, because the filter
+ * functions are evaluated on the normalized distance to the center. Consequently, only the upper
+ * right quadrant are computed and the shader takes that into consideration. */
+class SymmetricBlurWeights : public CachedResource {
+ private:
+ GPUTexture *texture_ = nullptr;
+
+ public:
+ SymmetricBlurWeights(int type, float2 radius);
+
+ ~SymmetricBlurWeights();
+
+ void bind_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh
new file mode 100644
index 00000000000..85e75e4535d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include <cstdint>
+
+#include "BLI_math_vec_types.hh"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_cached_resource.hh"
+
+namespace blender::realtime_compositor {
+
+/* ------------------------------------------------------------------------------------------------
+ * Symmetric Separable Blur Weights Key.
+ */
+class SymmetricSeparableBlurWeightsKey {
+ public:
+ int type;
+ float radius;
+
+ SymmetricSeparableBlurWeightsKey(int type, float radius);
+
+ uint64_t hash() const;
+};
+
+bool operator==(const SymmetricSeparableBlurWeightsKey &a,
+ const SymmetricSeparableBlurWeightsKey &b);
+
+/* -------------------------------------------------------------------------------------------------
+ * Symmetric Separable Blur Weights.
+ *
+ * A cached resource that computes and caches a 1D GPU texture containing the weights of the
+ * separable filter of the given type and radius. The filter is assumed to be symmetric, because
+ * the filter functions are all even functions. Consequently, only the positive half of the filter
+ * is computed and the shader takes that into consideration. */
+class SymmetricSeparableBlurWeights : public CachedResource {
+ private:
+ GPUTexture *texture_ = nullptr;
+
+ public:
+ SymmetricSeparableBlurWeights(int type, float radius);
+
+ ~SymmetricSeparableBlurWeights();
+
+ void bind_as_texture(GPUShader *shader, const char *texture_name) const;
+
+ void unbind_as_texture() const;
+};
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc
new file mode 100644
index 00000000000..eac88b907b8
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cmath>
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+
+#include "RE_pipeline.h"
+
+#include "DNA_scene_types.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_morphological_distance_feather_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Morphological Distance Feather Weights Key.
+ */
+
+MorphologicalDistanceFeatherWeightsKey::MorphologicalDistanceFeatherWeightsKey(int type,
+ float radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t MorphologicalDistanceFeatherWeightsKey::hash() const
+{
+ return get_default_hash_2(type, radius);
+}
+
+bool operator==(const MorphologicalDistanceFeatherWeightsKey &a,
+ const MorphologicalDistanceFeatherWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Morphological Distance Feather Weights.
+ */
+
+MorphologicalDistanceFeatherWeights::MorphologicalDistanceFeatherWeights(int type, int radius)
+{
+ compute_weights(radius);
+ compute_distance_falloffs(type, radius);
+}
+
+MorphologicalDistanceFeatherWeights::~MorphologicalDistanceFeatherWeights()
+{
+ GPU_texture_free(weights_texture_);
+ GPU_texture_free(distance_falloffs_texture_);
+}
+
+void MorphologicalDistanceFeatherWeights::compute_weights(int radius)
+{
+ /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
+ * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
+ * odd and there is a center weight. */
+ const int size = radius + 1;
+ Array<float> weights(size);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(R_FILTER_GAUSS, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Second, compute the other weights in the positive direction, making sure to add double the
+ * weight to the sum of weights because the filter is symmetric and we only loop over half of
+ * it. Skip the center weight already computed by dropping the front index. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : weights.index_range().drop_front(1)) {
+ const float weight = RE_filter_value(R_FILTER_GAUSS, i * scale);
+ weights[i] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int i : weights.index_range()) {
+ weights[i] /= sum;
+ }
+
+ weights_texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
+}
+
+/* Computes a falloff that is equal to 1 at an input of zero and decrease to zero at an input of 1,
+ * with the rate of decrease depending on the falloff type. */
+static float compute_distance_falloff(int type, float x)
+{
+ x = 1.0f - x;
+
+ switch (type) {
+ case PROP_SMOOTH:
+ return 3.0f * x * x - 2.0f * x * x * x;
+ case PROP_SPHERE:
+ return std::sqrt(2.0f * x - x * x);
+ case PROP_ROOT:
+ return std::sqrt(x);
+ case PROP_SHARP:
+ return x * x;
+ case PROP_INVSQUARE:
+ return x * (2.0f - x);
+ case PROP_LIN:
+ return x;
+ default:
+ BLI_assert_unreachable();
+ return x;
+ }
+}
+
+void MorphologicalDistanceFeatherWeights::compute_distance_falloffs(int type, int radius)
+{
+ /* The size of the distance falloffs is double the radius plus 1, but since the falloffs are
+ * symmetric, we only compute half of them and no doubling happens. We add 1 to make sure the
+ * falloffs size is always odd and there is a center falloff. */
+ const int size = radius + 1;
+ Array<float> falloffs(size);
+
+ /* Compute the distance falloffs in the positive direction only, because the falloffs are
+ * symmetric. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : falloffs.index_range()) {
+ falloffs[i] = compute_distance_falloff(type, i * scale);
+ }
+
+ distance_falloffs_texture_ = GPU_texture_create_1d(
+ "Distance Factors", size, 1, GPU_R16F, falloffs.data());
+}
+
+void MorphologicalDistanceFeatherWeights::bind_weights_as_texture(GPUShader *shader,
+ const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(weights_texture_, texture_image_unit);
+}
+
+void MorphologicalDistanceFeatherWeights::unbind_weights_as_texture() const
+{
+ GPU_texture_unbind(weights_texture_);
+}
+
+void MorphologicalDistanceFeatherWeights::bind_distance_falloffs_as_texture(
+ GPUShader *shader, const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(distance_falloffs_texture_, texture_image_unit);
+}
+
+void MorphologicalDistanceFeatherWeights::unbind_distance_falloffs_as_texture() const
+{
+ GPU_texture_unbind(distance_falloffs_texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc
new file mode 100644
index 00000000000..a22d32a8e18
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "RE_pipeline.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_symmetric_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Symmetric Blur Weights Key.
+ */
+
+SymmetricBlurWeightsKey::SymmetricBlurWeightsKey(int type, float2 radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t SymmetricBlurWeightsKey::hash() const
+{
+ return get_default_hash_3(type, radius.x, radius.y);
+}
+
+bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Symmetric Blur Weights.
+ */
+
+SymmetricBlurWeights::SymmetricBlurWeights(int type, float2 radius)
+{
+ /* The full size of filter is double the radius plus 1, but since the filter is symmetric, we
+ * only compute a single quadrant of it and so no doubling happens. We add 1 to make sure the
+ * filter size is always odd and there is a center weight. */
+ const float2 scale = math::safe_divide(float2(1.0f), radius);
+ const int2 size = int2(math::ceil(radius)) + int2(1);
+ Array<float> weights(size.x * size.y);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(type, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Then, compute the weights along the positive x axis, making sure to add double the weight to
+ * the sum of weights because the filter is symmetric and we only loop over the positive half
+ * of the x axis. Skip the center weight already computed by dropping the front index. */
+ for (const int x : IndexRange(size.x).drop_front(1)) {
+ const float weight = RE_filter_value(type, x * scale.x);
+ weights[x] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Then, compute the weights along the positive y axis, making sure to add double the weight to
+ * the sum of weights because the filter is symmetric and we only loop over the positive half
+ * of the y axis. Skip the center weight already computed by dropping the front index. */
+ for (const int y : IndexRange(size.y).drop_front(1)) {
+ const float weight = RE_filter_value(type, y * scale.y);
+ weights[size.x * y] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Then, compute the other weights in the upper right quadrant, making sure to add quadruple
+ * the weight to the sum of weights because the filter is symmetric and we only loop over one
+ * quadrant of it. Skip the weights along the y and x axis already computed by dropping the
+ * front index. */
+ for (const int y : IndexRange(size.y).drop_front(1)) {
+ for (const int x : IndexRange(size.x).drop_front(1)) {
+ const float weight = RE_filter_value(type, math::length(float2(x, y) * scale));
+ weights[size.x * y + x] = weight;
+ sum += weight * 4.0f;
+ }
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int y : IndexRange(size.y)) {
+ for (const int x : IndexRange(size.x)) {
+ weights[size.x * y + x] /= sum;
+ }
+ }
+
+ texture_ = GPU_texture_create_2d("Weights", size.x, size.y, 1, GPU_R16F, weights.data());
+}
+
+SymmetricBlurWeights::~SymmetricBlurWeights()
+{
+ GPU_texture_free(texture_);
+}
+
+void SymmetricBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(texture_, texture_image_unit);
+}
+
+void SymmetricBlurWeights::unbind_as_texture() const
+{
+ GPU_texture_unbind(texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc
new file mode 100644
index 00000000000..b8c47d5a5d0
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <cstdint>
+
+#include "BLI_array.hh"
+#include "BLI_hash.hh"
+#include "BLI_index_range.hh"
+#include "BLI_math_base.hh"
+
+#include "RE_pipeline.h"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_symmetric_separable_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Symmetric Separable Blur Weights Key.
+ */
+
+SymmetricSeparableBlurWeightsKey::SymmetricSeparableBlurWeightsKey(int type, float radius)
+ : type(type), radius(radius)
+{
+}
+
+uint64_t SymmetricSeparableBlurWeightsKey::hash() const
+{
+ return get_default_hash_2(type, radius);
+}
+
+bool operator==(const SymmetricSeparableBlurWeightsKey &a,
+ const SymmetricSeparableBlurWeightsKey &b)
+{
+ return a.type == b.type && a.radius == b.radius;
+}
+
+/* --------------------------------------------------------------------
+ * Symmetric Separable Blur Weights.
+ */
+
+SymmetricSeparableBlurWeights::SymmetricSeparableBlurWeights(int type, float radius)
+{
+ /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
+ * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
+ * odd and there is a center weight. */
+ const int size = math::ceil(radius) + 1;
+ Array<float> weights(size);
+
+ float sum = 0.0f;
+
+ /* First, compute the center weight. */
+ const float center_weight = RE_filter_value(type, 0.0f);
+ weights[0] = center_weight;
+ sum += center_weight;
+
+ /* Second, compute the other weights in the positive direction, making sure to add double the
+ * weight to the sum of weights because the filter is symmetric and we only loop over half of
+ * it. Skip the center weight already computed by dropping the front index. */
+ const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
+ for (const int i : weights.index_range().drop_front(1)) {
+ const float weight = RE_filter_value(type, i * scale);
+ weights[i] = weight;
+ sum += weight * 2.0f;
+ }
+
+ /* Finally, normalize the weights. */
+ for (const int i : weights.index_range()) {
+ weights[i] /= sum;
+ }
+
+ texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data());
+}
+
+SymmetricSeparableBlurWeights::~SymmetricSeparableBlurWeights()
+{
+ GPU_texture_free(texture_);
+}
+
+void SymmetricSeparableBlurWeights::bind_as_texture(GPUShader *shader,
+ const char *texture_name) const
+{
+ const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
+ GPU_texture_bind(texture_, texture_image_unit);
+}
+
+void SymmetricSeparableBlurWeights::unbind_as_texture() const
+{
+ GPU_texture_unbind(texture_);
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/context.cc b/source/blender/compositor/realtime_compositor/intern/context.cc
index 64ac29af3d1..0b123a2c271 100644
--- a/source/blender/compositor/realtime_compositor/intern/context.cc
+++ b/source/blender/compositor/realtime_compositor/intern/context.cc
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "COM_context.hh"
+#include "COM_static_cache_manager.hh"
#include "COM_static_shader_manager.hh"
#include "COM_texture_pool.hh"
@@ -17,9 +18,8 @@ int Context::get_frame_number() const
float Context::get_time() const
{
- const float frame_number = static_cast<float>(get_frame_number());
- const float frame_rate = static_cast<float>(get_scene()->r.frs_sec) /
- static_cast<float>(get_scene()->r.frs_sec_base);
+ const float frame_number = float(get_frame_number());
+ const float frame_rate = float(get_scene()->r.frs_sec) / float(get_scene()->r.frs_sec_base);
return frame_number / frame_rate;
}
@@ -33,4 +33,9 @@ StaticShaderManager &Context::shader_manager()
return shader_manager_;
}
+StaticCacheManager &Context::cache_manager()
+{
+ return cache_manager_;
+}
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
index d6bf74ffbee..dd585aedec6 100644
--- a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc
@@ -12,9 +12,9 @@
namespace blender::realtime_compositor {
-/* -------------------------------------------------------------------------------------------------
- * Conversion Operation.
- */
+/* -------------------------------------------------------------------- */
+/** \name Conversion Operation
+ * \{ */
void ConversionOperation::execute()
{
@@ -79,9 +79,11 @@ SimpleOperation *ConversionOperation::construct_if_needed(Context &context,
return nullptr;
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Vector Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Vector Operation
+ * \{ */
ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
: ConversionOperation(context)
@@ -94,7 +96,7 @@ ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context)
void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &output)
{
- output.set_vector_value(float3(input.get_float_value()));
+ output.set_vector_value(float4(float3(input.get_float_value()), 0.0f));
}
GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
@@ -102,9 +104,11 @@ GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_float_to_vector");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Float To Color Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Float to Color Operation
+ * \{ */
ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context)
: ConversionOperation(context)
@@ -127,9 +131,11 @@ GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_float_to_color");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Float Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Float Operation
+ * \{ */
ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context)
: ConversionOperation(context)
@@ -151,9 +157,11 @@ GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_color_to_float");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Color To Vector Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Color to Vector Operation
+ * \{ */
ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
: ConversionOperation(context)
@@ -167,7 +175,7 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context)
void ConvertColorToVectorOperation::execute_single(const Result &input, Result &output)
{
float4 color = input.get_color_value();
- output.set_vector_value(float3(color));
+ output.set_vector_value(float4(float3(color), 0.0f));
}
GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
@@ -175,9 +183,11 @@ GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_color_to_vector");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Float Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Float Operation
+ * \{ */
ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
: ConversionOperation(context)
@@ -190,7 +200,7 @@ ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context)
void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &output)
{
- float3 vector = input.get_vector_value();
+ float4 vector = input.get_vector_value();
output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f);
}
@@ -199,9 +209,11 @@ GPUShader *ConvertVectorToFloatOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_vector_to_float");
}
-/* -------------------------------------------------------------------------------------------------
- * Convert Vector To Color Operation.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Convert Vector to Color Operation
+ * \{ */
ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
: ConversionOperation(context)
@@ -214,7 +226,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context)
void ConvertVectorToColorOperation::execute_single(const Result &input, Result &output)
{
- output.set_color_value(float4(input.get_vector_value(), 1.0f));
+ output.set_color_value(float4(float3(input.get_vector_value()), 1.0f));
}
GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const
@@ -222,4 +234,6 @@ GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const
return shader_manager().get("compositor_convert_vector_to_color");
}
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
index 48457bec199..1cd7d4f8951 100644
--- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc
+++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc
@@ -28,6 +28,7 @@ Evaluator::Evaluator(Context &context, bNodeTree &node_tree)
void Evaluator::evaluate()
{
+ context_.cache_manager().reset();
context_.texture_pool().reset();
if (!is_compiled_) {
diff --git a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
index b3cc86b5f79..99f7cd90557 100644
--- a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc
@@ -38,7 +38,7 @@ void InputSingleValueOperation::execute()
break;
case ResultType::Vector:
result.set_vector_value(
- float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value));
+ float4(float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value), 0.0f));
break;
case ResultType::Color:
result.set_color_value(float4(bsocket->default_value_typed<bNodeSocketValueRGBA>()->value));
diff --git a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
index 817293c0fa6..e5c448d0e33 100644
--- a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc
@@ -38,8 +38,8 @@ void RealizeOnDomainOperation::execute()
GPU_shader_bind(shader);
/* Transform the input space into the domain space. */
- const float3x3 local_transformation = input.domain().transformation *
- domain_.transformation.inverted();
+ const float3x3 local_transformation = domain_.transformation.inverted() *
+ input.domain().transformation;
/* Set the origin of the transformation to be the center of the domain. */
const float3x3 transformation = float3x3::from_origin_transformation(
diff --git a/source/blender/compositor/realtime_compositor/intern/result.cc b/source/blender/compositor/realtime_compositor/intern/result.cc
index 8059367d211..d89f1c86167 100644
--- a/source/blender/compositor/realtime_compositor/intern/result.cc
+++ b/source/blender/compositor/realtime_compositor/intern/result.cc
@@ -62,7 +62,7 @@ void Result::allocate_invalid()
set_float_value(0.0f);
break;
case ResultType::Vector:
- set_vector_value(float3(0.0f));
+ set_vector_value(float4(0.0f));
break;
case ResultType::Color:
set_color_value(float4(0.0f));
@@ -125,7 +125,7 @@ float Result::get_float_value() const
return float_value_;
}
-float3 Result::get_vector_value() const
+float4 Result::get_vector_value() const
{
return vector_value_;
}
@@ -143,7 +143,7 @@ float Result::get_float_value_default(float default_value) const
return default_value;
}
-float3 Result::get_vector_value_default(const float3 &default_value) const
+float4 Result::get_vector_value_default(const float4 &default_value) const
{
if (is_single_value()) {
return get_vector_value();
@@ -165,7 +165,7 @@ void Result::set_float_value(float value)
GPU_texture_update(texture_, GPU_DATA_FLOAT, &float_value_);
}
-void Result::set_vector_value(const float3 &value)
+void Result::set_vector_value(const float4 &value)
{
vector_value_ = value;
GPU_texture_update(texture_, GPU_DATA_FLOAT, vector_value_);
diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc
index ac5cc55a73f..0d3cce7af39 100644
--- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc
+++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc
@@ -8,6 +8,7 @@
#include "NOD_derived_node_tree.hh"
+#include "BKE_node.h"
#include "BKE_node_runtime.hh"
#include "COM_scheduler.hh"
@@ -17,36 +18,103 @@ namespace blender::realtime_compositor {
using namespace nodes::derived_node_tree_types;
-/* Compute the output node whose result should be computed. The output node is the node marked as
- * NODE_DO_OUTPUT. If multiple types of output nodes are marked, then the preference will be
- * CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. If no output node exists, a null
- * node will be returned. */
-static DNode compute_output_node(DerivedNodeTree &tree)
+/* Find the active context from the given context and its descendants contexts. The active context
+ * is the one whose node instance key matches the active_viewer_key stored in the root node tree.
+ * The instance key of each context is computed by calling BKE_node_instance_key given the key of
+ * the parent as well as the group node making the context. */
+static const DTreeContext *find_active_context_recursive(const DTreeContext *context,
+ bNodeInstanceKey key)
{
- const bNodeTree &root_tree = tree.root_context().btree();
+ /* The instance key of the given context matches the active viewer instance key, so this is the
+ * active context, return it. */
+ if (key.value == context->derived_tree().root_context().btree().active_viewer_key.value) {
+ return context;
+ }
+
+ /* For each of the group nodes, compute their instance key and contexts and call this function
+ * recursively. */
+ for (const bNode *group_node : context->btree().group_nodes()) {
+ const bNodeInstanceKey child_key = BKE_node_instance_key(key, &context->btree(), group_node);
+ const DTreeContext *child_context = context->child_context(*group_node);
+ const DTreeContext *found_context = find_active_context_recursive(child_context, child_key);
+
+ /* If the found context is null, that means neither the child context nor one of its descendant
+ * contexts is active. */
+ if (!found_context) {
+ continue;
+ }
+
+ /* Otherwise, we have found our active context, return it. */
+ return found_context;
+ }
+
+ /* Neither the given context nor one of its descendant contexts is active, so return null. */
+ return nullptr;
+}
+
+/* Find the active context for the given node tree. The active context represents the node tree
+ * currently being edited. In most cases, that would be the top level node tree itself, but in the
+ * case where the user is editing the node tree of a node group, the active context would be a
+ * representation of the node tree of that node group. Note that the context also stores the group
+ * node that the user selected to edit the node tree, so the context fully represents a particular
+ * instance of the node group. */
+static const DTreeContext *find_active_context(const DerivedNodeTree &tree)
+{
+ /* The root context has an instance key of NODE_INSTANCE_KEY_BASE by definition. */
+ return find_active_context_recursive(&tree.root_context(), NODE_INSTANCE_KEY_BASE);
+}
+
+/* Return the output node which is marked as NODE_DO_OUTPUT. If multiple types of output nodes are
+ * marked, then the preference will be CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER.
+ * If no output node exists, a null node will be returned. */
+static DNode find_output_in_context(const DTreeContext *context)
+{
+ const bNodeTree &tree = context->btree();
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeComposite")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeComposite")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeViewer")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- for (const bNode *node : root_tree.nodes_by_type("CompositorNodeSplitViewer")) {
+ for (const bNode *node : tree.nodes_by_type("CompositorNodeSplitViewer")) {
if (node->flag & NODE_DO_OUTPUT) {
- return DNode(&tree.root_context(), node);
+ return DNode(context, node);
}
}
- /* No output node found, return a null node. */
return DNode();
}
+/* Compute the output node whose result should be computed. This node is the output node that
+ * satisfies the requirements in the find_output_in_context function. First, the active context is
+ * searched for an output node, if non was found, the root context is search. For more information
+ * on what contexts mean here, see the find_active_context function. */
+static DNode compute_output_node(const DerivedNodeTree &tree)
+{
+ const DTreeContext *active_context = find_active_context(tree);
+
+ const DNode node = find_output_in_context(active_context);
+ if (node) {
+ return node;
+ }
+
+ /* If the active context is the root one and no output node was found, we consider this node tree
+ * to have no output node, even if one of the non-active descendants have an output node. */
+ if (active_context->is_root()) {
+ return DNode();
+ }
+
+ /* The active context doesn't have an output node, search in the root context as a fallback. */
+ return find_output_in_context(&tree.root_context());
+}
+
/* A type representing a mapping that associates each node with a heuristic estimation of the
* number of intermediate buffers needed to compute it and all of its dependencies. See the
* compute_number_of_needed_buffers function for more information. */
@@ -225,7 +293,7 @@ static NeededBuffers compute_number_of_needed_buffers(DNode output_node)
* doesn't always guarantee an optimal evaluation order, as the optimal evaluation order is very
* difficult to compute, however, this method works well in most cases. Moreover it assumes that
* all buffers will have roughly the same size, which may not always be the case. */
-Schedule compute_schedule(DerivedNodeTree &tree)
+Schedule compute_schedule(const DerivedNodeTree &tree)
{
Schedule schedule;
diff --git a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
index 8e52baf63ec..88efdae1872 100644
--- a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
+++ b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc
@@ -273,7 +273,7 @@ static const char *get_store_function_name(ResultType type)
void ShaderOperation::populate_operation_result(DOutputSocket output_socket, GPUMaterial *material)
{
- const unsigned int output_id = output_sockets_to_output_identifiers_map_.size();
+ const uint output_id = output_sockets_to_output_identifiers_map_.size();
std::string output_identifier = "output" + std::to_string(output_id);
const ResultType result_type = get_node_socket_result_type(output_socket.bsocket());
diff --git a/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc
new file mode 100644
index 00000000000..da78412a815
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <memory>
+
+#include "BLI_math_vec_types.hh"
+
+#include "COM_morphological_distance_feather_weights.hh"
+#include "COM_symmetric_blur_weights.hh"
+#include "COM_symmetric_separable_blur_weights.hh"
+
+#include "COM_static_cache_manager.hh"
+
+namespace blender::realtime_compositor {
+
+/* --------------------------------------------------------------------
+ * Static Cache Manager.
+ */
+
+void StaticCacheManager::reset()
+{
+ /* First, delete all resources that are no longer needed. */
+ symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
+ symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
+ morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
+
+ /* Second, reset the needed status of the remaining resources to false to ready them to track
+ * their needed status for the next evaluation. */
+ for (auto &value : symmetric_blur_weights_.values()) {
+ value->needed = false;
+ }
+ for (auto &value : symmetric_separable_blur_weights_.values()) {
+ value->needed = false;
+ }
+ for (auto &value : morphological_distance_feather_weights_.values()) {
+ value->needed = false;
+ }
+}
+
+SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
+{
+ const SymmetricBlurWeightsKey key(type, radius);
+
+ auto &weights = *symmetric_blur_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<SymmetricBlurWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+SymmetricSeparableBlurWeights &StaticCacheManager::get_symmetric_separable_blur_weights(
+ int type, float radius)
+{
+ const SymmetricSeparableBlurWeightsKey key(type, radius);
+
+ auto &weights = *symmetric_separable_blur_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<SymmetricSeparableBlurWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+MorphologicalDistanceFeatherWeights &StaticCacheManager::
+ get_morphological_distance_feather_weights(int type, int radius)
+{
+ const MorphologicalDistanceFeatherWeightsKey key(type, radius);
+
+ auto &weights = *morphological_distance_feather_weights_.lookup_or_add_cb(
+ key, [&]() { return std::make_unique<MorphologicalDistanceFeatherWeights>(type, radius); });
+
+ weights.needed = true;
+ return weights;
+}
+
+} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
index 1568970a030..4b476574d72 100644
--- a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
+++ b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc
@@ -13,9 +13,9 @@
namespace blender::realtime_compositor {
-/* --------------------------------------------------------------------
- * Texture Pool Key.
- */
+/* -------------------------------------------------------------------- */
+/** \name Texture Pool Key
+ * \{ */
TexturePoolKey::TexturePoolKey(int2 size, eGPUTextureFormat format) : size(size), format(format)
{
@@ -37,9 +37,11 @@ bool operator==(const TexturePoolKey &a, const TexturePoolKey &b)
return a.size == b.size && a.format == b.format;
}
-/* --------------------------------------------------------------------
- * Texture Pool.
- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Texture Pool
+ * \{ */
GPUTexture *TexturePool::acquire(int2 size, eGPUTextureFormat format)
{
@@ -62,7 +64,7 @@ GPUTexture *TexturePool::acquire_color(int2 size)
GPUTexture *TexturePool::acquire_vector(int2 size)
{
- /* Vectors are stored in RGBA textures because RGB textures have limited support. */
+ /* Vectors are 4D, and are thus stored in RGBA textures. */
return acquire(size, GPU_RGBA16F);
}
@@ -81,4 +83,6 @@ void TexturePool::reset()
textures_.clear();
}
+/** \} */
+
} // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc
index 1a5823b8441..25472d6ed50 100644
--- a/source/blender/compositor/realtime_compositor/intern/utilities.cc
+++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc
@@ -71,7 +71,7 @@ bool is_output_linked_to_node_conditioned(DOutputSocket output, FunctionRef<bool
{
bool condition_satisfied = false;
output.foreach_target_socket(
- [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) {
+ [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) {
if (condition(target.node())) {
condition_satisfied = true;
return;
@@ -85,7 +85,7 @@ int number_of_inputs_linked_to_output_conditioned(DOutputSocket output,
{
int count = 0;
output.foreach_target_socket(
- [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) {
+ [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) {
if (condition(target)) {
count++;
}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl
new file mode 100644
index 00000000000..d55c8efd4c6
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl
@@ -0,0 +1,11 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ /* The lower bound is inclusive and upper bound is exclusive. */
+ bool is_inside = all(greaterThanEqual(texel, lower_bound)) && all(lessThan(texel, upper_bound));
+ /* Write the pixel color if it is inside the cropping region, otherwise, write zero. */
+ vec4 color = is_inside ? texture_load(input_tx, texel) : vec4(0.0);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl
new file mode 100644
index 00000000000..c7c5ada7a9f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 center_determinator = texture_load(determinator_tx, texel);
+
+ /* Go over the pixels in the blur window of the specified radius around the center pixel, and for
+ * pixels whose determinator is close enough to the determinator of the center pixel, accumulate
+ * their color as well as their weights. */
+ float accumulated_weight = 0.0;
+ vec4 accumulated_color = vec4(0.0);
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ vec4 determinator = texture_load(determinator_tx, texel + ivec2(x, y));
+ float difference = dot(abs(center_determinator - determinator).rgb, vec3(1.0));
+
+ if (difference < threshold) {
+ accumulated_weight += 1.0;
+ accumulated_color += texture_load(input_tx, texel + ivec2(x, y));
+ }
+ }
+ }
+
+ /* Write the accumulated color divided by the accumulated weight if any pixel in the window was
+ * accumulated, otherwise, write a fallback black color. */
+ vec4 fallback = vec4(vec3(0.0), 1.0);
+ vec4 color = (accumulated_weight != 0.0) ? (accumulated_color / accumulated_weight) : fallback;
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl
new file mode 100644
index 00000000000..c7ac620f99b
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl
@@ -0,0 +1,66 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+vec4 load_input(ivec2 texel)
+{
+ vec4 color;
+ if (extend_bounds) {
+ /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So
+ * we load the input with an offset by the radius amount and fallback to a transparent color if
+ * it is out of bounds. */
+ color = texture_load(input_tx, texel - radius, vec4(0.0));
+ }
+ else {
+ color = texture_load(input_tx, texel);
+ }
+
+ return color;
+}
+
+/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
+ * the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
+ * Note that we load the weights texture inverted along both directions to maintain the shape of
+ * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
+ * weights texture whose right half is all ones and whose left half is all zeros. Further, consider
+ * that we are blurring a single white pixel on a black background. When computing the value of a
+ * pixel that is to the right of the white pixel, the white pixel will be in the left region of the
+ * search window, and consequently, without inversion, a zero will be sampled from the left side of
+ * the weights texture and result will be zero. However, what we expect is that pixels to the right
+ * of the white pixel will be white, that is, they should sample a weight of 1 from the right side
+ * of the weights texture, hence the need for inversion. */
+vec4 load_weight(ivec2 texel)
+{
+ /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
+ * to sample at the center of the pixels, then divide by the upper bound plus one to transform
+ * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
+ * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
+ * mentioned in the function description. */
+ return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* The mask input is treated as a boolean. If it is zero, then no blurring happens for this
+ * pixel. Otherwise, the pixel is blurred normally and the mask value is irrelevant. */
+ float mask = texture_load(mask_tx, texel).x;
+ if (mask == 0.0) {
+ imageStore(output_img, texel, texture_load(input_tx, texel));
+ return;
+ }
+
+ /* Go over the window of the given radius and accumulate the colors multiplied by their
+ * respective weights as well as the weights themselves. */
+ vec4 accumulated_color = vec4(0.0);
+ vec4 accumulated_weight = vec4(0.0);
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ vec4 weight = load_weight(ivec2(x, y));
+ accumulated_color += load_input(texel + ivec2(x, y)) * weight;
+ accumulated_weight += weight;
+ }
+ }
+
+ imageStore(output_img, texel, safe_divide(accumulated_color, accumulated_weight));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl
new file mode 100644
index 00000000000..9383bbf9825
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl
@@ -0,0 +1,71 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
+ * the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
+ * Note that we load the weights texture inverted along both directions to maintain the shape of
+ * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
+ * weights texture whose right half is all ones and whose left half is all zeros. Further, consider
+ * that we are blurring a single white pixel on a black background. When computing the value of a
+ * pixel that is to the right of the white pixel, the white pixel will be in the left region of the
+ * search window, and consequently, without inversion, a zero will be sampled from the left side of
+ * the weights texture and result will be zero. However, what we expect is that pixels to the right
+ * of the white pixel will be white, that is, they should sample a weight of 1 from the right side
+ * of the weights texture, hence the need for inversion. */
+vec4 load_weight(ivec2 texel, float radius)
+{
+ /* The center zero texel is always assigned a unit weight regardless of the corresponding weight
+ * in the weights texture. That's to guarantee that at last the center pixel will be accumulated
+ * even if the weights texture is zero at its center. */
+ if (texel == ivec2(0)) {
+ return vec4(1.0);
+ }
+
+ /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
+ * to sample at the center of the pixels, then divide by the upper bound plus one to transform
+ * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
+ * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
+ * mentioned in the function description. */
+ return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* The mask input is treated as a boolean. If it is zero, then no blurring happens for this
+ * pixel. Otherwise, the pixel is blurred normally and the mask value is irrelevant. */
+ float mask = texture_load(mask_tx, texel).x;
+ if (mask == 0.0) {
+ imageStore(output_img, texel, texture_load(input_tx, texel));
+ return;
+ }
+
+ float center_size = texture_load(size_tx, texel).x * base_size;
+
+ /* Go over the window of the given search radius and accumulate the colors multiplied by their
+ * respective weights as well as the weights themselves, but only if both the size of the center
+ * pixel and the size of the candidate pixel are less than both the x and y distances of the
+ * candidate pixel. */
+ vec4 accumulated_color = vec4(0.0);
+ vec4 accumulated_weight = vec4(0.0);
+ for (int y = -search_radius; y <= search_radius; y++) {
+ for (int x = -search_radius; x <= search_radius; x++) {
+ float candidate_size = texture_load(size_tx, texel + ivec2(x, y)).x * base_size;
+
+ /* Skip accumulation if either the x or y distances of the candidate pixel are larger than
+ * either the center or candidate pixel size. Note that the max and min functions here denote
+ * "either" in the aforementioned description. */
+ float size = min(center_size, candidate_size);
+ if (max(abs(x), abs(y)) > size) {
+ continue;
+ }
+
+ vec4 weight = load_weight(ivec2(x, y), size);
+ accumulated_color += texture_load(input_tx, texel + ivec2(x, y)) * weight;
+ accumulated_weight += weight;
+ }
+ }
+
+ imageStore(output_img, texel, safe_divide(accumulated_color, accumulated_weight));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl
new file mode 100644
index 00000000000..6e98aa9fe17
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl
@@ -0,0 +1,118 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Get the 2D vertex position of the vertex with the given index in the regular polygon
+ * representing this bokeh. The polygon is rotated by the rotation amount and have a unit
+ * circumradius. The regular polygon is one whose vertices' exterior angles are given by
+ * exterior_angle. See the bokeh function for more information. */
+vec2 get_regular_polygon_vertex_position(int vertex_index)
+{
+ float angle = exterior_angle * vertex_index - rotation;
+ return vec2(cos(angle), sin(angle));
+}
+
+/* Find the closest point to the given point on the given line. This assumes the length of the
+ * given line is not zero. */
+vec2 closest_point_on_line(vec2 point, vec2 line_start, vec2 line_end)
+{
+ vec2 line_vector = line_end - line_start;
+ vec2 point_vector = point - line_start;
+ float line_length_squared = dot(line_vector, line_vector);
+ float parameter = dot(point_vector, line_vector) / line_length_squared;
+ return line_start + line_vector * parameter;
+}
+
+/* Compute the value of the bokeh at the given point. The computed bokeh is essentially a regular
+ * polygon centered in space having the given circumradius. The regular polygon is one whose
+ * vertices' exterior angles are given by "exterior_angle", which relates to the number of vertices
+ * n through the equation "exterior angle = 2 pi / n". The regular polygon may additionally morph
+ * into a shape with the given properties:
+ *
+ * - The regular polygon may have a circular hole in its center whose radius is controlled by the
+ * "catadioptric" value.
+ * - The regular polygon is rotated by the "rotation" value.
+ * - The regular polygon can morph into a circle controlled by the "roundness" value, such that it
+ * becomes a full circle at unit roundness.
+ *
+ * The function returns 0 when the point lies inside the regular polygon and 1 otherwise. However,
+ * at the edges, it returns a narrow band gradient as a form of anti-aliasing. */
+float bokeh(vec2 point, float circumradius)
+{
+ /* Get the index of the vertex of the regular polygon whose polar angle is maximum but less than
+ * the polar angle of the given point, taking rotation into account. This essentially finds the
+ * vertex closest to the given point in the clock-wise direction. */
+ float angle = mod(atan(point.y, point.x) + rotation, M_2PI);
+ int vertex_index = int(angle / exterior_angle);
+
+ /* Compute the shortest distance between the origin and the polygon edge composed from the
+ * previously selected vertex and the one following it. */
+ vec2 first_vertex = get_regular_polygon_vertex_position(vertex_index) * circumradius;
+ vec2 second_vertex = get_regular_polygon_vertex_position(vertex_index + 1) * circumradius;
+ vec2 closest_point = closest_point_on_line(point, first_vertex, second_vertex);
+ float distance_to_edge = length(closest_point);
+
+ /* Mix the distance to the edge with the circumradius, making it tend to the distance to a
+ * circle when roundness tends to 1. */
+ float distance_to_edge_round = mix(distance_to_edge, circumradius, roundness);
+
+ /* The point is outside of the bokeh, so we return 0. */
+ float distance = length(point);
+ if (distance > distance_to_edge_round) {
+ return 0.0;
+ }
+
+ /* The point is inside the catadioptric hole and is not part of the bokeh, so we return 0. */
+ float catadioptric_distance = distance_to_edge_round * catadioptric;
+ if (distance < catadioptric_distance) {
+ return 0.0;
+ }
+
+ /* The point is very close to the edge of the bokeh, so we return the difference between the
+ * distance to the edge and the distance as a form of anti-aliasing. */
+ if (distance_to_edge_round - distance < 1.0) {
+ return distance_to_edge_round - distance;
+ }
+
+ /* The point is very close to the edge of the catadioptric hole, so we return the difference
+ * between the distance to the hole and the distance as a form of anti-aliasing. */
+ if (catadioptric != 0.0 && distance - catadioptric_distance < 1.0) {
+ return distance - catadioptric_distance;
+ }
+
+ /* Otherwise, the point is part of the bokeh and we return 1. */
+ return 1.0;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Since we need the regular polygon to occupy the entirety of the output image, the circumradius
+ * of the regular polygon is half the width of the output image. */
+ float circumradius = float(imageSize(output_img).x) / 2.0;
+
+ /* Move the texel coordinates such that the regular polygon is centered. */
+ vec2 point = vec2(texel) - circumradius;
+
+ /* Each of the color channels of the output image contains a bokeh with a different circumradius.
+ * The largest one occupies the whole image as stated above, while the other two have circumradii
+ * that are shifted by an amount that is proportional to the "lens_shift" value. The alpha
+ * channel of the output is the average of all three values. */
+ float min_shift = abs(lens_shift * circumradius);
+ float min = mix(bokeh(point, circumradius - min_shift), 0.0, min_shift == circumradius);
+
+ float median_shift = min_shift / 2.0;
+ float median = bokeh(point, circumradius - median_shift);
+
+ float max = bokeh(point, circumradius);
+ vec4 bokeh = vec4(min, median, max, (max + median + min) / 3.0);
+
+ /* If the lens shift is negative, swap the min and max bokeh values, which are stored in the red
+ * and blue channels respectively. Note that we take the absolute value of the lens shift above,
+ * so the sign of the lens shift only controls this swap. */
+ if (lens_shift < 0) {
+ bokeh = bokeh.zyxw;
+ }
+
+ imageStore(output_img, texel, bokeh);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl
new file mode 100644
index 00000000000..fad23f28fde
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1));
+ uv -= location;
+ uv.y *= float(domain_size.y) / float(domain_size.x);
+ uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv;
+ bool is_inside = all(lessThan(abs(uv), size));
+
+ float base_mask_value = texture_load(base_mask_tx, texel).x;
+ float value = texture_load(mask_value_tx, texel).x;
+
+#if defined(CMP_NODE_MASKTYPE_ADD)
+ float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_SUBTRACT)
+ float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_MULTIPLY)
+ float output_mask_value = is_inside ? base_mask_value * value : 0.0;
+#elif defined(CMP_NODE_MASKTYPE_NOT)
+ float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value;
+#endif
+
+ imageStore(output_mask_img, texel, vec4(output_mask_value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl
new file mode 100644
index 00000000000..044fb057ca5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl
@@ -0,0 +1,8 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ vec4 value = texture_load(input_tx, texel);
+ imageStore(output_img, texel, CONVERT_EXPRESSION(value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl
new file mode 100644
index 00000000000..e4743d69d17
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl
@@ -0,0 +1,70 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Returns true if the given color is close enough to the given reference color within the
+ * threshold supplied by the user, and returns false otherwise. */
+bool is_close(vec4 reference_color, vec4 color)
+{
+ return all(lessThan(abs(reference_color - color).rgb, vec3(threshold)));
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* A 3x3 weights kernel whose weights are the inverse of the distance to the center of the
+ * kernel. So the center weight is zero, the corners weights are (1 / sqrt(2)), and the rest
+ * of the weights are 1. The total sum of weights is 4 plus quadruple the corner weight. */
+ float corner_weight = 1.0 / sqrt(2.0);
+ float sum_of_weights = 4.0 + corner_weight * 4.0;
+ mat3 weights = mat3(vec3(corner_weight, 1.0, corner_weight),
+ vec3(1.0, 0.0, 1.0),
+ vec3(corner_weight, 1.0, corner_weight));
+
+ vec4 center_color = texture_load(input_tx, texel);
+
+ /* Go over the pixels in the 3x3 window around the center pixel and compute the total sum of
+ * their colors multiplied by their weights. Additionally, for pixels whose colors are not close
+ * enough to the color of the center pixel, accumulate their color as well as their weights. */
+ vec4 sum_of_colors = vec4(0);
+ float accumulated_weight = 0.0;
+ vec4 accumulated_color = vec4(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ float weight = weights[j][i];
+ vec4 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * weight;
+ sum_of_colors += color;
+ if (!is_close(center_color, color)) {
+ accumulated_color += color;
+ accumulated_weight += weight;
+ }
+ }
+ }
+
+ /* If the accumulated weight is zero, that means all pixels in the 3x3 window are similar and no
+ * need to despeckle anything, so write the original center color and return. */
+ if (accumulated_weight == 0.0) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* If the ratio between the accumulated weights and the total sum of weights is not larger than
+ * the user specified neighbor threshold, then the number of pixels in the neighborhood that are
+ * not close enough to the center pixel is low, and no need to despeckle anything, so write the
+ * original center color and return. */
+ if (accumulated_weight / sum_of_weights < neighbor_threshold) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* If the weighted average color of the neighborhood is close enough to the center pixel, then no
+ * need to despeckle anything, so write the original center color and return. */
+ if (is_close(center_color, sum_of_colors / sum_of_weights)) {
+ imageStore(output_img, texel, center_color);
+ return;
+ }
+
+ /* We need to despeckle, so write the mean accumulated color. */
+ float factor = texture_load(factor_tx, texel).x;
+ vec4 mean_color = accumulated_color / accumulated_weight;
+ imageStore(output_img, texel, mix(center_color, mean_color, factor));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl
new file mode 100644
index 00000000000..1805cb5a7f5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl
@@ -0,0 +1,21 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ ivec2 input_size = texture_size(input_tx);
+
+ /* Add 0.5 to evaluate the input sampler at the center of the pixel. */
+ vec2 coordinates = vec2(texel) + vec2(0.5);
+
+ /* For each iteration, accumulate the input at the normalize coordinates, hence the divide by
+ * input size, then transform the coordinates for the next iteration. */
+ vec4 accumulated_color = vec4(0.0);
+ for (int i = 0; i < iterations; i++) {
+ accumulated_color += texture(input_tx, coordinates / input_size);
+ coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy;
+ }
+
+ /* Write the accumulated color divided by the number of iterations. */
+ imageStore(output_img, texel, accumulated_color / iterations);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl
new file mode 100644
index 00000000000..67e27c22602
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the dot product between the 3x3 window around the pixel and the edge detection kernel
+ * in the X direction and Y direction. The Y direction kernel is computed by transposing the
+ * given X direction kernel. */
+ vec3 color_x = vec3(0);
+ vec3 color_y = vec3(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ vec3 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)).rgb;
+ color_x += color * kernel[j][i];
+ color_y += color * kernel[i][j];
+ }
+ }
+
+ /* Compute the channel-wise magnitude of the 2D vector composed from the X and Y edge detection
+ * filter results. */
+ vec3 magnitude = sqrt(color_x * color_x + color_y * color_y);
+
+ /* Mix the channel-wise magnitude with the original color at the center of the kernel using the
+ * input factor. */
+ vec4 color = texture_load(input_tx, texel);
+ magnitude = mix(color.rgb, magnitude, texture_load(factor_tx, texel).x);
+
+ /* Store the channel-wise magnitude with the original alpha of the input. */
+ imageStore(output_img, texel, vec4(magnitude, color.a));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl
new file mode 100644
index 00000000000..28f725067e0
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1));
+ uv -= location;
+ uv.y *= float(domain_size.y) / float(domain_size.x);
+ uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv;
+ bool is_inside = length(uv / radius) < 1.0;
+
+ float base_mask_value = texture_load(base_mask_tx, texel).x;
+ float value = texture_load(mask_value_tx, texel).x;
+
+#if defined(CMP_NODE_MASKTYPE_ADD)
+ float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_SUBTRACT)
+ float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value;
+#elif defined(CMP_NODE_MASKTYPE_MULTIPLY)
+ float output_mask_value = is_inside ? base_mask_value * value : 0.0;
+#elif defined(CMP_NODE_MASKTYPE_NOT)
+ float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value;
+#endif
+
+ imageStore(output_mask_img, texel, vec4(output_mask_value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl
new file mode 100644
index 00000000000..e501c563dda
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl
@@ -0,0 +1,20 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the dot product between the 3x3 window around the pixel and the filter kernel. */
+ vec4 color = vec4(0);
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 3; i++) {
+ color += texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * kernel[j][i];
+ }
+ }
+
+ /* Mix with the original color at the center of the kernel using the input factor. */
+ color = mix(texture_load(input_tx, texel), color, texture_load(factor_tx, texel).x);
+
+ /* Store the color making sure it is not negative. */
+ imageStore(output_img, texel, max(color, 0.0));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl
new file mode 100644
index 00000000000..919c454ee63
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl
@@ -0,0 +1,15 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ ivec2 size = texture_size(input_tx);
+ ivec2 flipped_texel = texel;
+ if (flip_x) {
+ flipped_texel.x = size.x - texel.x - 1;
+ }
+ if (flip_y) {
+ flipped_texel.y = size.y - texel.y - 1;
+ }
+ imageStore(output_img, texel, texture_load(input_tx, flipped_texel));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl
new file mode 100644
index 00000000000..f20e033dee4
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ imageStore(output_img, texel, texture_load(input_tx, texel + lower_bound));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl
new file mode 100644
index 00000000000..09f896b7a9d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl
@@ -0,0 +1,24 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Find the minimum/maximum value in the circular window of the given radius around the pixel. By
+ * circular window, we mean that pixels in the window whose distance to the center of window is
+ * larger than the given radius are skipped and not considered. Consequently, the dilation or
+ * erosion that take place produces round results as opposed to squarish ones. This is
+ * essentially a morphological operator with a circular structuring element. The LIMIT value
+ * should be FLT_MAX if OPERATOR is min and FLT_MIN if OPERATOR is max. */
+ float value = LIMIT;
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ if (x * x + y * y <= radius * radius) {
+ value = OPERATOR(value, texture_load(input_tx, texel + ivec2(x, y), vec4(LIMIT)).x);
+ }
+ }
+ }
+
+ imageStore(output_img, texel, vec4(value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl
new file mode 100644
index 00000000000..acdd8a40342
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl
@@ -0,0 +1,101 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* The Morphological Distance Feather operation is a linear combination between the result of two
+ * operations. The first operation is a Gaussian blur with a radius equivalent to the dilate/erode
+ * distance, which is straightforward and implemented as a separable filter similar to the blur
+ * operation.
+ *
+ * The second operation is an approximation of a morphological inverse distance operation evaluated
+ * at a distance falloff function. The result of a morphological inverse distance operation is a
+ * narrow band distance field that starts at its maximum value at boundaries where a difference in
+ * values took place and linearly deceases until it reaches zero in the span of a number of pixels
+ * equivalent to the erode/dilate distance. Additionally, instead of linearly decreasing, the user
+ * may choose a different falloff which is evaluated at the computed distance. For dilation, the
+ * distance field decreases outwards, and for erosion, the distance field decreased inwards.
+ *
+ * The reason why the result of a Gaussian blur is mixed in with the distance field is because the
+ * distance field is merely approximated and not accurately computed, the defects of which is more
+ * apparent away from boundaries and especially at corners where the distance field should take a
+ * circular shape. That's why the Gaussian blur is mostly mixed only further from boundaries.
+ *
+ * The morphological inverse distance operation is approximated using a separable implementation
+ * and intertwined with the Gaussian blur implementation as follows. A search window of a radius
+ * equivalent to the dilate/erode distance is applied on the image to find either the minimum or
+ * maximum pixel value multiplied by its corresponding falloff value in the window. For dilation,
+ * we try to find the maximum, and for erosion, we try to find the minimum. Additionally, we also
+ * save the falloff value where the minimum or maximum was found. The found value will be that of
+ * the narrow band distance field and the saved falloff value will be used as the mixing factor
+ * with the Gaussian blur.
+ *
+ * To make sense of the aforementioned algorithm, assume we are dilating a binary image by 5 pixels
+ * whose half has a value of 1 and the other half has a value of zero. Consider the following:
+ *
+ * - A pixel of value 1 already has the maximum possible value, so its value will remain unchanged
+ * regardless of its position.
+ * - A pixel of value 0 that is right at the boundary of the 1's region will have a maximum value
+ * of around 0.8 depending on the falloff. That's because the search window intersects the 1's
+ * region, which when multiplied by the falloff gives the first value of the falloff, which is
+ * larger than the initially zero value computed at the center of the search window.
+ * - A pixel of value 0 that is 3 pixels away from the boundary will have a maximum value of around
+ * 0.4 depending on the falloff. That's because the search window intersects the 1's region,
+ * which when multiplied by the falloff gives the third value of the falloff, which is larger
+ * than the initially zero value computed at the center of the search window.
+ * - Finally, a pixel of value 0 that is 6 pixels away from the boundary will have a maximum value
+ * of 0, because the search window doesn't intersects the 1's region and only spans zero values.
+ *
+ * The previous example demonstrates how the distance field naturally arises, and the same goes for
+ * the erode case, except the minimum value is computed instead.
+ */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* A value for accumulating the blur result. */
+ float accumulated_value = 0.0;
+
+ /* Compute the contribution of the center pixel to the blur result. */
+ float center_value = texture_load(input_tx, texel).x;
+ accumulated_value += center_value * texture_load(weights_tx, 0).x;
+
+ /* Start with the center value as the maximum/minimum distance and reassign to the true maximum
+ * or minimum in the search loop below. Additionally, the center falloff is always 1.0, so start
+ * with that. */
+ float limit_distance = center_value;
+ float limit_distance_falloff = 1.0;
+
+ /* Compute the contributions of the pixels to the right and left, noting that the weights and
+ * falloffs textures only store the weights and falloffs for the positive half, but since the
+ * they are both symmetric, the same weights and falloffs are used for the negative half and we
+ * compute both of their contributions. */
+ for (int i = 1; i < texture_size(weights_tx); i++) {
+ float weight = texture_load(weights_tx, i).x;
+ float falloff = texture_load(falloffs_tx, i).x;
+
+ /* Loop for two iterations, where s takes the value of -1 and 1, which is used as the sign
+ * needed to evaluated the positive and negative sides as explain above. */
+ for (int s = -1; s < 2; s += 2) {
+ /* Compute the contribution of the pixel to the blur result. */
+ float value = texture_load(input_tx, texel + ivec2(s * i, 0)).x;
+ accumulated_value += value * weight;
+
+ /* The distance is computed such that its highest value is the pixel value itself, so
+ * multiply the distance falloff by the pixel value. */
+ float falloff_distance = value * falloff;
+
+ /* Find either the maximum or the minimum for the dilate and erode cases respectively. */
+ if (COMPARE(falloff_distance, limit_distance)) {
+ limit_distance = falloff_distance;
+ limit_distance_falloff = falloff;
+ }
+ }
+ }
+
+ /* Mix between the limit distance and the blurred accumulated value such that the limit distance
+ * is used for pixels closer to the boundary and the blurred value is used for pixels away from
+ * the boundary. */
+ float value = mix(accumulated_value, limit_distance, limit_distance_falloff);
+
+ /* Write the value using the transposed texel. See the execute_distance_feather_horizontal_pass
+ * method for more information on the rational behind this. */
+ imageStore(output_img, texel.yx, vec4(value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl
new file mode 100644
index 00000000000..e6625e7419f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl
@@ -0,0 +1,88 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* The Morphological Distance Threshold operation is effectively three consecutive operations
+ * implemented as a single operation. The three operations are as follows:
+ *
+ * .-----------. .--------------. .----------------.
+ * | Threshold |-->| Dilate/Erode |-->| Distance Inset |
+ * '-----------' '--------------' '----------------'
+ *
+ * The threshold operation just converts the input into a binary image, where the pixel is 1 if it
+ * is larger than 0.5 and 0 otherwise. Pixels that are 1 in the output of the threshold operation
+ * are said to be masked. The dilate/erode operation is a dilate or erode morphological operation
+ * with a circular structuring element depending on the sign of the distance, where it is a dilate
+ * operation if the distance is positive and an erode operation otherwise. This is equivalent to
+ * the Morphological Distance operation, see its implementation for more information. Finally, the
+ * distance inset is an operation that converts the binary image into a narrow band distance field.
+ * That is, pixels that are unmasked will remain 0, while pixels that are masked will start from
+ * zero at the boundary of the masked region and linearly increase until reaching 1 in the span of
+ * a number pixels given by the inset value.
+ *
+ * As a performance optimization, the dilate/erode operation is omitted and its effective result is
+ * achieved by slightly adjusting the distance inset operation. The base distance inset operation
+ * works by computing the signed distance from the current center pixel to the nearest pixel with a
+ * different value. Since our image is a binary image, that means that if the pixel is masked, we
+ * compute the signed distance to the nearest unmasked pixel, and if the pixel unmasked, we compute
+ * the signed distance to the nearest masked pixel. The distance is positive if the pixel is masked
+ * and negative otherwise. The distance is then normalized by dividing by the given inset value and
+ * clamped to the [0, 1] range. Since distances larger than the inset value are eventually clamped,
+ * the distance search window is limited to a radius equivalent to the inset value.
+ *
+ * To archive the effective result of the omitted dilate/erode operation, we adjust the distance
+ * inset operation as follows. First, we increase the radius of the distance search window by the
+ * radius of the dilate/erode operation. Then we adjust the resulting narrow band signed distance
+ * field as follows.
+ *
+ * For the erode case, we merely subtract the erode distance, which makes the outermost erode
+ * distance number of pixels zero due to clamping, consequently achieving the result of the erode,
+ * while retaining the needed inset because we increased the distance search window by the same
+ * amount we subtracted.
+ *
+ * Similarly, for the dilate case, we add the dilate distance, which makes the dilate distance
+ * number of pixels just outside of the masked region positive and part of the narrow band distance
+ * field, consequently achieving the result of the dilate, while at the same time, the innermost
+ * dilate distance number of pixels become 1 due to clamping, retaining the needed inset because we
+ * increased the distance search window by the same amount we added.
+ *
+ * Since the erode/dilate distance is already signed appropriately as described before, we just add
+ * it in both cases. */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Apply a threshold operation on the center pixel, where the threshold is currently hard-coded
+ * at 0.5. The pixels with values larger than the threshold are said to be masked. */
+ bool is_center_masked = texture_load(input_tx, texel).x > 0.5;
+
+ /* Since the distance search window will access pixels outside of the bounds of the image, we use
+ * a texture loader with a fallback value. And since we don't want those values to affect the
+ * result, the fallback value is chosen such that the inner condition fails, which is when the
+ * sampled pixel and the center pixel are the same, so choose a fallback that will be considered
+ * masked if the center pixel is masked and unmasked otherwise. */
+ vec4 fallback = vec4(is_center_masked ? 1.0 : 0.0);
+
+ /* Since the distance search window is limited to the given radius, the maximum possible squared
+ * distance to the center is double the squared radius. */
+ int minimum_squared_distance = radius * radius * 2;
+
+ /* Find the squared distance to the nearest different pixel in the search window of the given
+ * radius. */
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ bool is_sample_masked = texture_load(input_tx, texel + ivec2(x, y), fallback).x > 0.5;
+ if (is_center_masked != is_sample_masked) {
+ minimum_squared_distance = min(minimum_squared_distance, x * x + y * y);
+ }
+ }
+ }
+
+ /* Compute the actual distance from the squared distance and assign it an appropriate sign
+ * depending on whether it lies in a masked region or not. */
+ float signed_minimum_distance = sqrt(minimum_squared_distance) * (is_center_masked ? 1.0 : -1.0);
+
+ /* Add the erode/dilate distance and divide by the inset amount as described in the discussion,
+ * then clamp to the [0, 1] range. */
+ float value = clamp((signed_minimum_distance + distance) / inset, 0.0, 1.0);
+
+ imageStore(output_img, texel, vec4(value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl
new file mode 100644
index 00000000000..6992bc2afa5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl
@@ -0,0 +1,19 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Find the minimum/maximum value in the window of the given radius around the pixel. This is
+ * essentially a morphological operator with a square structuring element. The LIMIT value should
+ * be FLT_MAX if OPERATOR is min and FLT_MIN if OPERATOR is max. */
+ float value = LIMIT;
+ for (int i = -radius; i <= radius; i++) {
+ value = OPERATOR(value, texture_load(input_tx, texel + ivec2(i, 0), vec4(LIMIT)).x);
+ }
+
+ /* Write the value using the transposed texel. See the execute_step_horizontal_pass method for
+ * more information on the rational behind this. */
+ imageStore(output_img, texel.yx, vec4(value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl
new file mode 100644
index 00000000000..53dfeb01730
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl
@@ -0,0 +1,10 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ float value = texture_load(input_tx, texel).x;
+ float normalized_value = (value - minimum) * scale;
+ float clamped_value = clamp(normalized_value, 0.0, 1.0);
+ imageStore(output_img, texel, vec4(clamped_value));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl
new file mode 100644
index 00000000000..f6f84aa24c1
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl
@@ -0,0 +1,98 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* This shader reduces the given texture into a smaller texture of a size equal to the number of
+ * work groups. In particular, each work group reduces its contents into a single value and writes
+ * that value to a single pixel in the output image. The shader can be dispatched multiple times to
+ * eventually reduce the image into a single pixel.
+ *
+ * The shader works by loading the whole data of each work group into a linear array, then it
+ * reduces the second half of the array onto the first half of the array, then it reduces the
+ * second quarter of the array onto the first quarter or the array, and so on until only one
+ * element remains. The following figure illustrates the process for sum reduction on 8 elements.
+ *
+ * .---. .---. .---. .---. .---. .---. .---. .---.
+ * | 0 | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | Original data.
+ * '---' '---' '---' '---' '---' '---' '---' '---'
+ * |.____|_____|_____|_____| | | |
+ * || |.____|_____|___________| | |
+ * || || |.____|_________________| |
+ * || || || |.______________________| <--First reduction. Stride = 4.
+ * || || || ||
+ * .---. .---. .---. .----.
+ * | 4 | | 6 | | 8 | | 10 | <--Data after first reduction.
+ * '---' '---' '---' '----'
+ * |.____|_____| |
+ * || |.__________| <--Second reduction. Stride = 2.
+ * || ||
+ * .----. .----.
+ * | 12 | | 16 | <--Data after second reduction.
+ * '----' '----'
+ * |.____|
+ * || <--Third reduction. Stride = 1.
+ * .----.
+ * | 28 |
+ * '----' <--Data after third reduction.
+ *
+ *
+ * The shader is generic enough to implement many types of reductions. This is done by using macros
+ * that the developer should define to implement a certain reduction operation. Those include,
+ * TYPE, IDENTITY, INITIALIZE, LOAD, and REDUCE. See the implementation below for more information
+ * as well as the compositor_parallel_reduction_info.hh for example reductions operations. */
+
+/* Doing the reduction in shared memory is faster, so create a shared array where the whole data
+ * of the work group will be loaded and reduced. The 2D structure of the work group is irrelevant
+ * for reduction, so we just load the data in a 1D array to simplify reduction. The developer is
+ * expected to define the TYPE macro to be a float or a vec4, depending on the type of data being
+ * reduced. */
+const uint reduction_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y;
+shared TYPE reduction_data[reduction_size];
+
+void main()
+{
+ /* Load the data from the texture, while returning IDENTITY for out of bound coordinates. The
+ * developer is expected to define the IDENTITY macro to be a vec4 that does not affect the
+ * output of the reduction. For instance, sum reductions have an identity of vec4(0.0), while
+ * max value reductions have an identity of vec4(FLT_MIN). */
+ vec4 value = texture_load(input_tx, ivec2(gl_GlobalInvocationID.xy), IDENTITY);
+
+ /* Initialize the shared array given the previously loaded value. This step can be different
+ * depending on whether this is the initial reduction pass or a latter one. Indeed, the input
+ * texture for the initial reduction is the source texture itself, while the input texture to a
+ * latter reduction pass is an intermediate texture after one or more reductions have happened.
+ * This is significant because the data being reduced might be computed from the original data
+ * and different from it, for instance, when summing the luminance of an image, the original data
+ * is a vec4 color, while the reduced data is a float luminance value. So for the initial
+ * reduction pass, the luminance will be computed from the color, reduced, then stored into an
+ * intermediate float texture. On the other hand, for latter reduction passes, the luminance will
+ * be loaded directly and reduced without extra processing. So the developer is expected to
+ * define the INITIALIZE and LOAD macros to be expressions that derive the needed value from the
+ * loaded value for the initial reduction pass and latter ones respectively. */
+ reduction_data[gl_LocalInvocationIndex] = is_initial_reduction ? INITIALIZE(value) : LOAD(value);
+
+ /* Reduce the reduction data by half on every iteration until only one element remains. See the
+ * above figure for an intuitive understanding of the stride value. */
+ for (uint stride = reduction_size / 2; stride > 0; stride /= 2) {
+ barrier();
+
+ /* Only the threads up to the current stride should be active as can be seen in the diagram
+ * above. */
+ if (gl_LocalInvocationIndex >= stride) {
+ continue;
+ }
+
+ /* Reduce each two elements that are stride apart, writing the result to the element with the
+ * lower index, as can be seen in the diagram above. The developer is expected to define the
+ * REDUCE macro to be a commutative and associative binary operator suitable for parallel
+ * reduction. */
+ reduction_data[gl_LocalInvocationIndex] = REDUCE(
+ reduction_data[gl_LocalInvocationIndex], reduction_data[gl_LocalInvocationIndex + stride]);
+ }
+
+ /* Finally, the result of the reduction is available as the first element in the reduction data,
+ * write it to the pixel corresponding to the work group, making sure only the one thread writes
+ * it. */
+ barrier();
+ if (gl_LocalInvocationIndex == 0) {
+ imageStore(output_img, ivec2(gl_WorkGroupID.xy), vec4(reduction_data[0]));
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl
new file mode 100644
index 00000000000..ab44dac93e6
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Get the normalized coordinates of the pixel centers. */
+ vec2 normalized_texel = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
+
+ /* Sample the red and blue channels shifted by the dispersion amount. */
+ const float red = texture(input_tx, normalized_texel + vec2(dispersion, 0.0)).r;
+ const float green = texture_load(input_tx, texel).g;
+ const float blue = texture(input_tx, normalized_texel - vec2(dispersion, 0.0)).b;
+
+ imageStore(output_img, texel, vec4(red, green, blue, 1.0));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl
new file mode 100644
index 00000000000..b8561e5f059
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl
@@ -0,0 +1,29 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Add 0.5 to evaluate the input sampler at the center of the pixel. */
+ vec2 coordinates = vec2(texel) + vec2(0.5);
+
+ /* Transform the input image by transforming the domain coordinates with the inverse of input
+ * image's transformation. The inverse transformation is an affine matrix and thus the
+ * coordinates should be in homogeneous coordinates. */
+ coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy;
+
+ /* Since an input image with an identity transformation is supposed to be centered in the domain,
+ * we subtract the offset between the lower left corners of the input image and the domain, which
+ * is half the difference between their sizes, because the difference in size is on both sides of
+ * the centered image. Additionally, we floor the offset to retain the 0.5 offset added above in
+ * case the difference in sizes was odd. */
+ ivec2 domain_size = imageSize(domain_img);
+ ivec2 input_size = texture_size(input_tx);
+ vec2 offset = floor((domain_size - input_size) / 2.0);
+
+ /* Subtract the offset and divide by the input image size to get the relevant coordinates into
+ * the sampler's expected [0, 1] range. */
+ vec2 normalized_coordinates = (coordinates - offset) / input_size;
+
+ imageStore(domain_img, texel, texture(input_tx, normalized_coordinates));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl
new file mode 100644
index 00000000000..dc572ea5aaf
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl
@@ -0,0 +1,151 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_hash.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* A model that approximates lens distortion parameterized by a distortion parameter and dependent
+ * on the squared distance to the center of the image. The distorted pixel is then computed as the
+ * scalar multiplication of the pixel coordinates with the value returned by this model. See the
+ * compute_distorted_uv function for more details. */
+float compute_distortion_scale(float distortion, float distance_squared)
+{
+ return 1.0 / (1.0 + sqrt(max(0.0, 1.0 - distortion * distance_squared)));
+}
+
+/* A vectorized version of compute_distortion_scale that is applied on the chromatic distortion
+ * parameters passed to the shader. */
+vec3 compute_chromatic_distortion_scale(float distance_squared)
+{
+ return 1.0 / (1.0 + sqrt(max(vec3(0.0), 1.0 - chromatic_distortion * distance_squared)));
+}
+
+/* Compute the image coordinates after distortion by the given distortion scale computed by the
+ * compute_distortion_scale function. Note that the function expects centered normalized UV
+ * coordinates but outputs non-centered image coordinates. */
+vec2 compute_distorted_uv(vec2 uv, float scale)
+{
+ return (uv * scale + 0.5) * texture_size(input_tx) - 0.5;
+}
+
+/* Compute the number of integration steps that should be used to approximate the distorted pixel
+ * using a heuristic, see the compute_number_of_steps function for more details. The numbers of
+ * steps is proportional to the number of pixels spanned by the distortion amount. For jitter
+ * distortion, the square root of the distortion amount plus 1 is used with a minimum of 2 steps.
+ * For non-jitter distortion, the distortion amount plus 1 is used as the number of steps */
+int compute_number_of_integration_steps_heuristic(float distortion)
+{
+#if defined(JITTER)
+ return distortion < 4.0 ? 2 : int(sqrt(distortion + 1.0));
+#else
+ return int(distortion + 1.0);
+#endif
+}
+
+/* Compute the number of integration steps that should be used to compute each channel of the
+ * distorted pixel. Each of the channels are distorted by their respective chromatic distortion
+ * amount, then the amount of distortion between each two consecutive channels is computed, this
+ * amount is then used to heuristically infer the number of needed integration steps, see the
+ * integrate_distortion function for more information. */
+ivec3 compute_number_of_integration_steps(vec2 uv, float distance_squared)
+{
+ /* Distort each channel by its respective chromatic distortion amount. */
+ vec3 distortion_scale = compute_chromatic_distortion_scale(distance_squared);
+ vec2 distorted_uv_red = compute_distorted_uv(uv, distortion_scale.r);
+ vec2 distorted_uv_green = compute_distorted_uv(uv, distortion_scale.g);
+ vec2 distorted_uv_blue = compute_distorted_uv(uv, distortion_scale.b);
+
+ /* Infer the number of needed integration steps to compute the distorted red channel starting
+ * from the green channel. */
+ float distortion_red = distance(distorted_uv_red, distorted_uv_green);
+ int steps_red = compute_number_of_integration_steps_heuristic(distortion_red);
+
+ /* Infer the number of needed integration steps to compute the distorted blue channel starting
+ * from the green channel. */
+ float distortion_blue = distance(distorted_uv_green, distorted_uv_blue);
+ int steps_blue = compute_number_of_integration_steps_heuristic(distortion_blue);
+
+ /* The number of integration steps used to compute the green channel is the sum of both the red
+ * and the blue channel steps because it is computed once with each of them. */
+ return ivec3(steps_red, steps_red + steps_blue, steps_blue);
+}
+
+/* Returns a random jitter amount, which is essentially a random value in the [0, 1] range. If
+ * jitter is not enabled, return a constant 0.5 value instead. */
+float get_jitter(int seed)
+{
+#if defined(JITTER)
+ return hash_uint3_to_float(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, seed);
+#else
+ return 0.5;
+#endif
+}
+
+/* Each color channel may have a different distortion with the guarantee that the red will have the
+ * lowest distortion while the blue will have the highest one. If each channel is distorted
+ * independently, the image will look disintegrated, with each channel seemingly merely shifted.
+ * Consequently, the distorted pixels needs to be computed by integrating along the path of change
+ * of distortion starting from one channel to another. For instance, to compute the distorted red
+ * from the distorted green, we accumulate the color of the distorted pixel starting from the
+ * distortion of the red, taking small steps until we reach the distortion of the green. The pixel
+ * color is weighted such that it is maximum at the start distortion and zero at the end distortion
+ * in an arithmetic progression. The integration steps can be augmented with random values to
+ * simulate lens jitter. Finally, it should be noted that this function integrates both the start
+ * and end channels in reverse directions for more efficient computation. */
+vec3 integrate_distortion(int start, int end, float distance_squared, vec2 uv, int steps)
+{
+ vec3 accumulated_color = vec3(0.0);
+ float distortion_amount = chromatic_distortion[end] - chromatic_distortion[start];
+ for (int i = 0; i < steps; i++) {
+ /* The increment will be in the [0, 1) range across iterations. */
+ float increment = (i + get_jitter(i)) / steps;
+ float distortion = chromatic_distortion[start] + increment * distortion_amount;
+ float distortion_scale = compute_distortion_scale(distortion, distance_squared);
+
+ /* Sample the color at the distorted coordinates and accumulate it weighted by the increment
+ * value for both the start and end channels. */
+ vec2 distorted_uv = compute_distorted_uv(uv, distortion_scale);
+ vec4 color = texture(input_tx, distorted_uv / texture_size(input_tx));
+ accumulated_color[start] += (1.0 - increment) * color[start];
+ accumulated_color[end] += increment * color[end];
+ }
+ return accumulated_color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ /* Compute the UV image coordinates in the range [-1, 1] as well as the squared distance to the
+ * center of the image, which is at (0, 0) in the UV coordinates. */
+ vec2 center = texture_size(input_tx) / 2.0;
+ vec2 uv = scale * (texel + 0.5 - center) / center;
+ float distance_squared = dot(uv, uv);
+
+ /* If any of the color channels will get distorted outside of the screen beyond what is possible,
+ * write a zero transparent color and return. */
+ if (any(greaterThan(chromatic_distortion * distance_squared, vec3(1.0)))) {
+ imageStore(output_img, texel, vec4(0.0));
+ return;
+ }
+
+ /* Compute the number of integration steps that should be used to compute each channel of the
+ * distorted pixel. */
+ ivec3 number_of_steps = compute_number_of_integration_steps(uv, distance_squared);
+
+ /* Integrate the distortion of the red and green, then the green and blue channels. That means
+ * the green will be integrated twice, but this is accounted for in the number of steps which the
+ * color will later be divided by. See the compute_number_of_integration_steps function for more
+ * details. */
+ vec3 color = vec3(0.0);
+ color += integrate_distortion(0, 1, distance_squared, uv, number_of_steps.r);
+ color += integrate_distortion(1, 2, distance_squared, uv, number_of_steps.b);
+
+ /* The integration above performed weighted accumulation, and thus the color needs to be divided
+ * by the sum of the weights. Assuming no jitter, the weights are generated as an arithmetic
+ * progression starting from (0.5 / n) to ((n - 0.5) / n) for n terms. The sum of an arithmetic
+ * progression can be computed as (n * (start + end) / 2), which when subsisting the start and
+ * end reduces to (n / 2). So the color should be multiplied by 2 / n. The jitter sequence
+ * approximately sums to the same value because it is a uniform random value whose mean value is
+ * 0.5, so the expression doesn't change regardless of jitter. */
+ color *= 2.0 / vec3(number_of_steps);
+
+ imageStore(output_img, texel, vec4(color, 1.0));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl
new file mode 100644
index 00000000000..7dd40581790
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl
@@ -0,0 +1,8 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+ vec4 color = vec4(texture_load(image_tx, texel).rgb, texture_load(alpha_tx, texel).x);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl
new file mode 100644
index 00000000000..866b9045da2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+#if defined(SPLIT_HORIZONTAL)
+ bool condition = (view_size.x * split_ratio) < texel.x;
+#elif defined(SPLIT_VERTICAL)
+ bool condition = (view_size.y * split_ratio) < texel.y;
+#endif
+ vec4 color = condition ? texture_load(first_image_tx, texel) :
+ texture_load(second_image_tx, texel);
+ imageStore(output_img, texel, color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl
new file mode 100644
index 00000000000..df08991a35c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl
@@ -0,0 +1,77 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+vec4 load_input(ivec2 texel)
+{
+ vec4 color;
+ if (extend_bounds) {
+ /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So
+ * we load the input with an offset by the radius amount and fallback to a transparent color if
+ * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra
+ * center weight, see the SymmetricBlurWeights for more information. */
+ ivec2 blur_size = texture_size(weights_tx) - 1;
+ color = texture_load(input_tx, texel - blur_size, vec4(0.0));
+ }
+ else {
+ color = texture_load(input_tx, texel);
+ }
+
+ if (gamma_correct) {
+ color = gamma_correct_blur_input(color);
+ }
+
+ return color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 accumulated_color = vec4(0.0);
+
+ /* First, compute the contribution of the center pixel. */
+ vec4 center_color = load_input(texel);
+ accumulated_color += center_color * texture_load(weights_tx, ivec2(0)).x;
+
+ ivec2 weights_size = texture_size(weights_tx);
+
+ /* Then, compute the contributions of the pixels along the x axis of the filter, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int x = 1; x < weights_size.x; x++) {
+ float weight = texture_load(weights_tx, ivec2(x, 0)).x;
+ accumulated_color += load_input(texel + ivec2(x, 0)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, 0)) * weight;
+ }
+
+ /* Then, compute the contributions of the pixels along the y axis of the filter, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int y = 1; y < weights_size.y; y++) {
+ float weight = texture_load(weights_tx, ivec2(0, y)).x;
+ accumulated_color += load_input(texel + ivec2(0, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(0, -y)) * weight;
+ }
+
+ /* Finally, compute the contributions of the pixels in the four quadrants of the filter, noting
+ * that the weights texture only stores the weights for the upper right quadrant, but since the
+ * filter is symmetric, the same weight is used for the rest of the quadrants and we add all four
+ * of their contributions. */
+ for (int y = 1; y < weights_size.y; y++) {
+ for (int x = 1; x < weights_size.x; x++) {
+ float weight = texture_load(weights_tx, ivec2(x, y)).x;
+ accumulated_color += load_input(texel + ivec2(x, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(x, -y)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, -y)) * weight;
+ }
+ }
+
+ if (gamma_correct) {
+ accumulated_color = gamma_uncorrect_blur_output(accumulated_color);
+ }
+
+ imageStore(output_img, texel, accumulated_color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl
new file mode 100644
index 00000000000..ab0c7baa787
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl
@@ -0,0 +1,53 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+vec4 load_input(ivec2 texel)
+{
+ vec4 color;
+ if (extend_bounds) {
+ /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So
+ * we load the input with an offset by the radius amount and fallback to a transparent color if
+ * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra
+ * center weight, see the SymmetricSeparableBlurWeights for more information. */
+ int blur_size = texture_size(weights_tx) - 1;
+ color = texture_load(input_tx, texel - ivec2(blur_size, 0), vec4(0.0));
+ }
+ else {
+ color = texture_load(input_tx, texel);
+ }
+
+ if (gamma_correct_input) {
+ color = gamma_correct_blur_input(color);
+ }
+
+ return color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 accumulated_color = vec4(0.0);
+
+ /* First, compute the contribution of the center pixel. */
+ vec4 center_color = load_input(texel);
+ accumulated_color += center_color * texture_load(weights_tx, 0).x;
+
+ /* Then, compute the contributions of the pixel to the right and left, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int i = 1; i < texture_size(weights_tx); i++) {
+ float weight = texture_load(weights_tx, i).x;
+ accumulated_color += load_input(texel + ivec2(i, 0)) * weight;
+ accumulated_color += load_input(texel + ivec2(-i, 0)) * weight;
+ }
+
+ if (gamma_uncorrect_output) {
+ accumulated_color = gamma_uncorrect_blur_output(accumulated_color);
+ }
+
+ /* Write the color using the transposed texel. See the execute_separable_blur_horizontal_pass
+ * method for more information on the rational behind this. */
+ imageStore(output_img, texel.yx, accumulated_color);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl
new file mode 100644
index 00000000000..167006585ca
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl
@@ -0,0 +1,22 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* Tone mapping based on equation (1) and the trilinear interpolation between equations (6) and (7)
+ * from Reinhard, Erik, and Kate Devlin. "Dynamic range reduction inspired by photoreceptor
+ * physiology." IEEE transactions on visualization and computer graphics 11.1 (2005): 13-24. */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 input_color = texture_load(input_tx, texel);
+ float input_luminance = dot(input_color.rgb, luminance_coefficients);
+
+ /* Trilinear interpolation between equations (6) and (7) from Reinhard's 2005 paper. */
+ vec4 local_adaptation_level = mix(vec4(input_luminance), input_color, chromatic_adaptation);
+ vec4 adaptation_level = mix(global_adaptation_level, local_adaptation_level, light_adaptation);
+
+ /* Equation (1) from Reinhard's 2005 paper, assuming Vmax is 1. */
+ vec4 semi_saturation = pow(intensity * adaptation_level, vec4(contrast));
+ vec4 tone_mapped_color = input_color / (input_color + semi_saturation);
+
+ imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl
new file mode 100644
index 00000000000..ce42d021dd1
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl
@@ -0,0 +1,26 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+
+/* Tone mapping based on equation (3) from Reinhard, Erik, et al. "Photographic tone reproduction
+ * for digital images." Proceedings of the 29th annual conference on Computer graphics and
+ * interactive techniques. 2002. */
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 input_color = texture_load(input_tx, texel);
+
+ /* Equation (2) from Reinhard's 2002 paper. */
+ vec4 scaled_color = input_color * luminance_scale;
+
+ /* Equation (3) from Reinhard's 2002 paper, but with the 1 replaced with the blend factor for
+ * more flexibility. See ToneMapOperation::compute_luminance_scale_blend_factor. */
+ vec4 denominator = luminance_scale_blend_factor + scaled_color;
+ vec4 tone_mapped_color = safe_divide(scaled_color, denominator);
+
+ if (inverse_gamma != 0.0) {
+ tone_mapped_color = pow(max(tone_mapped_color, vec4(0.0)), vec4(inverse_gamma));
+ }
+
+ imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a));
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh
new file mode 100644
index 00000000000..11f2f329cd8
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_alpha_crop)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "lower_bound")
+ .push_constant(Type::IVEC2, "upper_bound")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_alpha_crop.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh
new file mode 100644
index 00000000000..301cd6acd9e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_bilateral_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .push_constant(Type::FLOAT, "threshold")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "determinator_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_bilateral_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh
new file mode 100644
index 00000000000..36b772aa486
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .push_constant(Type::BOOL, "extend_bounds")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "weights_tx")
+ .sampler(2, ImageType::FLOAT_2D, "mask_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh
new file mode 100644
index 00000000000..05b6385fd1e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_blur_variable_size)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "base_size")
+ .push_constant(Type::INT, "search_radius")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "weights_tx")
+ .sampler(2, ImageType::FLOAT_2D, "size_tx")
+ .sampler(3, ImageType::FLOAT_2D, "mask_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_blur_variable_size.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh
new file mode 100644
index 00000000000..3541de53070
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_bokeh_image)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "exterior_angle")
+ .push_constant(Type::FLOAT, "rotation")
+ .push_constant(Type::FLOAT, "roundness")
+ .push_constant(Type::FLOAT, "catadioptric")
+ .push_constant(Type::FLOAT, "lens_shift")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_bokeh_image.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh
new file mode 100644
index 00000000000..ecb253bbab1
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "domain_size")
+ .push_constant(Type::VEC2, "location")
+ .push_constant(Type::VEC2, "size")
+ .push_constant(Type::FLOAT, "cos_angle")
+ .push_constant(Type::FLOAT, "sin_angle")
+ .sampler(0, ImageType::FLOAT_2D, "base_mask_tx")
+ .sampler(1, ImageType::FLOAT_2D, "mask_value_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img")
+ .compute_source("compositor_box_mask.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_add)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_ADD")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_subtract)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_SUBTRACT")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_multiply)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_MULTIPLY")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_box_mask_not)
+ .additional_info("compositor_box_mask_shared")
+ .define("CMP_NODE_MASKTYPE_NOT")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh
new file mode 100644
index 00000000000..35e60056736
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_convert_shared)
+ .local_group_size(16, 16)
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .typedef_source("gpu_shader_compositor_type_conversion.glsl")
+ .compute_source("compositor_convert.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_vector)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_float(value.x), 0.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4_from_float(value.x)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec4(value), vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_vector)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_vec4(value), 0.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec3(value.xyz), vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4_from_vec3(value.xyz)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_extract_alpha_from_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.a, vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_half_color)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "value")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_float_to_half_float)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.r, vec3(0.0))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_convert_color_to_opaque)
+ .additional_info("compositor_convert_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("CONVERT_EXPRESSION(value)", "vec4(value.rgb, 1.0)")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh
new file mode 100644
index 00000000000..df86c3a8258
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_despeckle)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "threshold")
+ .push_constant(Type::FLOAT, "neighbor_threshold")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_despeckle.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh
new file mode 100644
index 00000000000..bb9199dcd26
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_directional_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "iterations")
+ .push_constant(Type::MAT4, "inverse_transformation")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_directional_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh
new file mode 100644
index 00000000000..916ec62bdba
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_edge_filter)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "kernel")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_edge_filter.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh
new file mode 100644
index 00000000000..52db91c94e5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "domain_size")
+ .push_constant(Type::VEC2, "location")
+ .push_constant(Type::VEC2, "radius")
+ .push_constant(Type::FLOAT, "cos_angle")
+ .push_constant(Type::FLOAT, "sin_angle")
+ .sampler(0, ImageType::FLOAT_2D, "base_mask_tx")
+ .sampler(1, ImageType::FLOAT_2D, "mask_value_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img")
+ .compute_source("compositor_ellipse_mask.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_add)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_ADD")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_subtract)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_SUBTRACT")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_multiply)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_MULTIPLY")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_not)
+ .additional_info("compositor_ellipse_mask_shared")
+ .define("CMP_NODE_MASKTYPE_NOT")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh
new file mode 100644
index 00000000000..9d565cf4b8a
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_filter)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "kernel")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "factor_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_filter.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh
new file mode 100644
index 00000000000..db831518cb7
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_flip)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "flip_x")
+ .push_constant(Type::BOOL, "flip_y")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_flip.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh
new file mode 100644
index 00000000000..e7736744c40
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_image_crop)
+ .local_group_size(16, 16)
+ .push_constant(Type::IVEC2, "lower_bound")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_image_crop.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh
new file mode 100644
index 00000000000..9f17f60129d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_shared)
+ .local_group_size(16, 16)
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_1D, "weights_tx")
+ .sampler(2, ImageType::FLOAT_1D, "falloffs_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_morphological_distance_feather.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_dilate)
+ .additional_info("compositor_morphological_distance_feather_shared")
+ .define("COMPARE(x, y)", "x > y")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_erode)
+ .additional_info("compositor_morphological_distance_feather_shared")
+ .define("COMPARE(x, y)", "x < y")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh
new file mode 100644
index 00000000000..fc960e119e5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_morphological_distance.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_dilate)
+ .additional_info("compositor_morphological_distance_shared")
+ .define("OPERATOR(a, b)", "max(a, b)")
+ .define("LIMIT", "FLT_MIN")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_erode)
+ .additional_info("compositor_morphological_distance_shared")
+ .define("OPERATOR(a, b)", "min(a, b)")
+ .define("LIMIT", "FLT_MAX")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh
new file mode 100644
index 00000000000..b1d64f61b80
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_distance_threshold)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .push_constant(Type::INT, "distance")
+ .push_constant(Type::FLOAT, "inset")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_morphological_distance_threshold.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh
new file mode 100644
index 00000000000..e97ffd9feea
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_step_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::INT, "radius")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_morphological_step.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_step_dilate)
+ .additional_info("compositor_morphological_step_shared")
+ .define("OPERATOR(a, b)", "max(a, b)")
+ .define("LIMIT", "FLT_MIN")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_morphological_step_erode)
+ .additional_info("compositor_morphological_step_shared")
+ .define("OPERATOR(a, b)", "min(a, b)")
+ .define("LIMIT", "FLT_MAX")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh
new file mode 100644
index 00000000000..02fdc424014
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_normalize)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "minimum")
+ .push_constant(Type::FLOAT, "scale")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_normalize.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh
new file mode 100644
index 00000000000..e2252b14758
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_parallel_reduction_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "is_initial_reduction")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .compute_source("compositor_parallel_reduction.glsl");
+
+/* --------------------------------------------------------------------
+ * Sum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_sum_shared)
+ .additional_info("compositor_parallel_reduction_shared")
+ .define("IDENTITY", "vec4(0.0)")
+ .define("REDUCE(lhs, rhs)", "lhs + rhs");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_float_shared)
+ .additional_info("compositor_sum_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("TYPE", "float")
+ .define("LOAD(value)", "value.x");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_red)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.r")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_green)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.g")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_blue)
+ .additional_info("compositor_sum_float_shared")
+ .define("INITIALIZE(value)", "value.b")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_luminance)
+ .additional_info("compositor_sum_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_log_luminance)
+ .additional_info("compositor_sum_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "log(max(dot(value.rgb, luminance_coefficients), 1e-5))")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_color)
+ .additional_info("compositor_sum_shared")
+ .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .define("TYPE", "vec4")
+ .define("INITIALIZE(value)", "value")
+ .define("LOAD(value)", "value")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Sum Of Squared Difference Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_sum_squared_difference_float_shared)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "subtrahend")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(subtrahend)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "lhs + rhs");
+
+GPU_SHADER_CREATE_INFO(compositor_sum_red_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.r - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_green_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.g - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_blue_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .define("INITIALIZE(value)", "pow(value.b - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_sum_luminance_squared_difference)
+ .additional_info("compositor_sum_squared_difference_float_shared")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("INITIALIZE(value)", "pow(dot(value.rgb, luminance_coefficients) - subtrahend, 2.0)")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Maximum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_maximum_luminance)
+ .additional_info("compositor_parallel_reduction_shared")
+ .typedef_source("common_math_lib.glsl")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(FLT_MIN)")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "max(lhs, rhs)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_maximum_float_in_range)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "lower_bound")
+ .push_constant(Type::FLOAT, "upper_bound")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(lower_bound)")
+ .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : lower_bound")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "((rhs > lhs) && (rhs <= upper_bound)) ? rhs : lhs")
+ .do_static_compilation(true);
+
+/* --------------------------------------------------------------------
+ * Minimum Reductions.
+ */
+
+GPU_SHADER_CREATE_INFO(compositor_minimum_luminance)
+ .additional_info("compositor_parallel_reduction_shared")
+ .typedef_source("common_math_lib.glsl")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(FLT_MAX)")
+ .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "min(lhs, rhs)")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_minimum_float_in_range)
+ .additional_info("compositor_parallel_reduction_shared")
+ .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .push_constant(Type::FLOAT, "lower_bound")
+ .push_constant(Type::FLOAT, "upper_bound")
+ .define("TYPE", "float")
+ .define("IDENTITY", "vec4(upper_bound)")
+ .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : upper_bound")
+ .define("LOAD(value)", "value.x")
+ .define("REDUCE(lhs, rhs)", "((rhs < lhs) && (rhs >= lower_bound)) ? rhs : lhs")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh
new file mode 100644
index 00000000000..98fe1731703
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_projector_lens_distortion)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "dispersion")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_projector_lens_distortion.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh
new file mode 100644
index 00000000000..4528649ae98
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::MAT4, "inverse_transformation")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .compute_source("compositor_realize_on_domain.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_color)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_vector)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_float)
+ .additional_info("compositor_realize_on_domain_shared")
+ .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh
new file mode 100644
index 00000000000..c42f2b328d4
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::VEC3, "chromatic_distortion")
+ .push_constant(Type::FLOAT, "scale")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_screen_lens_distortion.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion)
+ .additional_info("compositor_screen_lens_distortion_shared")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_jitter)
+ .additional_info("compositor_screen_lens_distortion_shared")
+ .define("JITTER")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh
new file mode 100644
index 00000000000..ca28194e921
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_set_alpha)
+ .local_group_size(16, 16)
+ .sampler(0, ImageType::FLOAT_2D, "image_tx")
+ .sampler(1, ImageType::FLOAT_2D, "alpha_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_set_alpha.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh
new file mode 100644
index 00000000000..d5793b0ce59
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_shared)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "split_ratio")
+ .push_constant(Type::IVEC2, "view_size")
+ .sampler(0, ImageType::FLOAT_2D, "first_image_tx")
+ .sampler(1, ImageType::FLOAT_2D, "second_image_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_split_viewer.glsl");
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_horizontal)
+ .additional_info("compositor_split_viewer_shared")
+ .define("SPLIT_HORIZONTAL")
+ .do_static_compilation(true);
+
+GPU_SHADER_CREATE_INFO(compositor_split_viewer_vertical)
+ .additional_info("compositor_split_viewer_shared")
+ .define("SPLIT_VERTICAL")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh
new file mode 100644
index 00000000000..8ba2b4e04ef
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_symmetric_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "extend_bounds")
+ .push_constant(Type::BOOL, "gamma_correct")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "weights_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_symmetric_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh
new file mode 100644
index 00000000000..57247dba4b8
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "extend_bounds")
+ .push_constant(Type::BOOL, "gamma_correct_input")
+ .push_constant(Type::BOOL, "gamma_uncorrect_output")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_1D, "weights_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_symmetric_separable_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh
new file mode 100644
index 00000000000..a460c9d58a6
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_tone_map_photoreceptor)
+ .local_group_size(16, 16)
+ .push_constant(Type::VEC4, "global_adaptation_level")
+ .push_constant(Type::FLOAT, "contrast")
+ .push_constant(Type::FLOAT, "intensity")
+ .push_constant(Type::FLOAT, "chromatic_adaptation")
+ .push_constant(Type::FLOAT, "light_adaptation")
+ .push_constant(Type::VEC3, "luminance_coefficients")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_tone_map_photoreceptor.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh
new file mode 100644
index 00000000000..2b220af9460
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_tone_map_simple)
+ .local_group_size(16, 16)
+ .push_constant(Type::FLOAT, "luminance_scale")
+ .push_constant(Type::FLOAT, "luminance_scale_blend_factor")
+ .push_constant(Type::FLOAT, "inverse_gamma")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_tone_map_simple.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
new file mode 100644
index 00000000000..8e3e033147f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
@@ -0,0 +1,48 @@
+void node_composite_alpha_over_mixed(
+ float factor, vec4 color, vec4 over_color, float premultiply_factor, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float add_factor = 1.0 - premultiply_factor + over_color.a * premultiply_factor;
+ float premultiplier = factor * add_factor;
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + vec2(premultiplier, factor).xxxy * over_color;
+ }
+}
+
+void node_composite_alpha_over_key(float factor, vec4 color, vec4 over_color, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ result = mix(color, vec4(over_color.rgb, 1.0), factor * over_color.a);
+ }
+}
+
+void node_composite_alpha_over_premultiply(float factor,
+ vec4 color,
+ vec4 over_color,
+ out vec4 result)
+{
+ if (over_color.a < 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + factor * over_color;
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl
new file mode 100644
index 00000000000..e404c03bbb0
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl
@@ -0,0 +1,32 @@
+/* Preprocess the input of the blur filter by squaring it in its alpha straight form, assuming the
+ * given color is alpha premultiplied. */
+vec4 gamma_correct_blur_input(vec4 color)
+{
+ /* Unpremultiply alpha. */
+ color.rgb /= color.a > 0.0 ? color.a : 1.0;
+
+ /* Square color channel if it is positive, otherwise zero it. */
+ color.rgb *= mix(color.rgb, vec3(0.0), lessThan(color.rgb, vec3(0.0)));
+
+ /* Premultiply alpha to undo previous alpha unpremultiplication. */
+ color.rgb *= color.a > 0.0 ? color.a : 1.0;
+
+ return color;
+}
+
+/* Postprocess the output of the blur filter by taking its square root it in its alpha straight
+ * form, assuming the given color is alpha premultiplied. This essential undoes the processing done
+ * by the gamma_correct_blur_input function. */
+vec4 gamma_uncorrect_blur_output(vec4 color)
+{
+ /* Unpremultiply alpha. */
+ color.rgb /= color.a > 0.0 ? color.a : 1.0;
+
+ /* Take the square root of the color channel if it is positive, otherwise zero it. */
+ color.rgb = mix(sqrt(color.rgb), vec3(0.0), lessThan(color.rgb, vec3(0.0)));
+
+ /* Premultiply alpha to undo previous alpha unpremultiplication. */
+ color.rgb *= color.a > 0.0 ? color.a : 1.0;
+
+ return color;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
new file mode 100644
index 00000000000..ce71b4fd8a4
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
@@ -0,0 +1,38 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* The algorithm is by Werner D. Streidt
+ * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+ * Extracted of OpenCV demhist.c
+ */
+
+#define FLT_EPSILON 1.192092896e-07F
+
+void node_composite_bright_contrast(
+ vec4 color, float brightness, float contrast, const float use_premultiply, out vec4 result)
+{
+ brightness /= 100.0;
+ float delta = contrast / 200.0;
+
+ float multiplier, offset;
+ if (contrast > 0.0) {
+ multiplier = 1.0 - delta * 2.0;
+ multiplier = 1.0 / max(multiplier, FLT_EPSILON);
+ offset = multiplier * (brightness - delta);
+ }
+ else {
+ delta *= -1.0;
+ multiplier = max(1.0 - delta * 2.0, 0.0);
+ offset = multiplier * brightness + delta;
+ }
+
+ if (use_premultiply != 0.0) {
+ color_alpha_unpremultiply(color, color);
+ }
+
+ result.rgb = color.rgb * multiplier + offset;
+ result.a = color.a;
+
+ if (use_premultiply != 0.0) {
+ color_alpha_premultiply(result, result);
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl
new file mode 100644
index 00000000000..f2dcc9543f2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl
@@ -0,0 +1,52 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+#define CMP_NODE_CHANNEL_MATTE_CS_RGB 1.0
+#define CMP_NODE_CHANNEL_MATTE_CS_HSV 2.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YUV 3.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YCC 4.0
+
+void node_composite_channel_matte(vec4 color,
+ const float color_space,
+ const float matte_channel,
+ const vec2 limit_channels,
+ float max_limit,
+ float min_limit,
+ out vec4 result,
+ out float matte)
+{
+ vec4 channels;
+ if (color_space == CMP_NODE_CHANNEL_MATTE_CS_HSV) {
+ rgb_to_hsv(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YUV) {
+ rgba_to_yuva_itu_709(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YCC) {
+ rgba_to_ycca_itu_709(color, channels);
+ }
+ else {
+ channels = color;
+ }
+
+ float matte_value = channels[int(matte_channel)];
+ float limit_value = max(channels[int(limit_channels.x)], channels[int(limit_channels.y)]);
+
+ float alpha = 1.0 - (matte_value - limit_value);
+ if (alpha > max_limit) {
+ alpha = color.a;
+ }
+ else if (alpha < min_limit) {
+ alpha = 0.0;
+ }
+ else {
+ alpha = (alpha - min_limit) / (max_limit - min_limit);
+ }
+
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+#undef CMP_NODE_CHANNEL_MATTE_CS_RGB
+#undef CMP_NODE_CHANNEL_MATTE_CS_HSV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YUV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YCC
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl
new file mode 100644
index 00000000000..5d6bea0c9db
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl
@@ -0,0 +1,43 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Algorithm from the book Video Demystified. Chapter 7. Chroma Keying. */
+void node_composite_chroma_matte(vec4 color,
+ vec4 key,
+ float acceptance,
+ float cutoff,
+ float falloff,
+ out vec4 result,
+ out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ /* Normalize the CrCb components into the [-1, 1] range. */
+ vec2 color_cc = color_ycca.yz * 2.0 - 1.0;
+ vec2 key_cc = key_ycca.yz * 2.0 - 1.0;
+
+ /* Rotate the color onto the space of the key such that x axis of the color space passes through
+ * the key color. */
+ color_cc = vector_to_rotation_matrix(key_cc * vec2(1.0, -1.0)) * color_cc;
+
+ /* Compute foreground key. If positive, the value is in the [0, 1] range. */
+ float foreground_key = color_cc.x - (abs(color_cc.y) / acceptance);
+
+ /* Negative foreground key values retain the original alpha. Positive values are scaled by the
+ * falloff, while colors that make an angle less than the cutoff angle get a zero alpha. */
+ float alpha = color.a;
+ if (foreground_key > 0.0) {
+ alpha = 1.0 - (foreground_key / falloff);
+
+ if (abs(atan(color_cc.y, color_cc.x)) < (cutoff / 2.0)) {
+ alpha = 0.0;
+ }
+ }
+
+ /* Compute output. */
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
new file mode 100644
index 00000000000..bffb94cdedb
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
@@ -0,0 +1,34 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_balance_lgg(
+ float factor, vec4 color, vec3 lift, vec3 gamma, vec3 gain, out vec4 result)
+{
+ lift = 2.0 - lift;
+ vec3 srgb_color = linear_rgb_to_srgb(color.rgb);
+ vec3 lift_balanced = ((srgb_color - 1.0) * lift) + 1.0;
+
+ vec3 gain_balanced = lift_balanced * gain;
+ gain_balanced = max(gain_balanced, vec3(0.0));
+
+ vec3 linear_color = srgb_to_linear_rgb(gain_balanced);
+ gamma = mix(gamma, vec3(1e-6), equal(gamma, vec3(0.0)));
+ vec3 gamma_balanced = pow(linear_color, 1.0 / gamma);
+
+ result.rgb = mix(color.rgb, gamma_balanced, min(factor, 1.0));
+ result.a = color.a;
+}
+
+void node_composite_color_balance_asc_cdl(float factor,
+ vec4 color,
+ vec3 offset,
+ vec3 power,
+ vec3 slope,
+ float offset_basis,
+ out vec4 result)
+{
+ offset += offset_basis;
+ vec3 balanced = color.rgb * slope + offset;
+ balanced = pow(max(balanced, vec3(0.0)), power);
+ result.rgb = mix(color.rgb, balanced, min(factor, 1.0));
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
new file mode 100644
index 00000000000..9b4858f03be
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
@@ -0,0 +1,87 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_correction(vec4 color,
+ float mask,
+ const vec3 enabled_channels,
+ float start_midtones,
+ float end_midtones,
+ float master_saturation,
+ float master_contrast,
+ float master_gamma,
+ float master_gain,
+ float master_lift,
+ float shadows_saturation,
+ float shadows_contrast,
+ float shadows_gamma,
+ float shadows_gain,
+ float shadows_lift,
+ float midtones_saturation,
+ float midtones_contrast,
+ float midtones_gamma,
+ float midtones_gain,
+ float midtones_lift,
+ float highlights_saturation,
+ float highlights_contrast,
+ float highlights_gamma,
+ float highlights_gain,
+ float highlights_lift,
+ const vec3 luminance_coefficients,
+ out vec4 result)
+{
+ const float margin = 0.10;
+ const float margin_divider = 0.5 / margin;
+ float level = (color.r + color.g + color.b) / 3.0;
+ float level_shadows = 0.0;
+ float level_midtones = 0.0;
+ float level_highlights = 0.0;
+ if (level < (start_midtones - margin)) {
+ level_shadows = 1.0;
+ }
+ else if (level < (start_midtones + margin)) {
+ level_midtones = ((level - start_midtones) * margin_divider) + 0.5;
+ level_shadows = 1.0 - level_midtones;
+ }
+ else if (level < (end_midtones - margin)) {
+ level_midtones = 1.0;
+ }
+ else if (level < (end_midtones + margin)) {
+ level_highlights = ((level - end_midtones) * margin_divider) + 0.5;
+ level_midtones = 1.0 - level_highlights;
+ }
+ else {
+ level_highlights = 1.0;
+ }
+
+ float contrast = level_shadows * shadows_contrast;
+ contrast += level_midtones * midtones_contrast;
+ contrast += level_highlights * highlights_contrast;
+ contrast *= master_contrast;
+ float saturation = level_shadows * shadows_saturation;
+ saturation += level_midtones * midtones_saturation;
+ saturation += level_highlights * highlights_saturation;
+ saturation *= master_saturation;
+ float gamma = level_shadows * shadows_gamma;
+ gamma += level_midtones * midtones_gamma;
+ gamma += level_highlights * highlights_gamma;
+ gamma *= master_gamma;
+ float gain = level_shadows * shadows_gain;
+ gain += level_midtones * midtones_gain;
+ gain += level_highlights * highlights_gain;
+ gain *= master_gain;
+ float lift = level_shadows * shadows_lift;
+ lift += level_midtones * midtones_lift;
+ lift += level_highlights * highlights_lift;
+ lift += master_lift;
+
+ float inverse_gamma = 1.0 / gamma;
+ float luma = get_luminance(color.rgb, luminance_coefficients);
+
+ vec3 corrected = luma + saturation * (color.rgb - luma);
+ corrected = 0.5 + (corrected - 0.5) * contrast;
+ corrected = fallback_pow(corrected * gain + lift, inverse_gamma, corrected);
+ corrected = mix(color.rgb, corrected, min(mask, 1.0));
+
+ result.rgb = mix(corrected, color.rgb, equal(enabled_channels, vec3(0.0)));
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl
new file mode 100644
index 00000000000..038471bc1bc
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_matte(vec4 color,
+ vec4 key,
+ float hue_epsilon,
+ float saturation_epsilon,
+ float value_epsilon,
+ out vec4 result,
+ out float matte)
+
+{
+ vec4 color_hsva;
+ rgb_to_hsv(color, color_hsva);
+ vec4 key_hsva;
+ rgb_to_hsv(key, key_hsva);
+
+ bool is_within_saturation = distance(color_hsva.y, key_hsva.y) < saturation_epsilon;
+ bool is_within_value = distance(color_hsva.z, key_hsva.z) < value_epsilon;
+ bool is_within_hue = distance(color_hsva.x, key_hsva.x) < hue_epsilon;
+ /* Hue wraps around, so check the distance around the boundary. */
+ float min_hue = min(color_hsva.x, key_hsva.x);
+ float max_hue = max(color_hsva.x, key_hsva.x);
+ is_within_hue = is_within_hue || ((min_hue + (1.0 - max_hue)) < hue_epsilon);
+
+ matte = (is_within_hue && is_within_saturation && is_within_value) ? 0.0 : color.a;
+ result = color * matte;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl
new file mode 100644
index 00000000000..0adad53ad80
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl
@@ -0,0 +1,13 @@
+void node_composite_color_spill(vec4 color,
+ float factor,
+ const float spill_channel,
+ vec3 spill_scale,
+ const vec2 limit_channels,
+ float limit_scale,
+ out vec4 result)
+{
+ float average_limit = (color[int(limit_channels.x)] + color[int(limit_channels.y)]) / 2.0;
+ float map = factor * color[int(spill_channel)] - limit_scale * average_limit;
+ result.rgb = map > 0.0 ? color.rgb + spill_scale * map : color.rgb;
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
new file mode 100644
index 00000000000..bcdd625bd4f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
@@ -0,0 +1,6 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void color_to_luminance(vec4 color, const vec3 luminance_coefficients, out float result)
+{
+ result = get_luminance(color.rgb, luminance_coefficients);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl
new file mode 100644
index 00000000000..d769cadce3c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl
@@ -0,0 +1,10 @@
+void node_composite_difference_matte(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 difference = abs(color - key);
+ float average_difference = (difference.r + difference.g + difference.b) / 3.0;
+ bool is_opaque = average_difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : (max(0.0, average_difference - tolerance) / falloff);
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl
new file mode 100644
index 00000000000..9beed66826c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl
@@ -0,0 +1,26 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_distance_matte_rgba(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ float difference = distance(color.rgb, key.rgb);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+void node_composite_distance_matte_ycca(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ float difference = distance(color_ycca.yz, key_ycca.yz);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
new file mode 100644
index 00000000000..f246635a91e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
@@ -0,0 +1,6 @@
+void node_composite_exposure(vec4 color, float exposure, out vec4 result)
+{
+ float multiplier = exp2(exposure);
+ result.rgb = color.rgb * multiplier;
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
new file mode 100644
index 00000000000..53070d4b0e2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+
+void node_composite_gamma(vec4 color, float gamma, out vec4 result)
+{
+ result.rgb = fallback_pow(color.rgb, gamma, color.rgb);
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
new file mode 100644
index 00000000000..99eb125cdf2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
@@ -0,0 +1,39 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize
+ * parameters accordingly. */
+#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range)
+
+void node_composite_hue_correct(float factor,
+ vec4 color,
+ sampler1DArray curve_map,
+ const float layer,
+ vec3 minimums,
+ vec3 range_dividers,
+ out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ /* First, adjust the hue channel on its own, since corrections in the saturation and value
+ * channels depends on the new value of the hue, not its original value. A curve map value of 0.5
+ * means no change in hue, so adjust the value to get an identity at 0.5. Since the identity of
+ * addition is 0, we subtract 0.5 (0.5 - 0.5 = 0). */
+ const float hue_parameter = NORMALIZE_PARAMETER(hsv.x, minimums.x, range_dividers.x);
+ hsv.x += texture(curve_map, vec2(hue_parameter, layer)).x - 0.5;
+
+ /* Second, adjust the saturation and value based on the new value of the hue. A curve map value
+ * of 0.5 means no change in hue, so adjust the value to get an identity at 0.5. Since the
+ * identity of duplication is 1, we multiply by 2 (0.5 * 2 = 1). */
+ vec2 parameters = NORMALIZE_PARAMETER(hsv.x, minimums.yz, range_dividers.yz);
+ hsv.y *= texture(curve_map, vec2(parameters.x, layer)).y * 2.0;
+ hsv.z *= texture(curve_map, vec2(parameters.y, layer)).z * 2.0;
+
+ /* Sanitize the new hue and saturation values. */
+ hsv.x = fract(hsv.x);
+ hsv.y = clamp(hsv.y, 0.0, 1.0);
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
new file mode 100644
index 00000000000..dd5eb33d318
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_hue_saturation_value(
+ vec4 color, float hue, float saturation, float value, float factor, out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ hsv.x = fract(hsv.x + hue + 0.5);
+ hsv.y = clamp(hsv.y * saturation, 0.0, 1.0);
+ hsv.z = hsv.z * value;
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
new file mode 100644
index 00000000000..59be746da7f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
@@ -0,0 +1,13 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_invert(float fac, vec4 color, float do_rgb, float do_alpha, out vec4 result)
+{
+ result = color;
+ if (do_rgb != 0.0) {
+ result.rgb = 1.0 - result.rgb;
+ }
+ if (do_alpha != 0.0) {
+ result.a = 1.0 - result.a;
+ }
+ result = mix(color, result, fac);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl
new file mode 100644
index 00000000000..3647ac583fe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_luminance_matte(vec4 color,
+ float high,
+ float low,
+ const vec3 luminance_coefficients,
+ out vec4 result,
+ out float matte)
+{
+ float luminance = get_luminance(color.rgb, luminance_coefficients);
+ float alpha = clamp(0.0, 1.0, (luminance - low) / (high - low));
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
new file mode 100644
index 00000000000..27624223dbc
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
@@ -0,0 +1,7 @@
+/* The compute shader that will be dispatched by the compositor ShaderOperation. It just calls the
+ * evaluate function that will be dynamically generated and appended to this shader in the
+ * ShaderOperation::generate_code method. */
+void main()
+{
+ evaluate();
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
new file mode 100644
index 00000000000..20874b4ef44
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
@@ -0,0 +1,56 @@
+/* An arbitrary value determined by Blender. */
+#define BLENDER_ZMAX 10000.0
+
+void node_composite_map_range(float value,
+ float from_min,
+ float from_max,
+ float to_min,
+ float to_max,
+ const float should_clamp,
+ out float result)
+{
+ if (abs(from_max - from_min) < 1e-6) {
+ result = 0.0;
+ }
+ else {
+ if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) {
+ result = (value - from_min) / (from_max - from_min);
+ result = to_min + result * (to_max - to_min);
+ }
+ else if (value > BLENDER_ZMAX) {
+ result = to_max;
+ }
+ else {
+ result = to_min;
+ }
+
+ if (should_clamp != 0.0) {
+ if (to_max > to_min) {
+ result = clamp(result, to_min, to_max);
+ }
+ else {
+ result = clamp(result, to_max, to_min);
+ }
+ }
+ }
+}
+
+void node_composite_map_value(float value,
+ float offset,
+ float size,
+ const float use_min,
+ float min,
+ const float use_max,
+ float max,
+ out float result)
+{
+ result = (value + offset) * size;
+
+ if (use_min != 0.0 && result < min) {
+ result = min;
+ }
+
+ if (use_max != 0.0 && result > max) {
+ result = max;
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
new file mode 100644
index 00000000000..a2e3b6c4aaa
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
@@ -0,0 +1,9 @@
+void node_composite_normal(vec3 input_vector,
+ vec3 input_normal,
+ out vec3 result_normal,
+ out float result_dot)
+{
+ vec3 normal = normalize(input_normal);
+ result_normal = normal;
+ result_dot = -dot(input_vector, normal);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
new file mode 100644
index 00000000000..ee8ae234abe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
@@ -0,0 +1,6 @@
+void node_composite_posterize(vec4 color, float steps, out vec4 result)
+{
+ steps = clamp(steps, 2.0, 1024.0);
+ result = floor(color * steps) / steps;
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
new file mode 100644
index 00000000000..d72d2260394
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
@@ -0,0 +1,132 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* ** Combine/Separate XYZ ** */
+
+void node_composite_combine_xyz(float x, float y, float z, out vec3 vector)
+{
+ vector = vec3(x, y, z);
+}
+
+void node_composite_separate_xyz(vec3 vector, out float x, out float y, out float z)
+{
+ x = vector.x;
+ y = vector.y;
+ z = vector.z;
+}
+
+/* ** Combine/Separate RGBA ** */
+
+void node_composite_combine_rgba(float r, float g, float b, float a, out vec4 color)
+{
+ color = vec4(r, g, b, a);
+}
+
+void node_composite_separate_rgba(vec4 color, out float r, out float g, out float b, out float a)
+{
+ r = color.r;
+ g = color.g;
+ b = color.b;
+ a = color.a;
+}
+
+/* ** Combine/Separate HSVA ** */
+
+void node_composite_combine_hsva(float h, float s, float v, float a, out vec4 color)
+{
+ hsv_to_rgb(vec4(h, s, v, a), color);
+}
+
+void node_composite_separate_hsva(vec4 color, out float h, out float s, out float v, out float a)
+{
+ vec4 hsva;
+ rgb_to_hsv(color, hsva);
+ h = hsva.x;
+ s = hsva.y;
+ v = hsva.z;
+ a = hsva.a;
+}
+
+/* ** Combine/Separate HSLA ** */
+
+void node_composite_combine_hsla(float h, float s, float l, float a, out vec4 color)
+{
+ hsl_to_rgb(vec4(h, s, l, a), color);
+}
+
+void node_composite_separate_hsla(vec4 color, out float h, out float s, out float l, out float a)
+{
+ vec4 hsla;
+ rgb_to_hsl(color, hsla);
+ h = hsla.x;
+ s = hsla.y;
+ l = hsla.z;
+ a = hsla.a;
+}
+
+/* ** Combine/Separate YCCA ** */
+
+void node_composite_combine_ycca_itu_601(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_601(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_itu_709(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_709(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_jpeg(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_jpeg(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_separate_ycca_itu_601(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_601(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_itu_709(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_709(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_jpeg(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_jpeg(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+/* ** Combine/Separate YUVA ** */
+
+void node_composite_combine_yuva_itu_709(float y, float u, float v, float a, out vec4 color)
+{
+ yuva_to_rgba_itu_709(vec4(y, u, v, a), color);
+}
+
+void node_composite_separate_yuva_itu_709(
+ vec4 color, out float y, out float u, out float v, out float a)
+{
+ vec4 yuva;
+ rgba_to_yuva_itu_709(color, yuva);
+ y = yuva.x;
+ u = yuva.y;
+ v = yuva.z;
+ a = yuva.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
new file mode 100644
index 00000000000..95380d1ed0f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
@@ -0,0 +1,9 @@
+void node_composite_set_alpha_apply(vec4 color, float alpha, out vec4 result)
+{
+ result = color * alpha;
+}
+
+void node_composite_set_alpha_replace(vec4 color, float alpha, out vec4 result)
+{
+ result = vec4(color.rgb, alpha);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
new file mode 100644
index 00000000000..7fba26907b5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
@@ -0,0 +1,26 @@
+/* The following functions are called to store the given value in the output identified by the
+ * given ID. The ID is an unsigned integer that is encoded in a float, so floatBitsToUint is called
+ * to get the actual identifier. The functions have an output value as their last argument that is
+ * used to establish an output link that is then used to track the nodes that contribute to the
+ * output of the compositor node tree.
+ *
+ * The store_[float|vector|color] functions are dynamically generated in
+ * ShaderOperation::generate_code_for_outputs. */
+
+void node_compositor_store_output_float(const float id, float value, out float out_value)
+{
+ store_float(floatBitsToUint(id), value);
+ out_value = value;
+}
+
+void node_compositor_store_output_vector(const float id, vec3 vector, out vec3 out_vector)
+{
+ store_vector(floatBitsToUint(id), vector);
+ out_vector = vector;
+}
+
+void node_compositor_store_output_color(const float id, vec4 color, out vec4 out_color)
+{
+ store_color(floatBitsToUint(id), color);
+ out_color = color;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
new file mode 100644
index 00000000000..128fc6aeaf5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
@@ -0,0 +1,35 @@
+/* A shorthand for 1D textureSize with a zero LOD. */
+int texture_size(sampler1D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 1D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler1D sampler, int x)
+{
+ const int texture_bound = texture_size(sampler) - 1;
+ return texelFetch(sampler, clamp(x, 0, texture_bound), 0);
+}
+
+/* A shorthand for 2D textureSize with a zero LOD. */
+ivec2 texture_size(sampler2D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 2D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler2D sampler, ivec2 texel)
+{
+ const ivec2 texture_bounds = texture_size(sampler) - ivec2(1);
+ return texelFetch(sampler, clamp(texel, ivec2(0), texture_bounds), 0);
+}
+
+/* A shorthand for 2D texelFetch with zero LOD and a fallback value for out-of-bound access. */
+vec4 texture_load(sampler2D sampler, ivec2 texel, vec4 fallback)
+{
+ const ivec2 texture_bounds = texture_size(sampler) - ivec2(1);
+ if (any(lessThan(texel, ivec2(0))) || any(greaterThan(texel, texture_bounds))) {
+ return fallback;
+ }
+ return texelFetch(sampler, texel, 0);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
new file mode 100644
index 00000000000..75c76fd7341
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
@@ -0,0 +1,29 @@
+float float_from_vec4(vec4 vector)
+{
+ return dot(vector.rgb, vec3(1.0)) / 3.0;
+}
+
+float float_from_vec3(vec3 vector)
+{
+ return dot(vector, vec3(1.0)) / 3.0;
+}
+
+vec3 vec3_from_vec4(vec4 vector)
+{
+ return vector.rgb;
+}
+
+vec3 vec3_from_float(float value)
+{
+ return vec3(value);
+}
+
+vec4 vec4_from_vec3(vec3 vector)
+{
+ return vec4(vector, 1.0);
+}
+
+vec4 vec4_from_float(float value)
+{
+ return vec4(vec3(value), 1.0);
+}
diff --git a/source/blender/compositor/tests/COM_BuffersIterator_test.cc b/source/blender/compositor/tests/COM_BuffersIterator_test.cc
index 03748760029..89febb38655 100644
--- a/source/blender/compositor/tests/COM_BuffersIterator_test.cc
+++ b/source/blender/compositor/tests/COM_BuffersIterator_test.cc
@@ -237,7 +237,7 @@ TEST_F(BuffersIteratorTest, OutputIteration)
{
set_inputs_enabled(false);
test_iteration(
- [](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
+ [](BuffersIterator<float> &it, const rcti & /*area*/) {
EXPECT_EQ(it.get_num_inputs(), 0);
for (; !it.is_end(); ++it) {
const int dummy = it.y * BUFFER_WIDTH + it.x;
@@ -247,7 +247,7 @@ TEST_F(BuffersIteratorTest, OutputIteration)
it.out[3] = dummy + 4.0f;
}
},
- [](float *out, Span<const float *> UNUSED(ins), const int x, const int y) {
+ [](float *out, Span<const float *> /*ins*/, const int x, const int y) {
const int dummy = y * BUFFER_WIDTH + x;
EXPECT_NEAR(out[0], dummy + 1.0f, FLT_EPSILON);
EXPECT_NEAR(out[1], dummy + 2.0f, FLT_EPSILON);
@@ -260,7 +260,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration)
{
set_inputs_enabled(true);
test_iteration(
- [](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
+ [](BuffersIterator<float> &it, const rcti & /*area*/) {
EXPECT_EQ(it.get_num_inputs(), NUM_INPUTS);
for (; !it.is_end(); ++it) {
const float *in1 = it.in(0);
@@ -271,7 +271,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration)
it.out[3] = in1[3] - in2[1];
}
},
- [](float *out, Span<const float *> ins, const int UNUSED(x), const int UNUSED(y)) {
+ [](float *out, Span<const float *> ins, const int /*x*/, const int /*y*/) {
const float *in1 = ins[0];
const float *in2 = ins[1];
EXPECT_NEAR(out[0], in1[0] + in2[0], FLT_EPSILON);