Blender  V2.93
COM_MemoryBuffer.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2011, Blender Foundation.
17  */
18 
19 #pragma once
20 
21 #include "COM_ExecutionGroup.h"
22 #include "COM_MemoryProxy.h"
23 
24 #include "BLI_math.h"
25 #include "BLI_rect.h"
26 
27 namespace blender::compositor {
28 
33 enum class MemoryBufferState {
36  Default = 0,
38  Temporary = 6,
39 };
40 
41 enum class MemoryBufferExtend {
42  Clip,
43  Extend,
44  Repeat,
45 };
46 
47 class MemoryProxy;
48 
52 class MemoryBuffer {
53  private:
57  MemoryProxy *m_memoryProxy;
58 
62  DataType m_datatype;
63 
67  rcti m_rect;
68 
72  MemoryBufferState m_state;
73 
77  float *m_buffer;
78 
83  uint8_t m_num_channels;
84 
85  public:
89  MemoryBuffer(MemoryProxy *memoryProxy, const rcti &rect, MemoryBufferState state);
90 
94  MemoryBuffer(DataType datatype, const rcti &rect);
95 
99  MemoryBuffer(const MemoryBuffer &src);
100 
104  ~MemoryBuffer();
105 
107  {
108  return this->m_num_channels;
109  }
110 
115  float *getBuffer()
116  {
117  return this->m_buffer;
118  }
119 
120  inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
121  {
122  const int w = getWidth();
123  const int h = getHeight();
124  x = x - m_rect.xmin;
125  y = y - m_rect.ymin;
126 
127  switch (extend_x) {
129  break;
131  if (x < 0) {
132  x = 0;
133  }
134  if (x >= w) {
135  x = w;
136  }
137  break;
139  x = (x >= 0.0f ? (x % w) : (x % w) + w);
140  break;
141  }
142 
143  switch (extend_y) {
145  break;
147  if (y < 0) {
148  y = 0;
149  }
150  if (y >= h) {
151  y = h;
152  }
153  break;
155  y = (y >= 0.0f ? (y % h) : (y % h) + h);
156  break;
157  }
158  }
159 
160  inline void wrap_pixel(float &x,
161  float &y,
162  MemoryBufferExtend extend_x,
163  MemoryBufferExtend extend_y)
164  {
165  const float w = (float)getWidth();
166  const float h = (float)getHeight();
167  x = x - m_rect.xmin;
168  y = y - m_rect.ymin;
169 
170  switch (extend_x) {
172  break;
174  if (x < 0) {
175  x = 0.0f;
176  }
177  if (x >= w) {
178  x = w;
179  }
180  break;
182  x = fmodf(x, w);
183  break;
184  }
185 
186  switch (extend_y) {
188  break;
190  if (y < 0) {
191  y = 0.0f;
192  }
193  if (y >= h) {
194  y = h;
195  }
196  break;
198  y = fmodf(y, h);
199  break;
200  }
201  }
202 
203  inline void read(float *result,
204  int x,
205  int y,
208  {
209  bool clip_x = (extend_x == MemoryBufferExtend::Clip && (x < m_rect.xmin || x >= m_rect.xmax));
210  bool clip_y = (extend_y == MemoryBufferExtend::Clip && (y < m_rect.ymin || y >= m_rect.ymax));
211  if (clip_x || clip_y) {
212  /* clip result outside rect is zero */
213  memset(result, 0, this->m_num_channels * sizeof(float));
214  }
215  else {
216  int u = x;
217  int v = y;
218  this->wrap_pixel(u, v, extend_x, extend_y);
219  const int offset = (getWidth() * y + x) * this->m_num_channels;
220  float *buffer = &this->m_buffer[offset];
221  memcpy(result, buffer, sizeof(float) * this->m_num_channels);
222  }
223  }
224 
225  inline void readNoCheck(float *result,
226  int x,
227  int y,
230  {
231  int u = x;
232  int v = y;
233 
234  this->wrap_pixel(u, v, extend_x, extend_y);
235  const int offset = (getWidth() * v + u) * this->m_num_channels;
236 
237  BLI_assert(offset >= 0);
238  BLI_assert(offset < this->buffer_len() * this->m_num_channels);
239  BLI_assert(!(extend_x == MemoryBufferExtend::Clip && (u < m_rect.xmin || u >= m_rect.xmax)) &&
240  !(extend_y == MemoryBufferExtend::Clip && (v < m_rect.ymin || v >= m_rect.ymax)));
241  float *buffer = &this->m_buffer[offset];
242  memcpy(result, buffer, sizeof(float) * this->m_num_channels);
243  }
244 
245  void writePixel(int x, int y, const float color[4]);
246  void addPixel(int x, int y, const float color[4]);
247  inline void readBilinear(float *result,
248  float x,
249  float y,
252  {
253  float u = x;
254  float v = y;
255  this->wrap_pixel(u, v, extend_x, extend_y);
256  if ((extend_x != MemoryBufferExtend::Repeat && (u < 0.0f || u >= getWidth())) ||
257  (extend_y != MemoryBufferExtend::Repeat && (v < 0.0f || v >= getHeight()))) {
258  copy_vn_fl(result, this->m_num_channels, 0.0f);
259  return;
260  }
261  BLI_bilinear_interpolation_wrap_fl(this->m_buffer,
262  result,
263  getWidth(),
264  getHeight(),
265  this->m_num_channels,
266  u,
267  v,
268  extend_x == MemoryBufferExtend::Repeat,
269  extend_y == MemoryBufferExtend::Repeat);
270  }
271 
272  void readEWA(float *result, const float uv[2], const float derivatives[2][2]);
273 
277  inline bool isTemporarily() const
278  {
279  return this->m_state == MemoryBufferState::Temporary;
280  }
281 
289  void fill_from(const MemoryBuffer &src);
290 
294  const rcti &get_rect() const
295  {
296  return this->m_rect;
297  }
298 
302  const int getWidth() const
303  {
304  return BLI_rcti_size_x(&m_rect);
305  }
306 
310  const int getHeight() const
311  {
312  return BLI_rcti_size_y(&m_rect);
313  }
314 
318  void clear();
319 
320  float get_max_value() const;
321  float get_max_value(const rcti &rect) const;
322 
323  private:
324  const int buffer_len() const
325  {
326  return getWidth() * getHeight();
327  }
328 
329 #ifdef WITH_CXX_GUARDEDALLOC
330  MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")
331 #endif
332 };
333 
334 } // namespace blender::compositor
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_bilinear_interpolation_wrap_fl(const float *buffer, float *output, int width, int height, int components, float u, float v, bool wrap_x, bool wrap_y)
Definition: math_interp.c:480
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
_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
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
a MemoryBuffer contains access to the data of a chunk
void read(float *result, int x, int y, MemoryBufferExtend extend_x=MemoryBufferExtend::Clip, MemoryBufferExtend extend_y=MemoryBufferExtend::Clip)
void writePixel(int x, int y, const float color[4])
bool isTemporarily() const
is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
void readNoCheck(float *result, int x, int y, MemoryBufferExtend extend_x=MemoryBufferExtend::Clip, MemoryBufferExtend extend_y=MemoryBufferExtend::Clip)
const rcti & get_rect() const
get the rect of this MemoryBuffer
const int getHeight() const
get the height of this MemoryBuffer
const int getWidth() const
get the width of this MemoryBuffer
MemoryBuffer(MemoryProxy *memoryProxy, const rcti &rect, MemoryBufferState state)
construct new temporarily MemoryBuffer for an area
void wrap_pixel(float &x, float &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
void fill_from(const MemoryBuffer &src)
add the content from otherBuffer to this MemoryBuffer
void readEWA(float *result, const float uv[2], const float derivatives[2][2])
void readBilinear(float *result, float x, float y, MemoryBufferExtend extend_x=MemoryBufferExtend::Clip, MemoryBufferExtend extend_y=MemoryBufferExtend::Clip)
float * getBuffer()
get the data of this MemoryBuffer
void clear()
clear the buffer. Make all pixels black transparent.
void addPixel(int x, int y, const float color[4])
A MemoryProxy is a unique identifier for a memory buffer. A single MemoryProxy is used among all chun...
MemoryBufferState
state of a memory buffer
@ Temporary
chunk is consolidated from other chunks. special state.
@ Default
memory has been allocated on creator device and CPU machine, but kernel has not been executed
DataType
possible data types for sockets
Definition: COM_defines.h:27
#define fmodf(x, y)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
static ulong state[N]
unsigned char uint8_t
Definition: stdint.h:81
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79