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             bool mSuppressHardwareUpdate;
00126             
00128             virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0;
00130             virtual void unlockImpl(void) = 0;
00131 
00132     public:
00134             HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer) 
00135                 : mUsage(usage), mIsLocked(false), mSystemMemory(systemMemory), 
00136                 mUseShadowBuffer(useShadowBuffer), mpShadowBuffer(NULL), mShadowUpdated(false), 
00137                 mSuppressHardwareUpdate(false) {}
00138             virtual ~HardwareBuffer() {}
00145             virtual void* lock(size_t offset, size_t length, LockOptions options)
00146             {
00147                 assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
00148                 void* ret;
00149                 if (mUseShadowBuffer)
00150                 {
00151                     if (options != HBL_READ_ONLY)
00152                     {
00153                         // we have to assume a read / write lock so we use the shadow buffer
00154                         // and tag for sync on unlock()
00155                         mShadowUpdated = true;
00156                     }
00157 
00158                     ret = mpShadowBuffer->lock(offset, length, options);
00159                 }
00160                 else
00161                 {
00162                     // Lock the real buffer if there is no shadow buffer 
00163                     ret = lockImpl(offset, length, options);
00164                     mIsLocked = true;
00165                 }
00166                 mLockStart = offset;
00167                 mLockSize = length;
00168                 return ret;
00169             }
00170 
00175             void* lock(LockOptions options)
00176             {
00177                 return this->lock(0, mSizeInBytes, options);
00178             }
00191             virtual void unlock(void)
00192             {
00193                 assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
00194 
00195                 // If we used the shadow buffer this time...
00196                 if (mUseShadowBuffer && mpShadowBuffer->isLocked())
00197                 {
00198                     mpShadowBuffer->unlock();
00199                     // Potentially update the 'real' buffer from the shadow buffer
00200                     _updateFromShadow();
00201                 }
00202                 else
00203                 {
00204                     // Otherwise, unlock the real one
00205                     unlockImpl();
00206                     mIsLocked = false;
00207                 }
00208 
00209             }
00210 
00217             virtual void readData(size_t offset, size_t length, void* pDest) = 0;
00226             virtual void writeData(size_t offset, size_t length, const void* pSource,
00227                     bool discardWholeBuffer = false) = 0;
00228 
00239             virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, 
00240                 size_t dstOffset, size_t length, bool discardWholeBuffer = false)
00241             {
00242                 const void *srcData = srcBuffer.lock(
00243                     srcOffset, length, HBL_READ_ONLY);
00244                 this->writeData(dstOffset, length, srcData, discardWholeBuffer);
00245                 srcBuffer.unlock();
00246             }
00247 
00249             virtual void _updateFromShadow(void)
00250             {
00251                 if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate)
00252                 {
00253                     // Do this manually to avoid locking problems
00254                     const void *srcData = mpShadowBuffer->lockImpl(
00255                         mLockStart, mLockSize, HBL_READ_ONLY);
00256                     // Lock with discard if the whole buffer was locked, otherwise normal
00257                     LockOptions lockOpt;
00258                     if (mLockStart == 0 && mLockSize == mSizeInBytes)
00259                         lockOpt = HBL_DISCARD;
00260                     else
00261                         lockOpt = HBL_NORMAL;
00262                     
00263                     void *destData = this->lockImpl(
00264                         mLockStart, mLockSize, lockOpt);
00265                     // Copy shadow to real
00266                     memcpy(destData, srcData, mLockSize);
00267                     this->unlockImpl();
00268                     mpShadowBuffer->unlockImpl();
00269                     mShadowUpdated = false;
00270                 }
00271             }
00272 
00274             size_t getSizeInBytes(void) const { return mSizeInBytes; }
00276             Usage getUsage(void) const { return mUsage; }
00278             bool isSystemMemory(void) const { return mSystemMemory; }
00280             bool hasShadowBuffer(void) const { return mUseShadowBuffer; }
00282             bool isLocked(void) const { 
00283                 return mIsLocked || (mUseShadowBuffer && mpShadowBuffer->isLocked()); 
00284             }
00286             void suppressHardwareUpdate(bool suppress) {
00287                 mSuppressHardwareUpdate = suppress;
00288                 if (!suppress)
00289                     _updateFromShadow();
00290             }
00291 
00292 
00293 
00294 
00295             
00296     };
00297 }
00298 #endif
00299 
00300 

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:16 2004