# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/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 v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:26.
Permission is granted to use this page to write and publish articles regarding Visualization Library.