411c5b9ad8a581e6d7a74eebe97b4ccca5fd89b3
[blender.git] / source / blender / compositor / intern / COM_MemoryBuffer.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 class MemoryBuffer;
24
25 #ifndef _COM_MemoryBuffer_h_
26 #define _COM_MemoryBuffer_h_
27
28 #include "COM_ExecutionGroup.h"
29 #include "BLI_rect.h"
30 #include "COM_MemoryProxy.h"
31
32 extern "C" {
33         //#include "BLI_threads.h"
34         #include "BLI_math.h"
35 }
36 //#include <vector>
37
38 /**
39  * @brief state of a memory buffer
40  * @ingroup Memory
41  */
42 typedef enum MemoryBufferState {
43         /** @brief memory has been allocated on creator device and CPU machine, but kernel has not been executed */
44         COM_MB_ALLOCATED = 1,
45         /** @brief memory is available for use, content has been created */
46         COM_MB_AVAILABLE = 2,
47         /** @brief chunk is consolidated from other chunks. special state.*/
48         COM_MB_TEMPORARILY = 6
49 } MemoryBufferState;
50
51 class MemoryProxy;
52
53 /**
54  * @brief a MemoryBuffer contains access to the data of a chunk
55  */
56 class MemoryBuffer {
57 private:
58         /**
59          * @brief proxy of the memory (same for all chunks in the same buffer)
60          */
61         MemoryProxy *m_memoryProxy;
62         
63         /**
64          * @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR
65          */
66         DataType m_datatype;
67         
68         
69         /**
70          * @brief region of this buffer inside relative to the MemoryProxy
71          */
72         rcti m_rect;
73         
74         /**
75          * brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
76          * @see memoryProxy
77          */
78         unsigned int m_chunkNumber;
79         
80         /**
81          * @brief width of the chunk
82          */
83         unsigned int m_chunkWidth;
84         
85         /**
86          * @brief state of the buffer
87          */
88         MemoryBufferState m_state;
89         
90         /**
91          * @brief the actual float buffer/data
92          */
93         float *m_buffer;
94
95 public:
96         /**
97          * @brief construct new MemoryBuffer for a chunk
98          */
99         MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
100         
101         /**
102          * @brief construct new temporarily MemoryBuffer for an area
103          */
104         MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect);
105         
106         /**
107          * @brief destructor
108          */
109         ~MemoryBuffer();
110         
111         /**
112          * @brief read the ChunkNumber of this MemoryBuffer
113          */
114         unsigned int getChunkNumber() { return this->m_chunkNumber; }
115         
116         /**
117          * @brief get the data of this MemoryBuffer
118          * @note buffer should already be available in memory
119          */
120         float *getBuffer() { return this->m_buffer; }
121         
122         /**
123          * @brief after execution the state will be set to available by calling this method
124          */
125         void setCreatedState()
126         {
127                 this->m_state = COM_MB_AVAILABLE;
128         }
129         
130         inline void read(float result[4], int x, int y)
131         {
132                 if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
133                     y >= this->m_rect.ymin && y < this->m_rect.ymax)
134                 {
135                         const int dx = x - this->m_rect.xmin;
136                         const int dy = y - this->m_rect.ymin;
137                         const int offset = (this->m_chunkWidth * dy + dx) * COM_NUMBER_OF_CHANNELS;
138                         copy_v4_v4(result, &this->m_buffer[offset]);
139                 }
140                 else {
141                         zero_v4(result);
142                 }
143         }
144
145         inline void readNoCheck(float result[4], int x, int y)
146         {
147                 const int dx = x - this->m_rect.xmin;
148                 const int dy = y - this->m_rect.ymin;
149                 const int offset = (this->m_chunkWidth * dy + dx) * COM_NUMBER_OF_CHANNELS;
150                 copy_v4_v4(result, &this->m_buffer[offset]);
151         }
152         
153         void writePixel(int x, int y, const float color[4]);
154         void addPixel(int x, int y, const float color[4]);
155         inline void readCubic(float result[4], float x, float y)
156         {
157                 int x1 = floor(x);
158                 int x2 = x1 + 1;
159                 int y1 = floor(y);
160                 int y2 = y1 + 1;
161
162                 float valuex = x - x1;
163                 float valuey = y - y1;
164                 float mvaluex = 1.0f - valuex;
165                 float mvaluey = 1.0f - valuey;
166
167                 float color1[4];
168                 float color2[4];
169                 float color3[4];
170                 float color4[4];
171
172                 read(color1, x1, y1);
173                 read(color2, x1, y2);
174                 read(color3, x2, y1);
175                 read(color4, x2, y2);
176
177                 color1[0] = color1[0] * mvaluey + color2[0] * valuey;
178                 color1[1] = color1[1] * mvaluey + color2[1] * valuey;
179                 color1[2] = color1[2] * mvaluey + color2[2] * valuey;
180                 color1[3] = color1[3] * mvaluey + color2[3] * valuey;
181
182                 color3[0] = color3[0] * mvaluey + color4[0] * valuey;
183                 color3[1] = color3[1] * mvaluey + color4[1] * valuey;
184                 color3[2] = color3[2] * mvaluey + color4[2] * valuey;
185                 color3[3] = color3[3] * mvaluey + color4[3] * valuey;
186
187                 result[0] = color1[0] * mvaluex + color3[0] * valuex;
188                 result[1] = color1[1] * mvaluex + color3[1] * valuex;
189                 result[2] = color1[2] * mvaluex + color3[2] * valuex;
190                 result[3] = color1[3] * mvaluex + color3[3] * valuex;
191         }
192                 
193
194
195         void readEWA(float result[4], float fx, float fy, float dx, float dy);
196         
197         /**
198          * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
199          */
200         inline const bool isTemporarily() const { return this->m_state == COM_MB_TEMPORARILY; }
201         
202         /**
203          * @brief add the content from otherBuffer to this MemoryBuffer
204          * @param otherBuffer source buffer
205          */
206         void copyContentFrom(MemoryBuffer *otherBuffer);
207         
208         /**
209          * @brief get the rect of this MemoryBuffer
210          */
211         rcti *getRect() { return &this->m_rect; }
212         
213         /**
214          * @brief get the width of this MemoryBuffer
215          */
216         int getWidth() const;
217         
218         /**
219          * @brief get the height of this MemoryBuffer
220          */
221         int getHeight() const;
222         
223         /**
224          * @brief clear the buffer. Make all pixels black transparent.
225          */
226         void clear();
227         
228         MemoryBuffer *duplicate();
229         
230         float *convertToValueBuffer();
231         float getMaximumValue();
232         float getMaximumValue(rcti* rect);
233 private:
234         unsigned int determineBufferSize();
235
236 #ifdef WITH_CXX_GUARDEDALLOC
237         MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")
238 #endif
239 };
240
241 #endif