Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreHardwareBuffer.h

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #ifndef __HardwareBuffer__
00026 #define __HardwareBuffer__
00027 
00028 // Precompiler options
00029 #include "OgrePrerequisites.h"
00030 
00031 namespace Ogre {
00032 
00064     class _OgreExport HardwareBuffer 
00065     {
00066 
00067         public:
00069             enum Usage 
00070             {
00074                 HBU_STATIC = 1,
00080                 HBU_DYNAMIC = 2,
00087                 HBU_WRITE_ONLY = 4,
00089                 HBU_STATIC_WRITE_ONLY = 5, 
00091                 HBU_DYNAMIC_WRITE_ONLY = 6
00092 
00093 
00094             };
00096             enum LockOptions
00097             {
00099                 HBL_NORMAL,
00104                 HBL_DISCARD,
00108                 HBL_READ_ONLY,
00112                 HBL_NO_OVERWRITE
00113                 
00114             };
00115         protected:
00116             size_t mSizeInBytes;
00117             Usage mUsage;
00118             bool mIsLocked;
00119             size_t mLockStart;
00120             size_t mLockSize;
00121             bool mSystemMemory;
00122             bool mUseShadowBuffer;
00123             HardwareBuffer* mpShadowBuffer;
00124             bool mShadowUpdated;
00125             
00127             virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0;
00129             virtual void unlockImpl(void) = 0;
00130 
00131     public:
00133             HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer) 
00134                 : mUsage(usage), mIsLocked(false), mSystemMemory(systemMemory), 
00135                 mUseShadowBuffer(useShadowBuffer), mpShadowBuffer(NULL), mShadowUpdated(false) {}
00136             virtual ~HardwareBuffer() {}
00143             virtual void* lock(size_t offset, size_t length, LockOptions options)
00144             {
00145                 assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
00146                 void* ret;
00147                 if (mUseShadowBuffer)
00148                 {
00149                     if (options != HBL_READ_ONLY)
00150                     {
00151                         // we have to assume a read / write lock so we use the shadow buffer
00152                         // and tag for sync on unlock()
00153                         mShadowUpdated = true;
00154                     }
00155 
00156                     ret = mpShadowBuffer->lock(offset, length, options);
00157                 }
00158                 else
00159                 {
00160                     // Lock the real buffer if there is no shadow buffer 
00161                     ret = lockImpl(offset, length, options);
00162                     mIsLocked = true;
00163                 }
00164                 mLockStart = offset;
00165                 mLockSize = length;
00166                 return ret;
00167             }
00168 
00173             void* lock(LockOptions options)
00174             {
00175                 return this->lock(0, mSizeInBytes, options);
00176             }
00189             virtual void unlock(void)
00190             {
00191                 assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
00192 
00193                 // If we used the shadow buffer this time...
00194                 if (mUseShadowBuffer && mpShadowBuffer->isLocked())
00195                 {
00196                     mpShadowBuffer->unlock();
00197                     // Potentially update the 'real' buffer from the shadow buffer
00198                     _updateFromShadow();
00199                 }
00200                 else
00201                 {
00202                     // Otherwise, unlock the real one
00203                     unlockImpl();
00204                     mIsLocked = false;
00205                 }
00206 
00207             }
00208 
00215             virtual void readData(size_t offset, size_t length, void* pDest) = 0;
00224             virtual void writeData(size_t offset, size_t length, const void* pSource,
00225                     bool discardWholeBuffer = false) = 0;
00226 
00237             virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, 
00238                 size_t dstOffset, size_t length, bool discardWholeBuffer = false)
00239             {
00240                 const void *srcData = srcBuffer.lock(
00241                     srcOffset, length, HBL_READ_ONLY);
00242                 this->writeData(dstOffset, length, srcData, discardWholeBuffer);
00243                 srcBuffer.unlock();
00244             }
00245 
00247             virtual void _updateFromShadow(void)
00248             {
00249                 if (mUseShadowBuffer && mShadowUpdated)
00250                 {
00251                     // Do this manually to avoid locking problems
00252                     const void *srcData = mpShadowBuffer->lockImpl(
00253                         mLockStart, mLockSize, HBL_READ_ONLY);
00254                     // Lock with discard if the whole buffer was locked, otherwise normal
00255                     LockOptions lockOpt;
00256                     if (mLockStart == 0 && mLockSize == mSizeInBytes)
00257                         lockOpt = HBL_DISCARD;
00258                     else
00259                         lockOpt = HBL_NORMAL;
00260                     
00261                     void *destData = this->lockImpl(
00262                         mLockStart, mLockSize, lockOpt);
00263                     // Copy shadow to real
00264                     memcpy(destData, srcData, mLockSize);
00265                     this->unlockImpl();
00266                     mpShadowBuffer->unlockImpl();
00267                     mShadowUpdated = false;
00268                 }
00269             }
00270 
00272             size_t getSizeInBytes(void) const { return mSizeInBytes; }
00274             Usage getUsage(void) const { return mUsage; }
00276             bool isSystemMemory(void) const { return mSystemMemory; }
00278             bool isLocked(void) const { 
00279                 return mIsLocked || (mUseShadowBuffer && mpShadowBuffer->isLocked()); 
00280             }
00281 
00282 
00283 
00284 
00285             
00286     };
00287 }
00288 #endif
00289 
00290 

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:13 2004