Blender V4.3
COM_GaussianBlurBaseOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7namespace blender::compositor {
8
11{
12 gausstab_ = nullptr;
13#if BLI_HAVE_SSE2
14 gausstab_sse_ = nullptr;
15#endif
16 filtersize_ = 0;
17 rad_ = 0.0f;
18 dimension_ = dim;
19}
20
28
30{
33#if BLI_HAVE_SSE2
34 gausstab_sse_ = BlurBaseOperation::convert_gausstab_sse(gausstab_, filtersize_);
35#endif
36}
37
39{
41
42 if (gausstab_) {
44 gausstab_ = nullptr;
45 }
46#if BLI_HAVE_SSE2
47 if (gausstab_sse_) {
48 MEM_freeN(gausstab_sse_);
49 gausstab_sse_ = nullptr;
50 }
51#endif
52}
53
55 const rcti &output_area,
56 rcti &r_input_area)
57{
58 if (input_idx != IMAGE_INPUT_INDEX) {
59 BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area);
60 return;
61 }
62
63 r_input_area = output_area;
64 switch (dimension_) {
65 case eDimension::X:
66 r_input_area.xmin = output_area.xmin - filtersize_ - 1;
67 r_input_area.xmax = output_area.xmax + filtersize_ + 1;
68 break;
69 case eDimension::Y:
70 r_input_area.ymin = output_area.ymin - filtersize_ - 1;
71 r_input_area.ymax = output_area.ymax + filtersize_ + 1;
72 break;
73 }
74}
75
77 const rcti &area,
79{
80 const int2 unit_offset = dimension_ == eDimension::X ? int2(1, 0) : int2(0, 1);
81 MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX];
82 for (BuffersIterator<float> it = output->iterate_with({input}, area); !it.is_end(); ++it) {
83 alignas(16) float4 accumulated_color = float4(0.0f);
84#if BLI_HAVE_SSE2
85 __m128 accumulated_color_sse = _mm_setzero_ps();
86 for (int i = -filtersize_; i <= filtersize_; i++) {
87 const int2 offset = unit_offset * i;
88 __m128 weight = gausstab_sse_[i + filtersize_];
89 __m128 color = _mm_load_ps(input->get_elem_clamped(it.x + offset.x, it.y + offset.y));
90 __m128 weighted_color = _mm_mul_ps(color, weight);
91 accumulated_color_sse = _mm_add_ps(accumulated_color_sse, weighted_color);
92 }
93 _mm_store_ps(accumulated_color, accumulated_color_sse);
94#else
95 for (int i = -filtersize_; i <= filtersize_; i++) {
96 const int2 offset = unit_offset * i;
97 const float weight = gausstab_[i + filtersize_];
98 const float4 color = input->get_elem_clamped(it.x + offset.x, it.y + offset.y);
99 accumulated_color += color * weight;
100 }
101#endif
102 copy_v4_v4(it.out, accumulated_color);
103 }
104}
105
106} // namespace blender::compositor
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE void copy_v4_v4(float r[4], const float a[4])
#define MAX_GAUSSTAB_RADIUS
virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
virtual void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
a MemoryBuffer contains access to the data
DataType
possible data types for sockets
Definition COM_defines.h:21
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
ccl_device_inline float3 ceil(const float3 a)
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
int ymin
int ymax
int xmin
int xmax