Blender V4.5
conversion_operation.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 <fmt/format.h>
6
7#include "BLI_color.hh"
8#include "BLI_cpp_type.hh"
9#include "BLI_generic_span.hh"
11#include "BLI_utildefines.h"
12
13#include "GPU_shader.hh"
14
16
18
19#include "COM_context.hh"
22#include "COM_result.hh"
23#include "COM_utilities.hh"
24
25namespace blender::compositor {
26
28 const ResultType input_type,
29 const ResultType expected_type)
31{
33 this->populate_result(context.create_result(expected_type));
34}
35
37{
38 Result &result = this->get_result();
39 const Result &input = this->get_input();
40
41 if (input.is_single_value()) {
42 result.allocate_single_value();
43 this->execute_single(input, result);
44 return;
45 }
46
47 result.allocate_texture(input.domain());
48 if (this->context().use_gpu()) {
49 const std::string shader_name = fmt::format("compositor_convert_{}_to_{}",
50 Result::type_name(this->get_input().type()),
51 Result::type_name(this->get_result().type()));
52 GPUShader *shader = this->context().get_shader(shader_name.c_str());
53 GPU_shader_bind(shader);
54
55 if (this->get_input().type() == ResultType::Color &&
57 {
58 float luminance_coefficients[3];
60 GPU_shader_uniform_3fv(shader, "luminance_coefficients_u", luminance_coefficients);
61 }
62
63 input.bind_as_texture(shader, "input_tx");
64 result.bind_as_image(shader, "output_img");
65
66 compute_dispatch_threads_at_least(shader, input.domain().size);
67
68 input.unbind_as_texture();
69 result.unbind_as_image();
71 }
72 else {
73 this->execute_cpu(input, result);
74 }
75}
76
78 const Result &input_result,
79 const InputDescriptor &input_descriptor)
80{
81 if (input_descriptor.skip_type_conversion) {
82 return nullptr;
83 }
84
85 const ResultType result_type = input_result.type();
86 const ResultType expected_type = input_descriptor.type;
87 if (result_type != expected_type) {
88 return new ConversionOperation(context, result_type, expected_type);
89 }
90 return nullptr;
91}
92
93/* Gets the single value of the given result as a single element GSpan. This calls the underlying
94 * single_value method to construct a GSpan from the GPointer, however, it has an exception for
95 * color types, since colors are stored as float4 internally, while their semantic type is
96 * ColorSceneLinear4f<eAlpha::Premultiplied> during conversion. */
98{
99 if (result.type() == ResultType::Color) {
100 return GSpan(
102 }
103
104 return GSpan(result.single_value().type(), result.single_value().get(), 1);
105}
106
108{
109 if (result.type() == ResultType::Color) {
110 return GMutableSpan(
112 }
113
114 return GMutableSpan(result.single_value().type(), result.single_value().get(), 1);
115}
116
117void ConversionOperation::execute_single(const Result &input, Result &output)
118{
122 output.update_single_value_data();
123}
124
125/* Gets the CPU data of the given result as a GSpan. This calls the underlying cpu_data method,
126 * however, it has an exception for color types, since colors are stored as float4 internally,
127 * while their semantic type is ColorSceneLinear4f<eAlpha::Premultiplied> during conversion. */
129{
130 if (result.type() == ResultType::Color) {
132 result.cpu_data().data(),
133 result.cpu_data().size());
134 }
135
136 return result.cpu_data();
137}
138
139/* Same as get_result_data but takes non-const result and returns a GMutableSpan. */
141{
142 if (result.type() == ResultType::Color) {
144 result.cpu_data().data(),
145 result.cpu_data().size());
146 }
147
148 return result.cpu_data();
149}
150
151void ConversionOperation::execute_cpu(const Result &input, Result &output)
152{
155}
156
157} // namespace blender::compositor
#define ELEM(...)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
void GPU_shader_unbind()
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
static const CPPType & get()
void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const
Result create_result(ResultType type, ResultPrecision precision)
GPUShader * get_shader(const char *info_name, ResultPrecision precision)
static SimpleOperation * construct_if_needed(Context &context, const Result &input_result, const InputDescriptor &input_descriptor)
ConversionOperation(Context &context, const ResultType input_type, const ResultType expected_type)
static ResultType type(eGPUTextureFormat format)
Definition result.cc:194
static const char * type_name(const ResultType type)
Definition result.cc:269
bool is_single_value() const
Definition result.cc:622
void declare_input_descriptor(InputDescriptor descriptor)
#define input
#define output
const DataTypeConversions & get_implicit_type_conversions()
static GSpan get_result_data(const Result &result)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
Definition utilities.cc:170
static GSpan get_result_single_value(const Result &result)