Blender  V2.93
COM_DirectionalBlurOperation.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 
20 #include "COM_OpenCLDevice.h"
21 
22 #include "BLI_math.h"
23 
24 #include "RE_pipeline.h"
25 
26 namespace blender::compositor {
27 
29 {
32  flags.complex = true;
33  flags.open_cl = true;
34  this->m_inputProgram = nullptr;
35 }
36 
38 {
39  this->m_inputProgram = getInputSocketReader(0);
41  const float angle = this->m_data->angle;
42  const float zoom = this->m_data->zoom;
43  const float spin = this->m_data->spin;
44  const float iterations = this->m_data->iter;
45  const float distance = this->m_data->distance;
46  const float center_x = this->m_data->center_x;
47  const float center_y = this->m_data->center_y;
48  const float width = getWidth();
49  const float height = getHeight();
50 
51  const float a = angle;
52  const float itsc = 1.0f / powf(2.0f, (float)iterations);
53  float D;
54 
55  D = distance * sqrtf(width * width + height * height);
56  this->m_center_x_pix = center_x * width;
57  this->m_center_y_pix = center_y * height;
58 
59  this->m_tx = itsc * D * cosf(a);
60  this->m_ty = -itsc * D * sinf(a);
61  this->m_sc = itsc * zoom;
62  this->m_rot = itsc * spin;
63 }
64 
65 void DirectionalBlurOperation::executePixel(float output[4], int x, int y, void * /*data*/)
66 {
67  const int iterations = pow(2.0f, this->m_data->iter);
68  float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
69  float col2[4] = {0.0f, 0.0f, 0.0f, 0.0f};
70  this->m_inputProgram->readSampled(col2, x, y, PixelSampler::Bilinear);
71  float ltx = this->m_tx;
72  float lty = this->m_ty;
73  float lsc = this->m_sc;
74  float lrot = this->m_rot;
75  /* blur the image */
76  for (int i = 0; i < iterations; i++) {
77  const float cs = cosf(lrot), ss = sinf(lrot);
78  const float isc = 1.0f / (1.0f + lsc);
79 
80  const float v = isc * (y - this->m_center_y_pix) + lty;
81  const float u = isc * (x - this->m_center_x_pix) + ltx;
82 
83  this->m_inputProgram->readSampled(col,
84  cs * u + ss * v + this->m_center_x_pix,
85  cs * v - ss * u + this->m_center_y_pix,
87 
88  add_v4_v4(col2, col);
89 
90  /* double transformations */
91  ltx += this->m_tx;
92  lty += this->m_ty;
93  lrot += this->m_rot;
94  lsc += this->m_sc;
95  }
96 
97  mul_v4_v4fl(output, col2, 1.0f / (iterations + 1));
98 }
99 
101  MemoryBuffer *outputMemoryBuffer,
102  cl_mem clOutputBuffer,
103  MemoryBuffer **inputMemoryBuffers,
104  std::list<cl_mem> *clMemToCleanUp,
105  std::list<cl_kernel> * /*clKernelsToCleanUp*/)
106 {
107  cl_kernel directionalBlurKernel = device->COM_clCreateKernel("directionalBlurKernel", nullptr);
108 
109  cl_int iterations = pow(2.0f, this->m_data->iter);
110  cl_float2 ltxy = {{this->m_tx, this->m_ty}};
111  cl_float2 centerpix = {{this->m_center_x_pix, this->m_center_y_pix}};
112  cl_float lsc = this->m_sc;
113  cl_float lrot = this->m_rot;
114 
116  directionalBlurKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
118  directionalBlurKernel, 1, clOutputBuffer);
120  directionalBlurKernel, 2, outputMemoryBuffer);
121  clSetKernelArg(directionalBlurKernel, 3, sizeof(cl_int), &iterations);
122  clSetKernelArg(directionalBlurKernel, 4, sizeof(cl_float), &lsc);
123  clSetKernelArg(directionalBlurKernel, 5, sizeof(cl_float), &lrot);
124  clSetKernelArg(directionalBlurKernel, 6, sizeof(cl_float2), &ltxy);
125  clSetKernelArg(directionalBlurKernel, 7, sizeof(cl_float2), &centerpix);
126 
127  device->COM_clEnqueueRange(directionalBlurKernel, outputMemoryBuffer, 8, this);
128 }
129 
131 {
132  this->m_inputProgram = nullptr;
133 }
134 
136  ReadBufferOperation *readOperation,
137  rcti *output)
138 {
139  rcti newInput;
140 
141  newInput.xmax = this->getWidth();
142  newInput.xmin = 0;
143  newInput.ymax = this->getHeight();
144  newInput.ymin = 0;
145 
146  return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
147 }
148 
149 } // namespace blender::compositor
#define D
MINLINE void mul_v4_v4fl(float r[3], const float a[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
_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
_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
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define output
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
static SpinLock spin
Definition: cachefile.c:152
void executePixel(float output[4], int x, int y, void *data) override
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) override
void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, std::list< cl_mem > *clMemToCleanUp, std::list< cl_kernel > *clKernelsToCleanUp) override
custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevic...
a MemoryBuffer contains access to the data of a chunk
void readSampled(float result[4], float x, float y, PixelSampler sampler)
void addInputSocket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
void addOutputSocket(DataType datatype)
SocketReader * getInputSocketReader(unsigned int inputSocketindex)
virtual bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
device representing an GPU OpenCL device. an instance of this class represents a single cl_device
void COM_clAttachMemoryBufferOffsetToKernelParameter(cl_kernel kernel, int offsetIndex, MemoryBuffer *memoryBuffers)
cl_mem COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, std::list< cl_mem > *cleanup, MemoryBuffer **inputMemoryBuffers, SocketReader *reader)
void COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemoryBuffer)
void COM_clAttachOutputMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, cl_mem clOutputMemoryBuffer)
cl_kernel COM_clCreateKernel(const char *kernelname, std::list< cl_kernel > *clKernelsToCleanUp)
uint col
#define sinf(x)
#define cosf(x)
#define powf(x, y)
#define sqrtf(x)
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
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
ccl_device_inline float distance(const float2 &a, const float2 &b)