20 canvas_input_index_ = 0;
46 is_hash_output_params_implemented_ =
true;
48 if (!is_hash_output_params_implemented_) {
53 if (outputs_.size() > 0) {
58 hash.params_hash_ = params_hash_;
60 hash.parents_hash_ = 0;
62 if (!socket.is_connected()) {
67 const bool is_constant =
input.get_flags().is_constant_operation;
81 hash.type_hash_ =
typeid(*this).hash_code();
82 hash.operation_ =
this;
89 return &outputs_[index];
94 return &inputs_[index];
109 unsigned int used_canvas_index = 0;
113 const bool determined =
input.determine_canvas(preferred_area, any_area);
118 used_canvas_index += 1;
121 else if (canvas_input_index_ < inputs_.size()) {
123 input.determine_canvas(preferred_area, r_area);
124 used_canvas_index = canvas_input_index_;
127 if (modify_determined_canvas_fn_) {
128 modify_determined_canvas_fn_(r_area);
132 const rcti &local_preferred_area = r_area;
133 for (
unsigned int index = 0; index < inputs_.size(); index++) {
134 if (index == used_canvas_index) {
138 if (
input.is_connected()) {
139 input.determine_canvas(local_preferred_area, unused_area);
146 this->canvas_input_index_ = index;
209 return &
input->get_link()->get_operation();
219 if (inputs_.size() == 0) {
229 input, read_operation, &temp_output)) {
253 const rcti &output_area,
256 if (
get_flags().is_fullframe_operation) {
257 r_input_area = output_area;
268 const rcti &output_area,
284 if (
get_flags().is_fullframe_operation) {
285 render_full_frame(output_buf, areas, inputs_bufs);
288 render_full_frame_fallback(output_buf, areas, inputs_bufs);
292 void NodeOperation::render_full_frame(
MemoryBuffer *output_buf,
303 void NodeOperation::render_full_frame_fallback(MemoryBuffer *output_buf,
305 Span<MemoryBuffer *> inputs_bufs)
307 Vector<NodeOperationOutput *> orig_input_links = replace_inputs_with_buffers(inputs_bufs);
312 float *output_elem = output_buf->get_elem(0, 0);
316 for (
const rcti &rect : areas) {
318 rcti tile_rect = split_rect;
323 render_tile(output_buf, &tile_rect);
330 remove_buffers_and_restore_original_inputs(orig_input_links);
333 void NodeOperation::render_tile(MemoryBuffer *output_buf,
rcti *tile_rect)
337 const int elem_stride = output_buf->elem_stride;
338 for (
int y = tile_rect->
ymin; y < tile_rect->ymax;
y++) {
339 float *output_elem = output_buf->get_elem(tile_rect->
xmin,
y);
341 for (
int x = tile_rect->
xmin; x < tile_rect->xmax;
x++) {
342 read(output_elem,
x,
y, tile_data);
343 output_elem += elem_stride;
347 for (
int x = tile_rect->
xmin; x < tile_rect->xmax;
x++) {
349 output_elem += elem_stride;
358 Vector<NodeOperationOutput *> NodeOperation::replace_inputs_with_buffers(
359 Span<MemoryBuffer *> inputs_bufs)
362 Vector<NodeOperationOutput *> orig_links(inputs_bufs.size());
363 for (
int i = 0; i < inputs_bufs.size(); i++) {
365 BufferOperation *buffer_op =
new BufferOperation(inputs_bufs[i],
366 input_socket->get_data_type());
367 orig_links[i] = input_socket->get_link();
368 input_socket->set_link(buffer_op->get_output_socket());
369 buffer_op->init_execution();
374 void NodeOperation::remove_buffers_and_restore_original_inputs(
375 Span<NodeOperationOutput *> original_inputs_links)
378 for (
int i = 0; i < original_inputs_links.size(); i++) {
381 BLI_assert(
typeid(*buffer_op) ==
typeid(BufferOperation));
382 buffer_op->deinit_execution();
384 input_socket->set_link(original_inputs_links[i]);
398 : operation_(op), datatype_(datatype), resize_mode_(resize_mode), link_(nullptr)
425 : operation_(op), datatype_(datatype)
445 if (node_operation_flags.
complex) {
448 if (node_operation_flags.
open_cl) {
452 os <<
"single_threaded,";
455 os <<
"render_border,";
458 os <<
"view_border,";
464 os <<
"set_operation,";
467 os <<
"write_buffer,";
470 os <<
"read_buffer,";
482 os <<
"no_conversion,";
488 os <<
"contant_operation,";
491 os <<
"can_be_constant,";
500 os <<
"NodeOperation(";
501 os <<
"id=" << node_operation.
get_id();
502 if (!node_operation.
get_name().empty()) {
503 os <<
",name=" << node_operation.
get_name();
505 os <<
",flags={" << flags <<
"}";
511 if (write_operation) {
#define BLI_assert_msg(a, msg)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
bool BLI_rcti_is_empty(const struct rcti *rect)
void BLI_mutex_end(ThreadMutex *mutex)
void BLI_mutex_init(ThreadMutex *mutex)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void execute_work(const rcti &work_rect, std::function< void(const rcti &split_rect)> work_func)
a MemoryBuffer contains access to the data of a chunk
A MemoryProxy is a unique identifier for a memory buffer. A single MemoryProxy is used among all chun...
WriteBufferOperation * get_write_buffer_operation() const
get the WriteBufferOperation that is responsible for writing to this MemoryProxy
NodeOperationOutput(NodeOperation *op, DataType datatype)
void determine_canvas(const rcti &preferred_area, rcti &r_area)
NodeOperation & get_operation() const
NodeOperation contains calculation logic.
static void combine_hashes(size_t &combined, size_t other)
virtual void init_execution()
void set_canvas(const rcti &canvas_area)
void add_output_socket(DataType datatype)
unsigned int get_number_of_output_sockets() const
virtual bool is_output_operation(bool) const
is_output_operation determines whether this operation is an output of the ExecutionSystem during rend...
virtual void update_memory_buffer(MemoryBuffer *UNUSED(output), const rcti &UNUSED(area), Span< MemoryBuffer * > UNUSED(inputs))
const NodeOperationFlags get_flags() const
SocketReader * get_input_socket_reader(unsigned int index)
virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area)
Get input operation area being read by this operation on rendering given output area.
std::optional< NodeOperationHash > generate_hash()
float get_constant_value_default(float default_value)
unsigned int get_number_of_input_sockets() const
NodeOperationFlags flags_
NodeOperationOutput * get_output_socket(unsigned int index=0)
const rcti & get_canvas() const
NodeOperation * get_input_operation(int index)
const float * get_constant_elem_default(const float *default_elem)
ExecutionSystem * exec_system_
virtual void deinit_execution()
NodeOperationInput * get_input_socket(unsigned int index)
virtual void execute_region(rcti *, unsigned int)
when a chunk is executed by a CPUDevice, this method is called
void read(float result[4], int x, int y, void *chunk_data)
virtual bool determine_depending_area_of_interest(rcti *input, ReadBufferOperation *read_operation, rcti *output)
virtual void deinitialize_tile_data(rcti *, void *)
void read_sampled(float result[4], float x, float y, PixelSampler sampler)
virtual void hash_output_params()
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
const std::string get_name() const
void set_canvas_input_index(unsigned int index)
set the index of the input socket that will determine the canvas of this operation
void hash_params(T1 param1, T2 param2)
virtual void * initialize_tile_data(rcti *)
void render(MemoryBuffer *output_buf, Span< rcti > areas, Span< MemoryBuffer * > inputs_bufs)
virtual void determine_canvas(const rcti &preferred_area, rcti &r_area)
MemoryProxy * get_memory_proxy() const
NodeOperation to write to a tile.
DataType
possible data types for sockets
ResizeMode
Resize modes of inputsockets How are the input and working resolutions matched.
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
static constexpr unsigned int RESOLUTION_INPUT_ANY
static void area(int d1, int d2, int e1, int e2, float weights[2])
constexpr int COM_data_type_num_channels(const DataType datatype)
constexpr rcti COM_AREA_NONE
std::ostream & operator<<(std::ostream &os, const eCompositorPriority &priority)
uint64_t get_default_hash(const T &v)
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
bool is_write_buffer_operation
bool use_datatype_conversion
bool is_preview_operation
bool is_constant_operation
bool is_read_buffer_operation
bool is_fullframe_operation