Blender  V3.3
COM_NodeOperation.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
4 #pragma once
5 
6 #include <functional>
7 #include <list>
8 
9 #include "BLI_ghash.h"
10 #include "BLI_hash.hh"
11 #include "BLI_rect.h"
12 #include "BLI_span.hh"
13 #include "BLI_threads.h"
14 #include "BLI_utildefines.h"
15 
16 #include "COM_Enums.h"
17 #include "COM_MemoryBuffer.h"
18 #include "COM_MetaData.h"
19 
20 #include "clew.h"
21 
22 #include "DNA_node_types.h"
23 
24 namespace blender::compositor {
25 
26 class OpenCLDevice;
27 class ReadBufferOperation;
28 class ExecutionSystem;
29 class NodeOperation;
30 class NodeOperationOutput;
31 
33 
39 static constexpr unsigned int RESOLUTION_INPUT_ANY = 999999;
40 
46 enum class ResizeMode {
51  None = NS_CR_NONE,
56  Align = 100,
63  FitAny = NS_CR_FIT,
67 };
68 
70  private:
71  NodeOperation *operation_;
72 
76  DataType datatype_;
77 
79  ResizeMode resize_mode_;
80 
82  NodeOperationOutput *link_;
83 
84  public:
86  DataType datatype,
87  ResizeMode resize_mode = ResizeMode::Center);
88 
90  {
91  return *operation_;
92  }
94  {
95  return datatype_;
96  }
97 
99  {
100  link_ = link;
101  }
103  {
104  return link_;
105  }
106  bool is_connected() const
107  {
108  return link_;
109  }
110 
111  void set_resize_mode(ResizeMode resize_mode)
112  {
113  resize_mode_ = resize_mode;
114  }
116  {
117  return resize_mode_;
118  }
119 
121 
125  bool determine_canvas(const rcti &preferred_area, rcti &r_area);
126 
127 #ifdef WITH_CXX_GUARDEDALLOC
128  MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
129 #endif
130 };
131 
133  private:
134  NodeOperation *operation_;
135 
139  DataType datatype_;
140 
141  public:
143 
145  {
146  return *operation_;
147  }
149  {
150  return datatype_;
151  }
152 
153  void determine_canvas(const rcti &preferred_area, rcti &r_area);
154 
155 #ifdef WITH_CXX_GUARDEDALLOC
156  MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
157 #endif
158 };
159 
170  bool complex : 1;
171 
175  bool open_cl : 1;
176 
181  bool single_threaded : 1;
182 
199 
203  bool is_canvas_set : 1;
204 
215 
223 
228 
233 
238  bool can_be_constant : 1;
239 
241  {
242  complex = false;
243  single_threaded = false;
244  open_cl = false;
245  use_render_border = false;
246  use_viewer_border = false;
247  is_canvas_set = false;
248  is_set_operation = false;
249  is_read_buffer_operation = false;
251  is_proxy_operation = false;
252  is_viewer_operation = false;
253  is_preview_operation = false;
255  is_fullframe_operation = false;
256  is_constant_operation = false;
257  can_be_constant = false;
258  }
259 };
260 
263  private:
264  NodeOperation *operation_;
265  size_t type_hash_;
266  size_t parents_hash_;
267  size_t params_hash_;
268 
269  friend class NodeOperation;
270 
271  public:
273  {
274  return operation_;
275  }
276 
277  bool operator==(const NodeOperationHash &other) const
278  {
279  return type_hash_ == other.type_hash_ && parents_hash_ == other.parents_hash_ &&
280  params_hash_ == other.params_hash_;
281  }
282 
283  bool operator!=(const NodeOperationHash &other) const
284  {
285  return !(*this == other);
286  }
287 
288  bool operator<(const NodeOperationHash &other) const
289  {
290  return type_hash_ < other.type_hash_ ||
291  (type_hash_ == other.type_hash_ && parents_hash_ < other.parents_hash_) ||
292  (type_hash_ == other.type_hash_ && parents_hash_ == other.parents_hash_ &&
293  params_hash_ < other.params_hash_);
294  }
295 };
296 
304  private:
305  int id_;
306  std::string name_;
309 
310  size_t params_hash_;
311  bool is_hash_output_params_implemented_;
312 
316  unsigned int canvas_input_index_;
317 
318  std::function<void(rcti &canvas)> modify_determined_canvas_fn_;
319 
329  ThreadMutex mutex_;
330 
334  const bNodeTree *btree_;
335 
336  protected:
341 
343 
348 
350 
351  public:
352  virtual ~NodeOperation()
353  {
354  }
355 
356  void set_name(const std::string name)
357  {
358  name_ = name;
359  }
360 
361  const std::string get_name() const
362  {
363  return name_;
364  }
365 
366  void set_id(const int id)
367  {
368  id_ = id;
369  }
370 
371  const int get_id() const
372  {
373  return id_;
374  }
375 
377  float get_constant_value_default(float default_value);
379  const float *get_constant_elem_default(const float *default_elem);
380 
382  {
383  return flags_;
384  }
385 
391  std::optional<NodeOperationHash> generate_hash();
392 
393  unsigned int get_number_of_input_sockets() const
394  {
395  return inputs_.size();
396  }
397  unsigned int get_number_of_output_sockets() const
398  {
399  return outputs_.size();
400  }
401  NodeOperationOutput *get_output_socket(unsigned int index = 0);
402  NodeOperationInput *get_input_socket(unsigned int index);
403 
405 
406  virtual void determine_canvas(const rcti &preferred_area, rcti &r_area);
407 
423  virtual bool is_output_operation(bool /*rendering*/) const
424  {
425  return false;
426  }
427 
429  {
430  execution_model_ = model;
431  }
432 
434  {
435  btree_ = tree;
436  }
437 
439  {
440  exec_system_ = system;
441  }
442 
447  virtual void init_data();
448 
449  virtual void init_execution();
450 
458  virtual void execute_region(rcti * /*rect*/, unsigned int /*chunk_number*/)
459  {
460  }
461 
474  virtual void execute_opencl_region(OpenCLDevice * /*device*/,
475  rcti * /*rect*/,
476  unsigned int /*chunk_number*/,
477  MemoryBuffer ** /*memory_buffers*/,
478  MemoryBuffer * /*output_buffer*/)
479  {
480  }
481 
497  virtual void execute_opencl(OpenCLDevice * /*device*/,
498  MemoryBuffer * /*output_memory_buffer*/,
499  cl_mem /*cl_output_buffer*/,
500  MemoryBuffer ** /*input_memory_buffers*/,
501  std::list<cl_mem> * /*cl_mem_to_clean_up*/,
502  std::list<cl_kernel> * /*cl_kernels_to_clean_up*/)
503  {
504  }
505  virtual void deinit_execution();
506 
507  void set_canvas(const rcti &canvas_area);
508  const rcti &get_canvas() const;
513  void unset_canvas();
514 
522  virtual bool is_active_viewer_output() const
523  {
524  return false;
525  }
526 
528  ReadBufferOperation *read_operation,
529  rcti *output);
530 
535  void set_canvas_input_index(unsigned int index);
536 
541  void set_determined_canvas_modifier(std::function<void(rcti &canvas)> fn)
542  {
543  modify_determined_canvas_fn_ = fn;
544  }
545 
552  {
554  }
555 
556  inline bool is_braked() const
557  {
558  return btree_->test_break(btree_->tbh);
559  }
560 
561  inline void update_draw()
562  {
563  if (btree_->update_draw) {
564  btree_->update_draw(btree_->udh);
565  }
566  }
567 
568  unsigned int get_width() const
569  {
570  return BLI_rcti_size_x(&get_canvas());
571  }
572 
573  unsigned int get_height() const
574  {
575  return BLI_rcti_size_y(&get_canvas());
576  }
577 
578  inline void read_sampled(float result[4], float x, float y, PixelSampler sampler)
579  {
581  }
582 
583  inline void read_filtered(float result[4], float x, float y, float dx[2], float dy[2])
584  {
585  execute_pixel_filtered(result, x, y, dx, dy);
586  }
587 
588  inline void read(float result[4], int x, int y, void *chunk_data)
589  {
590  execute_pixel(result, x, y, chunk_data);
591  }
592 
593  virtual void *initialize_tile_data(rcti * /*rect*/)
594  {
595  return 0;
596  }
597 
598  virtual void deinitialize_tile_data(rcti * /*rect*/, void * /*data*/)
599  {
600  }
601 
602  virtual MemoryBuffer *get_input_memory_buffer(MemoryBuffer ** /*memory_buffers*/)
603  {
604  return 0;
605  }
606 
611  virtual std::unique_ptr<MetaData> get_meta_data()
612  {
613  return std::unique_ptr<MetaData>();
614  }
615 
616  /* -------------------------------------------------------------------- */
626  void render(MemoryBuffer *output_buf, Span<rcti> areas, Span<MemoryBuffer *> inputs_bufs);
627 
632  const rcti &UNUSED(area),
634  {
635  }
636 
649  virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area);
650  void get_area_of_interest(NodeOperation *input_op, const rcti &output_area, rcti &r_input_area);
651 
654  protected:
655  NodeOperation();
656 
657  /* Overridden by subclasses to allow merging equal operations on compiling. Implementations must
658  * hash any subclass parameter that affects the output result using `hash_params` methods. */
659  virtual void hash_output_params()
660  {
661  is_hash_output_params_implemented_ = false;
662  }
663 
664  static void combine_hashes(size_t &combined, size_t other)
665  {
666  combined = BLI_ghashutil_combine_hash(combined, other);
667  }
668 
669  template<typename T> void hash_param(T param)
670  {
671  combine_hashes(params_hash_, get_default_hash(param));
672  }
673 
674  template<typename T1, typename T2> void hash_params(T1 param1, T2 param2)
675  {
676  combine_hashes(params_hash_, get_default_hash_2(param1, param2));
677  }
678 
679  template<typename T1, typename T2, typename T3> void hash_params(T1 param1, T2 param2, T3 param3)
680  {
681  combine_hashes(params_hash_, get_default_hash_3(param1, param2, param3));
682  }
683 
684  void add_input_socket(DataType datatype, ResizeMode resize_mode = ResizeMode::Center);
685  void add_output_socket(DataType datatype);
686 
687  /* TODO(manzanilla): to be removed with tiled implementation. */
688  void set_width(unsigned int width)
689  {
691  flags_.is_canvas_set = true;
692  }
693  void set_height(unsigned int height)
694  {
696  flags_.is_canvas_set = true;
697  }
698 
699  SocketReader *get_input_socket_reader(unsigned int index);
700 
701  void deinit_mutex();
702  void init_mutex();
703  void lock_mutex();
704  void unlock_mutex();
705 
712  void set_complex(bool complex)
713  {
714  flags_.complex = complex;
715  }
716 
725  virtual void execute_pixel_sampled(float /*output*/[4],
726  float /*x*/,
727  float /*y*/,
728  PixelSampler /*sampler*/)
729  {
730  }
731 
741  virtual void execute_pixel(float output[4], int x, int y, void * /*chunk_data*/)
742  {
744  }
745 
757  float /*output*/[4], float /*x*/, float /*y*/, float /*dx*/[2], float /*dy*/[2])
758  {
759  }
760 
761  private:
762  /* -------------------------------------------------------------------- */
769  void render_full_frame(MemoryBuffer *output_buf,
770  Span<rcti> areas,
771  Span<MemoryBuffer *> inputs_bufs);
772 
776  void render_full_frame_fallback(MemoryBuffer *output_buf,
777  Span<rcti> areas,
779  void render_tile(MemoryBuffer *output_buf, rcti *tile_rect);
783  Vector<NodeOperationOutput *> replace_inputs_with_buffers(Span<MemoryBuffer *> inputs_bufs);
784  void remove_buffers_and_restore_original_inputs(
785  Span<NodeOperationOutput *> original_inputs_links);
786 
789  /* allow the DebugInfo class to look at internals */
790  friend class DebugInfo;
791 
792 #ifdef WITH_CXX_GUARDEDALLOC
793  MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
794 #endif
795 };
796 
797 std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operation_flags);
798 std::ostream &operator<<(std::ostream &os, const NodeOperation &node_operation);
799 
800 } // namespace blender::compositor
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
#define UNUSED(x)
#define NS_CR_FIT_HEIGHT
#define NS_CR_STRETCH
#define NS_CR_CENTER
#define NS_CR_FIT
#define NS_CR_FIT_WIDTH
#define NS_CR_NONE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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
_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 GLsizei width
int64_t size() const
Definition: BLI_vector.hh:694
the ExecutionSystem contains the whole compositor tree.
a MemoryBuffer contains access to the data of a chunk
void set_link(NodeOperationOutput *link)
bool determine_canvas(const rcti &preferred_area, rcti &r_area)
NodeOperationInput(NodeOperation *op, DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void set_resize_mode(ResizeMode resize_mode)
NodeOperationOutput * get_link() const
NodeOperationOutput(NodeOperation *op, DataType datatype)
void determine_canvas(const rcti &preferred_area, rcti &r_area)
NodeOperation contains calculation logic.
void set_bnodetree(const bNodeTree *tree)
static void combine_hashes(size_t &combined, size_t other)
void set_name(const std::string name)
void set_canvas(const rcti &canvas_area)
virtual void execute_pixel_filtered(float[4], float, float, float[2], float[2])
calculate a single pixel using an EWA filter
void add_output_socket(DataType datatype)
void read_filtered(float result[4], float x, float y, float dx[2], float dy[2])
virtual void execute_opencl_region(OpenCLDevice *, rcti *, unsigned int, MemoryBuffer **, MemoryBuffer *)
when a chunk is executed by an OpenCLDevice, this method is called
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)
virtual MemoryBuffer * get_input_memory_buffer(MemoryBuffer **)
unsigned int get_number_of_input_sockets() const
virtual bool is_active_viewer_output() const
is this operation the active viewer output user can select an ViewerNode to be active (the result of ...
NodeOperationOutput * get_output_socket(unsigned int index=0)
NodeOperation * get_input_operation(int index)
const float * get_constant_elem_default(const float *default_elem)
void hash_params(T1 param1, T2 param2, T3 param3)
NodeOperationInput * get_input_socket(unsigned int index)
void set_width(unsigned int width)
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 execute_opencl(OpenCLDevice *, MemoryBuffer *, cl_mem, MemoryBuffer **, std::list< cl_mem > *, std::list< cl_kernel > *)
custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevic...
virtual eCompositorPriority get_render_priority() const
get the render priority of this node.
void set_height(unsigned int height)
virtual void deinitialize_tile_data(rcti *, void *)
void read_sampled(float result[4], float x, float y, PixelSampler sampler)
virtual std::unique_ptr< MetaData > get_meta_data()
void set_determined_canvas_modifier(std::function< void(rcti &canvas)> fn)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void execute_pixel(float output[4], int x, int y, void *)
calculate a single pixel
void set_execution_system(ExecutionSystem *system)
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 execute_pixel_sampled(float[4], float, float, PixelSampler)
calculate a single pixel
void set_complex(bool complex)
set whether this operation is complex
void set_execution_model(const eExecutionModel model)
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)
device representing an GPU OpenCL device. an instance of this class represents a single cl_device
SyclQueue void void size_t num_bytes void
void * tree
depth_tx sampler(1, ImageType::FLOAT_2D, "combined_tx") .sampler(2
eCompositorPriority
Possible priority settings.
Definition: COM_Enums.h:32
DataType
possible data types for sockets
Definition: COM_defines.h:30
ResizeMode
Resize modes of inputsockets How are the input and working resolutions matched.
@ FitAny
Fit the width or the height of the input image to the width or height of the working area of the node...
@ FitWidth
Fit the width of the input image to the width of the working area of the node.
@ Center
Center the input image to the center of the working area of the node, no resizing occurs.
@ FitHeight
Fit the height of the input image to the height of the working area of the node.
@ Stretch
Fit the width and the height of the input image to the width and height of the working area of the no...
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
#define T
#define T2
Definition: md5.cpp:18
#define T3
Definition: md5.cpp:19
#define T1
Definition: md5.cpp:17
static constexpr unsigned int RESOLUTION_INPUT_ANY
static void area(int d1, int d2, int e1, int e2, float weights[2])
constexpr rcti COM_AREA_NONE
Definition: COM_defines.h:112
NodeOperation SocketReader
std::ostream & operator<<(std::ostream &os, const eCompositorPriority &priority)
Definition: COM_Enums.cc:26
uint64_t get_default_hash(const T &v)
Definition: BLI_hash.hh:218
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
Definition: BLI_hash.hh:223
uint64_t get_default_hash_3(const T1 &v1, const T2 &v2, const T3 &v3)
Definition: BLI_hash.hh:231
static bNodeSocketTemplate inputs[]
int(* test_break)(void *)
void(* update_draw)(void *)
bool operator!=(const NodeOperationHash &other) const
bool operator==(const NodeOperationHash &other) const
bool operator<(const NodeOperationHash &other) const
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63