Blender V4.3
symmetric_separable_blur_weights.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <cstdint>
6#include <memory>
7
8#include "BLI_array.hh"
9#include "BLI_hash.hh"
10#include "BLI_index_range.hh"
11#include "BLI_math_base.hh"
12
13#include "RE_pipeline.h"
14
15#include "GPU_shader.hh"
16#include "GPU_texture.hh"
17
18#include "COM_context.hh"
19#include "COM_result.hh"
21
23
24/* --------------------------------------------------------------------
25 * Symmetric Separable Blur Weights Key.
26 */
27
29 : type(type), radius(radius)
30{
31}
32
34{
35 return get_default_hash(type, radius);
36}
37
40{
41 return a.type == b.type && a.radius == b.radius;
42}
43
44/* --------------------------------------------------------------------
45 * Symmetric Separable Blur Weights.
46 */
47
49 int type,
50 float radius)
51{
52 /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only
53 * compute half of it and no doubling happens. We add 1 to make sure the filter size is always
54 * odd and there is a center weight. */
55 const int size = math::ceil(radius) + 1;
56 Array<float> weights(size);
57
58 float sum = 0.0f;
59
60 /* First, compute the center weight. */
61 const float center_weight = RE_filter_value(type, 0.0f);
62 weights[0] = center_weight;
63 sum += center_weight;
64
65 /* Second, compute the other weights in the positive direction, making sure to add double the
66 * weight to the sum of weights because the filter is symmetric and we only loop over half of
67 * it. Skip the center weight already computed by dropping the front index. */
68 const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
69 for (const int i : weights.index_range().drop_front(1)) {
70 const float weight = RE_filter_value(type, i * scale);
71 weights[i] = weight;
72 sum += weight * 2.0f;
73 }
74
75 /* Finally, normalize the weights. */
76 for (const int i : weights.index_range()) {
77 weights[i] /= sum;
78 }
79
80 texture_ = GPU_texture_create_1d(
81 "Weights",
82 size,
83 1,
84 Result::gpu_texture_format(ResultType::Float, context.get_precision()),
86 weights.data());
87 GPU_texture_filter_mode(texture_, true);
89}
90
95
97 const char *texture_name) const
98{
99 const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
100 GPU_texture_bind(texture_, texture_image_unit);
101}
102
107
108/* --------------------------------------------------------------------
109 * Symmetric Separable Blur Weights Container.
110 */
111
113{
114 /* First, delete all resources that are no longer needed. */
115 map_.remove_if([](auto item) { return !item.value->needed; });
116
117 /* Second, reset the needed status of the remaining resources to false to ready them to track
118 * their needed status for the next evaluation. */
119 for (auto &value : map_.values()) {
120 value->needed = false;
121 }
122}
123
125 int type,
126 float radius)
127{
128 const SymmetricSeparableBlurWeightsKey key(type, radius);
129
130 auto &weights = *map_.lookup_or_add_cb(key, [&]() {
131 return std::make_unique<SymmetricSeparableBlurWeights>(context, type, radius);
132 });
133
134 weights.needed = true;
135 return weights;
136}
137
138} // namespace blender::realtime_compositor
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
void GPU_texture_bind(GPUTexture *texture, int unit)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
void GPU_texture_unbind(GPUTexture *texture)
void GPU_texture_extend_mode(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
@ GPU_TEXTURE_USAGE_GENERAL
@ GPU_SAMPLER_EXTEND_MODE_EXTEND
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
struct GPUShader GPUShader
static T sum(const btAlignedObjectArray< T > &items)
const T * data() const
Definition BLI_array.hh:301
IndexRange index_range() const
Definition BLI_array.hh:349
constexpr IndexRange drop_front(int64_t n) const
static eGPUTextureFormat gpu_texture_format(ResultType type, ResultPrecision precision)
Definition result.cc:29
SymmetricSeparableBlurWeights & get(Context &context, int type, float radius)
void bind_as_texture(GPUShader *shader, const char *texture_name) const
local_group_size(16, 16) .push_constant(Type b
float RE_filter_value(int type, float x)
T ceil(const T &a)
bool operator==(const BokehKernelKey &a, const BokehKernelKey &b)
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
unsigned __int64 uint64_t
Definition stdint.h:90