Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Buffer.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef Buffer_INCLUDE_ONCE
33 #define Buffer_INCLUDE_ONCE
34 
35 #include <vlCore/Object.hpp>
36 #include <string.h>
37 
38 namespace vl
39 {
40  //-----------------------------------------------------------------------------
41  // Buffer
42  //-----------------------------------------------------------------------------
46  class Buffer: public Object
47  {
49 
50  public:
51  typedef enum
52  {
56 
57  public:
59  {
60  VL_DEBUG_SET_OBJECT_NAME()
61  mPtr = NULL;
62  mByteCount = 0;
63  mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
65  }
66  Buffer(const Buffer& other): Object(other)
67  {
68  VL_DEBUG_SET_OBJECT_NAME()
69  mPtr = NULL;
70  mByteCount = 0;
71  mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
73  // copy local data
74  *this = other;
75  }
76  Buffer& operator=(const Buffer& other)
77  {
79  {
80  // same alignment
81  mAlignment = other.mAlignment;
82  // make space for new data
83  resize(other.bytesUsed());
84  // copy new data
85  memcpy(mPtr, other.ptr(), bytesUsed());
86  }
87  else
88  {
89  VL_CHECK(mPtr);
90  VL_CHECK(other.mPtr);
91  VL_CHECK(mByteCount == other.mByteCount);
92  memcpy(mPtr, other.ptr(), bytesUsed());
93  }
94  return *this;
95  }
96 
97  // swaps the data
98  void swap(Buffer& other)
99  {
100  // temp
101  unsigned char* tmp_ptr = mPtr;
102  size_t tmp_byte_count = mByteCount;
103  size_t tmp_alignment = mAlignment;
104  // this <- other
105  mPtr = other.mPtr;
106  mByteCount = other.mByteCount;
107  mAlignment = other.mAlignment;
108  // this -> other
109  other.mPtr = tmp_ptr;
110  other.mByteCount = tmp_byte_count;
111  other.mAlignment = tmp_alignment;
112  }
113 
115  {
116  clear();
117  }
118 
119  void clear()
120  {
122  alignedFree(mPtr);
123  }
124  mPtr = NULL;
125  mByteCount = 0;
127  }
128 
129  // if alignment < 1 uses the last specified alignment or the default one
130  void resize(size_t byte_count, size_t alignment = 0)
131  {
133 
134  if (byte_count == 0)
135  {
136  clear();
137  return;
138  }
139 
141  if ( byte_count != mByteCount || alignment != mAlignment)
142  {
144  // allocate the new chunk
145  unsigned char* ptr = NULL;
146  if (byte_count)
147  ptr = (unsigned char*)alignedMalloc(byte_count, mAlignment);
148  if (mPtr)
149  {
150  if (byte_count)
151  {
152  size_t min = mByteCount < byte_count ? mByteCount : byte_count;
153  // copy the old content brutally
154  memcpy(ptr, mPtr, min);
155  }
156  // free the old pointer
157  alignedFree(mPtr);
158  }
159  // set the new pointer
160  mPtr = ptr;
161  // set the new reserved bytes
162  mByteCount = byte_count;
163  }
164  }
165 
173  void setUserAllocatedBuffer(void* ptr, size_t bytes)
174  {
175  clear();
176  mPtr = (unsigned char*)ptr;
177  mByteCount = bytes;
178  mAlignment = 0;
180  }
181 
182  void setAllocationMode( EAllocationMode mode )
183  {
184  if ( mAllocationMode != mode )
185  {
186  clear();
187  mAllocationMode = mode;
188  // reset buffer data
189  mPtr = 0;
190  mByteCount = 0;
191  mAlignment = 0;
192  }
193  }
194 
195  EAllocationMode allocationMode() const { return mAllocationMode; }
196 
197  size_t bytesUsed() const { return mByteCount; }
198 
199  bool empty() const { return mByteCount == 0; }
200 
201  unsigned char* ptr() { return mPtr; }
202 
203  const unsigned char* ptr() const { return mPtr; }
204 
205  size_t alignment() const { return mAlignment; }
206 
207  // returns a chunck of memory aligned to the specified amount
208  // alignment must be a power of two
209  static void *alignedMalloc(size_t bytes, size_t alignment)
210  {
211  // alignment must be a power of two
212  if ( alignment & (alignment-1))
213  return NULL;
214 
215  size_t actual_byte_count = bytes + alignment - 1;
216 
217  // reserve space to store the delta
218  actual_byte_count += sizeof(int);
219 
220  // allocation
221  char *original_ptr = new char[actual_byte_count];
222 
223  if (original_ptr == NULL)
224  return NULL;
225 
226  // move base pointer by the space required for our delta
227  char *base_ptr = (char *)original_ptr + sizeof(int);
228 
229  // align the pointer
230  #if 1
231  // warning-free workaround
232  unsigned long long long_long_ptr = base_ptr - (char*)0;
233  while( long_long_ptr % alignment ) ++long_long_ptr;
234  void *aligned_ptr = (char*)0 + long_long_ptr;
235  #else
236  // this generates too many warnings
237  void *aligned_ptr = (void *) (((unsigned long long)base_ptr + alignment - 1) & ~((unsigned long long)alignment - 1));
238  #endif
239 
240  // compute the delta
241  int delta = (int)((char*)aligned_ptr - (char*)original_ptr);
242 
243  // store the delta just sizeof(int) bytes before the aligned pointer
244  *((int *)aligned_ptr - 1) = delta;
245 
246  return aligned_ptr;
247  }
248 
249  static void alignedFree(void *ptr)
250  {
251  if (ptr == NULL)
252  return;
253 
254  // gets the previously stored delta
255  int delta = *( (int *)ptr - 1);
256 
257  // calculate the pointer returned by malloc()
258  char *original_ptr = (char*)ptr - delta;
259 
260  // finally free the original pointer
261  delete [] original_ptr;
262  }
263 
264  protected:
265  unsigned char* mPtr;
266  size_t mByteCount;
267  size_t mAlignment;
268  EAllocationMode mAllocationMode;
269  };
270 
271 }
272 
273 #endif
void setUserAllocatedBuffer(void *ptr, size_t bytes)
Uses a user-allocated buffer as storage.
Definition: Buffer.hpp:173
unsigned char * mPtr
Definition: Buffer.hpp:265
size_t alignment() const
Definition: Buffer.hpp:205
size_t mAlignment
Definition: Buffer.hpp:267
void swap(Buffer &other)
Definition: Buffer.hpp:98
Implements a buffer whose storage is in local memory.
Definition: Buffer.hpp:46
void clear()
Definition: Buffer.hpp:119
size_t bytesUsed() const
Definition: Buffer.hpp:197
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
EAllocationMode
Definition: Buffer.hpp:51
EAllocationMode allocationMode() const
Definition: Buffer.hpp:195
Visualization Library main namespace.
const unsigned char * ptr() const
Definition: Buffer.hpp:203
Buffer(const Buffer &other)
Definition: Buffer.hpp:66
Buffer & operator=(const Buffer &other)
Definition: Buffer.hpp:76
EAllocationMode mAllocationMode
Definition: Buffer.hpp:268
bool empty() const
Definition: Buffer.hpp:199
The base class for all the reference counted objects.
Definition: Object.hpp:158
float min(float a, float b)
Definition: Vector2.hpp:307
void setAllocationMode(EAllocationMode mode)
Definition: Buffer.hpp:182
#define NULL
Definition: OpenGLDefs.hpp:81
unsigned char * ptr()
Definition: Buffer.hpp:201
void resize(size_t byte_count, size_t alignment=0)
Definition: Buffer.hpp:130
static void alignedFree(void *ptr)
Definition: Buffer.hpp:249
#define VL_CHECK(expr)
Definition: checks.hpp:73
static void * alignedMalloc(size_t bytes, size_t alignment)
Definition: Buffer.hpp:209
size_t mByteCount
Definition: Buffer.hpp:266