# Visualization Library

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

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

- Main Page
- 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.com                                               */
    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   public:
    00049     typedef enum
    00050     {
    00051       UserAllocatedBuffer,
    00052       AutoAllocatedBuffer
    00053     } EAllocationMode;
    00054
    00055   public:
    00056     virtual const char* className() { return "vl::Buffer"; }
    00057     Buffer()
    00058     {
    00059       VL_DEBUG_SET_OBJECT_NAME()
    00060       mPtr = NULL;
    00061       mByteCount = 0;
    00062       mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
    00063       mAllocationMode = AutoAllocatedBuffer;
    00064     }
    00065     Buffer(const Buffer& other): Object(other)
    00066     {
    00067       VL_DEBUG_SET_OBJECT_NAME()
    00068       mPtr = NULL;
    00069       mByteCount = 0;
    00070       mAlignment = VL_DEFAULT_BUFFER_BYTE_ALIGNMENT;
    00071       mAllocationMode = AutoAllocatedBuffer;
    00072       // copy local data
    00073       *this = other;
    00074     }
    00075     Buffer& operator=(const Buffer& other)
    00076     {
    00077       if ( mAllocationMode == AutoAllocatedBuffer)
    00078       {
    00079         // same alignment
    00080         mAlignment = other.mAlignment;
    00081         // make space for new data
    00082         resize(other.bytesUsed());
    00083         // copy new data
    00084         memcpy(mPtr, other.ptr(), bytesUsed());
    00085       }
    00086       else
    00087       {
    00088         VL_CHECK(mPtr);
    00089         VL_CHECK(other.mPtr);
    00090         VL_CHECK(mByteCount == other.mByteCount);
    00091         memcpy(mPtr, other.ptr(), bytesUsed());
    00092       }
    00093       return *this;
    00094     }
    00095
    00096     // swaps the data
    00097     void swap(Buffer& other)
    00098     {
    00099       // temp
    00100       unsigned char* tmp_ptr = mPtr;
    00101       size_t tmp_byte_count = mByteCount;
    00102       size_t tmp_alignment = mAlignment;
    00103       // this <- other
    00104       mPtr = other.mPtr;
    00105       mByteCount = other.mByteCount;
    00106       mAlignment = other.mAlignment;
    00107       // this -> other
    00108       other.mPtr = tmp_ptr;
    00109       other.mByteCount = tmp_byte_count;
    00110       other.mAlignment = tmp_alignment;
    00111     }
    00112
    00113     ~Buffer()
    00114     {
    00115       clear();
    00116     }
    00117
    00118     void clear()
    00119     {
    00120       if ( mAllocationMode == AutoAllocatedBuffer )
    00121         alignedFree(mPtr);
    00122       mPtr = NULL;
    00123       mByteCount = 0;
    00124     }
    00125
    00126     // if alignment < 1 uses the last specified alignment or the default one
    00127     void resize(size_t byte_count, size_t alignment = 0)
    00128     {
    00129       VL_CHECK( mAllocationMode == AutoAllocatedBuffer );
    00130
    00131       if (byte_count == 0)
    00132       {
    00133         clear();
    00134         return;
    00135       }
    00136
    00137       alignment = alignment >= 1 ? alignment : mAlignment;
    00138       if ( byte_count != mByteCount || alignment != mAlignment)
    00139       {
    00140         mAlignment = alignment;
    00141         // allocate the new chunk
    00142         unsigned char* ptr = NULL;
    00143         if (byte_count)
    00144           ptr = (unsigned char*)alignedMalloc(byte_count, mAlignment);
    00145         if (mPtr)
    00146         {
    00147           if (byte_count)
    00148           {
    00149             size_t min = mByteCount < byte_count ? mByteCount : byte_count;
    00150             // copy the old content brutally
    00151             memcpy(ptr, mPtr, min);
    00152           }
    00153           // free the old pointer
    00154           alignedFree(mPtr);
    00155         }
    00156         // set the new pointer
    00157         mPtr = ptr;
    00158         // set the new reserved bytes
    00159         mByteCount = byte_count;
    00160       }
    00161     }
    00162
    00170     void setUserAllocatedBuffer(void* ptr, size_t bytes)
    00171     {
    00172       clear();
    00173       mPtr = (unsigned char*)ptr;
    00174       mByteCount = bytes;
    00175       mAlignment = 0;
    00176       mAllocationMode = UserAllocatedBuffer;
    00177     }
    00178
    00179     void setAllocationMode( EAllocationMode mode )
    00180     {
    00181       if ( mAllocationMode != mode )
    00182       {
    00183         clear();
    00184         mAllocationMode = mode;
    00185         // reset buffer data
    00186         mPtr = 0;
    00187         mByteCount = 0;
    00188         mAlignment = 0;
    00189       }
    00190     }
    00191
    00192     EAllocationMode allocationMode() const { return mAllocationMode; }
    00193
    00194     size_t bytesUsed() const { return mByteCount; }
    00195
    00196     bool empty() const { return mByteCount == 0; }
    00197
    00198     unsigned char* ptr() { return mPtr; }
    00199
    00200     const unsigned char* ptr() const { return mPtr; }
    00201
    00202     size_t alignment() const { return mAlignment; }
    00203
    00204     // returns a chunck of memory aligned to the specified amount
    00205     // alignment must be a power of two
    00206     static void *alignedMalloc(size_t bytes, size_t alignment)
    00207     {
    00208       // alignment must be a power of two
    00209       if ( alignment & (alignment-1))
    00210         return NULL;
    00211
    00212       size_t actual_byte_count = bytes + alignment - 1;
    00213
    00214       // reserve space to store the delta
    00215       actual_byte_count += sizeof(int);
    00216
    00217       // allocation
    00218       char *original_ptr = new char[actual_byte_count];
    00219
    00220       if (original_ptr == NULL)
    00221         return NULL;
    00222
    00223       // move base pointer by the space required for our delta
    00224       char *base_ptr = (char *)original_ptr + sizeof(int);
    00225
    00226       // align the pointer
    00227       #if 1
    00228         // warning-free workaround
    00229         unsigned long long long_long_ptr = base_ptr - (char*)0;
    00230         while( long_long_ptr % alignment ) ++long_long_ptr;
    00231         void *aligned_ptr = (char*)0 + long_long_ptr;
    00232       #else
    00233         // this generates too many warnings
    00234         void *aligned_ptr = (void *) (((unsigned long long)base_ptr + alignment - 1) & ~((unsigned long long)alignment - 1));
    00235       #endif
    00236
    00237       // compute the delta
    00238       int delta = (int)((char*)aligned_ptr - (char*)original_ptr);
    00239
    00240       // store the delta just sizeof(int) bytes before the aligned pointer
    00241       *((int *)aligned_ptr - 1) = delta;
    00242
    00243       return aligned_ptr;
    00244     }
    00245
    00246     static void alignedFree(void *ptr)
    00247     {
    00248       if (ptr == NULL)
    00249         return;
    00250
    00251       // gets the previously stored delta
    00252       int delta = *( (int *)ptr - 1);
    00253
    00254       // calculate the pointer returned by malloc()
    00255       char *original_ptr = (char*)ptr - delta;
    00256
    00257       // finally free the original pointer
    00258       delete [] original_ptr;
    00259     }
    00260
    00261   protected:
    00262     unsigned char* mPtr;
    00263     size_t mByteCount;
    00264     size_t mAlignment;
    00265     EAllocationMode mAllocationMode;
    00266   };
    00267
    00268 }
    00269
    00270 #endif

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:20.
Permission is granted to use this page to write and publish articles regarding Visualization Library.