Blender  V2.93
COM_MemoryBuffer.cc
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 #include "COM_MemoryBuffer.h"
20 
21 #include "MEM_guardedalloc.h"
22 
23 namespace blender::compositor {
24 
26 {
27  m_rect = rect;
28  this->m_memoryProxy = memoryProxy;
29  this->m_num_channels = COM_data_type_num_channels(memoryProxy->getDataType());
30  this->m_buffer = (float *)MEM_mallocN_aligned(
31  sizeof(float) * buffer_len() * this->m_num_channels, 16, "COM_MemoryBuffer");
32  this->m_state = state;
33  this->m_datatype = memoryProxy->getDataType();
34 }
35 
37 {
38  m_rect = rect;
39  this->m_memoryProxy = nullptr;
40  this->m_num_channels = COM_data_type_num_channels(dataType);
41  this->m_buffer = (float *)MEM_mallocN_aligned(
42  sizeof(float) * buffer_len() * this->m_num_channels, 16, "COM_MemoryBuffer");
43  this->m_state = MemoryBufferState::Temporary;
44  this->m_datatype = dataType;
45 }
46 
48  : MemoryBuffer(src.m_memoryProxy, src.m_rect, MemoryBufferState::Temporary)
49 {
50  memcpy(m_buffer, src.m_buffer, buffer_len() * m_num_channels * sizeof(float));
51 }
52 
54 {
55  memset(m_buffer, 0, buffer_len() * m_num_channels * sizeof(float));
56 }
57 
59 {
60  float result = this->m_buffer[0];
61  const unsigned int size = this->buffer_len();
62  unsigned int i;
63 
64  const float *fp_src = this->m_buffer;
65 
66  for (i = 0; i < size; i++, fp_src += this->m_num_channels) {
67  float value = *fp_src;
68  if (value > result) {
69  result = value;
70  }
71  }
72 
73  return result;
74 }
75 
76 float MemoryBuffer::get_max_value(const rcti &rect) const
77 {
78  rcti rect_clamp;
79 
80  /* first clamp the rect by the bounds or we get un-initialized values */
81  BLI_rcti_isect(&rect, &this->m_rect, &rect_clamp);
82 
83  if (!BLI_rcti_is_empty(&rect_clamp)) {
84  MemoryBuffer temp_buffer(this->m_datatype, rect_clamp);
85  temp_buffer.fill_from(*this);
86  return temp_buffer.get_max_value();
87  }
88 
89  BLI_assert(0);
90  return 0.0f;
91 }
92 
94 {
95  if (this->m_buffer) {
96  MEM_freeN(this->m_buffer);
97  this->m_buffer = nullptr;
98  }
99 }
100 
102 {
103  unsigned int otherY;
104  unsigned int minX = MAX2(this->m_rect.xmin, src.m_rect.xmin);
105  unsigned int maxX = MIN2(this->m_rect.xmax, src.m_rect.xmax);
106  unsigned int minY = MAX2(this->m_rect.ymin, src.m_rect.ymin);
107  unsigned int maxY = MIN2(this->m_rect.ymax, src.m_rect.ymax);
108  int offset;
109  int otherOffset;
110 
111  for (otherY = minY; otherY < maxY; otherY++) {
112  otherOffset = ((otherY - src.m_rect.ymin) * src.getWidth() + minX - src.m_rect.xmin) *
113  this->m_num_channels;
114  offset = ((otherY - this->m_rect.ymin) * getWidth() + minX - this->m_rect.xmin) *
115  this->m_num_channels;
116  memcpy(&this->m_buffer[offset],
117  &src.m_buffer[otherOffset],
118  (maxX - minX) * this->m_num_channels * sizeof(float));
119  }
120 }
121 
122 void MemoryBuffer::writePixel(int x, int y, const float color[4])
123 {
124  if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin &&
125  y < this->m_rect.ymax) {
126  const int offset = (getWidth() * (y - this->m_rect.ymin) + x - this->m_rect.xmin) *
127  this->m_num_channels;
128  memcpy(&this->m_buffer[offset], color, sizeof(float) * this->m_num_channels);
129  }
130 }
131 
132 void MemoryBuffer::addPixel(int x, int y, const float color[4])
133 {
134  if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin &&
135  y < this->m_rect.ymax) {
136  const int offset = (getWidth() * (y - this->m_rect.ymin) + x - this->m_rect.xmin) *
137  this->m_num_channels;
138  float *dst = &this->m_buffer[offset];
139  const float *src = color;
140  for (int i = 0; i < this->m_num_channels; i++, dst++, src++) {
141  *dst += *src;
142  }
143  }
144 }
145 
146 static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4])
147 {
148  MemoryBuffer *buffer = (MemoryBuffer *)userdata;
149  buffer->read(result, x, y);
150 }
151 
152 void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2])
153 {
154  BLI_assert(this->m_datatype == DataType::Color);
155  float inv_width = 1.0f / (float)this->getWidth(), inv_height = 1.0f / (float)this->getHeight();
156  /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
157  * but compositor uses pixel space. For now let's just divide the values and
158  * switch compositor to normalized space for EWA later.
159  */
160  float uv_normal[2] = {uv[0] * inv_width, uv[1] * inv_height};
161  float du_normal[2] = {derivatives[0][0] * inv_width, derivatives[0][1] * inv_height};
162  float dv_normal[2] = {derivatives[1][0] * inv_width, derivatives[1][1] * inv_height};
163 
164  BLI_ewa_filter(this->getWidth(),
165  this->getHeight(),
166  false,
167  true,
168  uv_normal,
169  du_normal,
170  dv_normal,
172  this,
173  result);
174 }
175 
176 } // namespace blender::compositor
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_ewa_filter(const int width, const int height, const bool intpol, const bool use_alpha, const float uv[2], const float du[2], const float dv[2], ewa_filter_read_pixel_cb read_pixel_cb, void *userdata, float result[4])
Definition: math_interp.c:599
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
bool BLI_rcti_is_empty(const struct rcti *rect)
#define MAX2(a, b)
#define MIN2(a, b)
_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
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
a MemoryBuffer contains access to the data of a chunk
void writePixel(int x, int y, const float color[4])
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 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 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.
DataType
possible data types for sockets
Definition: COM_defines.h:27
__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
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
Definition: mallocn.c:49
static ulong state[N]
static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4])
constexpr int COM_data_type_num_channels(const DataType datatype)
Definition: COM_defines.h:39
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