Blender V4.3
COM_ViewerOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6#include "BKE_image.hh"
7#include "BKE_scene.hh"
9
11#include "IMB_imbuf.hh"
12#include "IMB_imbuf_types.hh"
13
14namespace blender::compositor {
15
17{
18 this->set_image(nullptr);
19 this->set_image_user(nullptr);
20 output_buffer_ = nullptr;
21 active_ = false;
22 view_settings_ = nullptr;
23 display_settings_ = nullptr;
24 use_alpha_input_ = false;
25
28
29 rd_ = nullptr;
30 view_name_ = nullptr;
33}
34
36{
38 init_image();
39 }
40}
41
43{
44 output_buffer_ = nullptr;
45}
46
47void ViewerOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
48{
49 int scene_render_width, scene_render_height;
50 BKE_render_resolution(rd_, false, &scene_render_width, &scene_render_height);
51
52 rcti local_preferred = preferred_area;
53 local_preferred.xmax = local_preferred.xmin + scene_render_width;
54 local_preferred.ymax = local_preferred.ymin + scene_render_height;
55
56 NodeOperation::determine_canvas(local_preferred, r_area);
57}
58
59void ViewerOperation::init_image()
60{
61 Image *ima = image_;
62 ImageUser iuser = *image_user_;
63 void *lock;
64 ImBuf *ibuf;
65
66 /* make sure the image has the correct number of views */
67 if (ima && BKE_scene_multiview_is_render_view_first(rd_, view_name_)) {
68 BKE_image_ensure_viewer_views(rd_, ima, image_user_);
69 }
70
72
73 /* local changes to the original ImageUser */
74 iuser.multi_index = BKE_scene_multiview_view_id_get(rd_, view_name_);
75 ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
76
77 if (!ibuf) {
79 return;
80 }
81
82 if (ibuf->x != get_width() || ibuf->y != get_height()) {
83
86 ibuf->x = get_width();
87 ibuf->y = get_height();
88 /* zero size can happen if no image buffers exist to define a sensible resolution */
89 if (ibuf->x > 0 && ibuf->y > 0) {
90 imb_addrectfloatImBuf(ibuf, 4);
91 }
92
94 }
95
96 /* now we combine the input with ibuf */
97 output_buffer_ = ibuf->float_buffer.data;
98
99 /* needed for display buffer update */
100 ibuf_ = ibuf;
101
102 BKE_image_release_ibuf(image_, ibuf_, lock);
103
105}
106
107void ViewerOperation::update_image(const rcti *rect)
108{
109 if (exec_system_->is_breaked()) {
110 return;
111 }
112
113 image_->runtime.backdrop_offset[0] = canvas_.xmin;
114 image_->runtime.backdrop_offset[1] = canvas_.ymin;
115 float *buffer = output_buffer_;
117 buffer,
118 nullptr,
119 get_width(),
120 0,
121 0,
122 view_settings_,
123 display_settings_,
124 rect->xmin,
125 rect->ymin,
126 rect->xmax,
127 rect->ymax);
128
129 /* This could be improved to use partial updates. For now disabled as the full frame compositor
130 * would not use partial frames anymore and the image engine requires more testing. */
132 this->update_draw();
133}
134
143
145 const rcti &area,
147{
148 if (!output_buffer_) {
149 return;
150 }
151
152 MemoryBuffer output_buffer(
154 const MemoryBuffer *input_image = inputs[0];
155 output_buffer.copy_from(input_image, area);
156 if (use_alpha_input_) {
157 const MemoryBuffer *input_alpha = inputs[1];
158 output_buffer.copy_from(input_alpha, area, 0, COM_DATA_TYPE_VALUE_CHANNELS, 3);
159 }
160
161 update_image(&area);
162}
163
165 const rcti & /*area*/,
166 Span<MemoryBuffer *> /*inputs*/)
167{
168 if (!image_) {
169 return;
170 }
171
172 const std::unique_ptr<MetaData> meta_data =
174
175 if (meta_data && meta_data->is_data) {
176 image_->flag &= ~IMA_VIEW_AS_RENDER;
177 /* TODO: Assign image buffer's color space to either non-color or linear, to be fully correct
178 * about the content of the pixels. This needs to happen consistently with the GPU compositor,
179 * and also consistently with the ibuf_ acquired as a state of this operation (which is not
180 * always guaranteed to happen here. */
181 }
182 else {
183 image_->flag |= IMA_VIEW_AS_RENDER;
184 }
185}
186
188{
190 if (exec_system_->is_breaked()) {
191 return;
192 }
193
194 init_image();
195 if (output_buffer_ == nullptr) {
196 return;
197 }
198
199 size_t buf_bytes = size_t(ibuf_->y) * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float);
200 if (buf_bytes > 0) {
201 memset(output_buffer_, 0, buf_bytes);
202 rcti display_area;
203 BLI_rcti_init(&display_area, 0, ibuf_->x, 0, ibuf_->y);
204 update_image(&display_area);
205 }
206}
207
208} // namespace blender::compositor
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_ensure_viewer_views(const RenderData *rd, Image *ima, ImageUser *iuser)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_image_partial_update_mark_full_update(Image *image)
Mark the whole image to be updated.
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2877
bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
Definition scene.cc:3002
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3070
#define BLI_assert(a)
Definition BLI_assert.h:50
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
void BLI_thread_unlock(int type)
Definition threads.cc:333
void BLI_thread_lock(int type)
Definition threads.cc:328
@ LOCK_DRAW_IMAGE
Definition BLI_threads.h:68
@ IMA_VIEW_AS_RENDER
void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const unsigned char *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, int xmin, int ymin, int xmax, int ymax)
void imb_freerectImBuf(ImBuf *ibuf)
void imb_freerectfloatImBuf(ImBuf *ibuf)
bool imb_addrectfloatImBuf(ImBuf *ibuf, const unsigned int channels, bool initialize_pixels=true)
Contains defines and structs used throughout the imbuf module.
@ IB_DISPLAY_BUFFER_INVALID
volatile int lock
a MemoryBuffer contains access to the data
void copy_from(const MemoryBuffer *src, const rcti &area)
virtual std::unique_ptr< MetaData > get_meta_data()
NodeOperationInput * get_input_socket(unsigned int index)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void determine_canvas(const rcti &preferred_area, rcti &r_area)
void set_image_user(ImageUser *image_user)
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
eCompositorPriority get_render_priority() const override
get the render priority of this node.
bool is_active_viewer_output() const override
is this operation the active viewer output user can select an ViewerNode to be active (the result of ...
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
void update_memory_buffer_finished(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
draw_view in_light_buf[] float
eCompositorPriority
Possible priority settings.
Definition COM_Enums.h:33
constexpr int COM_DATA_TYPE_VALUE_CHANNELS
Definition COM_defines.h:55
constexpr int COM_DATA_TYPE_COLOR_CHANNELS
Definition COM_defines.h:58
ImBufFloatBuffer float_buffer
short multi_index
float backdrop_offset[2]
Image_Runtime runtime
int ymin
int ymax
int xmin
int xmax