Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Buffer.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef Buffer_INCLUDE_ONCE
00033 #define Buffer_INCLUDE_ONCE
00034 
00035 #include <vlCore/Object.hpp>
00036 #include <string.h>
00037 
00038 namespace vl
00039 {
00040   //-----------------------------------------------------------------------------
00041   // Buffer
00042   //-----------------------------------------------------------------------------
00046   class Buffer: public Object
00047   {
00048     VL_INSTRUMENT_CLASS(vl::Buffer, Object)
00049 
00050   public:
00051     typedef enum
00052     {
00053       UserAllocatedBuffer,
00054       AutoAllocatedBuffer
00055     } EAllocationMode;
00056 
00057   public:
00058     Buffer()
00059     {
00060       VL_DEBUG_SET_OBJECT_NAME()
00061       mPtr = NULL;
00062       mByteCount = 0;
00063       mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
00064       mAllocationMode = AutoAllocatedBuffer;
00065     }
00066     Buffer(const Buffer& other): Object(other)
00067     {
00068       VL_DEBUG_SET_OBJECT_NAME()
00069       mPtr = NULL;
00070       mByteCount = 0;
00071       mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
00072       mAllocationMode = AutoAllocatedBuffer;
00073       // copy local data
00074       *this = other;
00075     }
00076     Buffer& operator=(const Buffer& other) 
00077     { 
00078       if ( mAllocationMode == AutoAllocatedBuffer)
00079       {
00080         // same alignment
00081         mAlignment = other.mAlignment;
00082         // make space for new data
00083         resize(other.bytesUsed());
00084         // copy new data
00085         memcpy(mPtr, other.ptr(), bytesUsed());
00086       }
00087       else
00088       {
00089         VL_CHECK(mPtr);
00090         VL_CHECK(other.mPtr);
00091         VL_CHECK(mByteCount == other.mByteCount);
00092         memcpy(mPtr, other.ptr(), bytesUsed());
00093       }
00094       return *this;
00095     }
00096 
00097     // swaps the data
00098     void swap(Buffer& other)
00099     {
00100       // temp
00101       unsigned char* tmp_ptr = mPtr;
00102       size_t tmp_byte_count = mByteCount;
00103       size_t tmp_alignment = mAlignment;
00104       // this <- other
00105       mPtr = other.mPtr;
00106       mByteCount = other.mByteCount;
00107       mAlignment = other.mAlignment;
00108       // this -> other
00109       other.mPtr = tmp_ptr;
00110       other.mByteCount = tmp_byte_count;
00111       other.mAlignment = tmp_alignment;
00112     }
00113 
00114     ~Buffer()
00115     {
00116       clear();
00117     }
00118 
00119     void clear()
00120     {
00121       if ( mAllocationMode == AutoAllocatedBuffer )
00122         alignedFree(mPtr);
00123       mPtr = NULL;
00124       mByteCount = 0;
00125     }
00126 
00127     // if alignment < 1 uses the last specified alignment or the default one
00128     void resize(size_t byte_count, size_t alignment = 0)
00129     {
00130       VL_CHECK( mAllocationMode == AutoAllocatedBuffer );
00131 
00132       if (byte_count == 0)
00133       {
00134         clear();
00135         return;
00136       }
00137 
00138       alignment = alignment >= 1 ? alignment : mAlignment;
00139       if ( byte_count != mByteCount || alignment != mAlignment)
00140       {
00141         mAlignment = alignment;
00142         // allocate the new chunk
00143         unsigned char* ptr = NULL;
00144         if (byte_count)
00145           ptr = (unsigned char*)alignedMalloc(byte_count, mAlignment);
00146         if (mPtr)
00147         {
00148           if (byte_count)
00149           {
00150             size_t min = mByteCount < byte_count ? mByteCount : byte_count;
00151             // copy the old content brutally
00152             memcpy(ptr, mPtr, min);
00153           }
00154           // free the old pointer
00155           alignedFree(mPtr);
00156         }
00157         // set the new pointer
00158         mPtr = ptr;
00159         // set the new reserved bytes
00160         mByteCount = byte_count;
00161       }
00162     }
00163 
00171     void setUserAllocatedBuffer(void* ptr, size_t bytes)
00172     {
00173       clear();
00174       mPtr = (unsigned char*)ptr;
00175       mByteCount = bytes;
00176       mAlignment = 0;
00177       mAllocationMode = UserAllocatedBuffer;
00178     }
00179 
00180     void setAllocationMode( EAllocationMode mode ) 
00181     { 
00182       if ( mAllocationMode != mode )
00183       {
00184         clear();
00185         mAllocationMode = mode;
00186         // reset buffer data
00187         mPtr = 0;
00188         mByteCount = 0;
00189         mAlignment = 0;
00190       }
00191     }
00192 
00193     EAllocationMode allocationMode() const { return mAllocationMode; }
00194 
00195     size_t bytesUsed() const { return mByteCount; }
00196 
00197     bool empty() const { return mByteCount == 0; }
00198 
00199     unsigned char* ptr() { return mPtr; }
00200 
00201     const unsigned char* ptr() const { return mPtr; }
00202 
00203     size_t alignment() const { return mAlignment; }
00204 
00205     // returns a chunck of memory aligned to the specified amount
00206     // alignment must be a power of two
00207     static void *alignedMalloc(size_t bytes, size_t alignment)
00208     {
00209       // alignment must be a power of two
00210       if ( alignment & (alignment-1))
00211         return NULL;
00212 
00213       size_t actual_byte_count = bytes + alignment - 1; 
00214 
00215       // reserve space to store the delta
00216       actual_byte_count += sizeof(int);
00217 
00218       // allocation
00219       char *original_ptr = new char[actual_byte_count];
00220 
00221       if (original_ptr == NULL)
00222         return NULL;
00223 
00224       // move base pointer by the space required for our delta
00225       char *base_ptr = (char *)original_ptr + sizeof(int);
00226 
00227       // align the pointer
00228       #if 1
00229         // warning-free workaround
00230         unsigned long long long_long_ptr = base_ptr - (char*)0;
00231         while( long_long_ptr % alignment ) ++long_long_ptr;
00232         void *aligned_ptr = (char*)0 + long_long_ptr;
00233       #else
00234         // this generates too many warnings
00235         void *aligned_ptr = (void *) (((unsigned long long)base_ptr + alignment - 1) & ~((unsigned long long)alignment - 1));
00236       #endif
00237 
00238       // compute the delta
00239       int delta = (int)((char*)aligned_ptr - (char*)original_ptr);
00240 
00241       // store the delta just sizeof(int) bytes before the aligned pointer
00242       *((int *)aligned_ptr - 1) = delta;
00243 
00244       return aligned_ptr;
00245     }
00246 
00247     static void alignedFree(void *ptr)
00248     {
00249       if (ptr == NULL)
00250         return;
00251 
00252       // gets the previously stored delta
00253       int delta = *( (int *)ptr - 1);
00254 
00255       // calculate the pointer returned by malloc()
00256       char *original_ptr = (char*)ptr - delta;
00257 
00258       // finally free the original pointer
00259       delete [] original_ptr;
00260     }
00261 
00262   protected:
00263     unsigned char* mPtr;
00264     size_t mByteCount;
00265     size_t mAlignment;
00266     EAllocationMode mAllocationMode;
00267   };
00268 
00269 }
00270 
00271 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:28.
Permission is granted to use this page to write and publish articles regarding Visualization Library.