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 (c) 2000-2009 Torus Knot Software Ltd 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a copy 00010 of this software and associated documentation files (the "Software"), to deal 00011 in the Software without restriction, including without limitation the rights 00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 copies of the Software, and to permit persons to whom the Software is 00014 furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 THE SOFTWARE. 00026 ----------------------------------------------------------------------------- 00027 */ 00028 #ifndef __HardwareBuffer__ 00029 #define __HardwareBuffer__ 00030 00031 // Precompiler options 00032 #include "OgrePrerequisites.h" 00033 00034 namespace Ogre { 00035 00073 class _OgreExport HardwareBuffer : public BufferAlloc 00074 { 00075 00076 public: 00078 enum Usage 00079 { 00083 HBU_STATIC = 1, 00089 HBU_DYNAMIC = 2, 00096 HBU_WRITE_ONLY = 4, 00105 HBU_DISCARDABLE = 8, 00107 HBU_STATIC_WRITE_ONLY = 5, 00113 HBU_DYNAMIC_WRITE_ONLY = 6, 00115 HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE = 14 00116 00117 00118 }; 00120 enum LockOptions 00121 { 00123 HBL_NORMAL, 00128 HBL_DISCARD, 00132 HBL_READ_ONLY, 00136 HBL_NO_OVERWRITE 00137 00138 }; 00139 protected: 00140 size_t mSizeInBytes; 00141 Usage mUsage; 00142 bool mIsLocked; 00143 size_t mLockStart; 00144 size_t mLockSize; 00145 bool mSystemMemory; 00146 bool mUseShadowBuffer; 00147 HardwareBuffer* mpShadowBuffer; 00148 bool mShadowUpdated; 00149 bool mSuppressHardwareUpdate; 00150 00152 virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0; 00154 virtual void unlockImpl(void) = 0; 00155 00156 public: 00158 HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer) 00159 : mUsage(usage), mIsLocked(false), mSystemMemory(systemMemory), 00160 mUseShadowBuffer(useShadowBuffer), mpShadowBuffer(NULL), mShadowUpdated(false), 00161 mSuppressHardwareUpdate(false) 00162 { 00163 // If use shadow buffer, upgrade to WRITE_ONLY on hardware side 00164 if (useShadowBuffer && usage == HBU_DYNAMIC) 00165 { 00166 mUsage = HBU_DYNAMIC_WRITE_ONLY; 00167 } 00168 else if (useShadowBuffer && usage == HBU_STATIC) 00169 { 00170 mUsage = HBU_STATIC_WRITE_ONLY; 00171 } 00172 } 00173 virtual ~HardwareBuffer() {} 00180 virtual void* lock(size_t offset, size_t length, LockOptions options) 00181 { 00182 assert(!isLocked() && "Cannot lock this buffer, it is already locked!"); 00183 void* ret; 00184 if (mUseShadowBuffer) 00185 { 00186 if (options != HBL_READ_ONLY) 00187 { 00188 // we have to assume a read / write lock so we use the shadow buffer 00189 // and tag for sync on unlock() 00190 mShadowUpdated = true; 00191 } 00192 00193 ret = mpShadowBuffer->lock(offset, length, options); 00194 } 00195 else 00196 { 00197 // Lock the real buffer if there is no shadow buffer 00198 ret = lockImpl(offset, length, options); 00199 mIsLocked = true; 00200 } 00201 mLockStart = offset; 00202 mLockSize = length; 00203 return ret; 00204 } 00205 00210 void* lock(LockOptions options) 00211 { 00212 return this->lock(0, mSizeInBytes, options); 00213 } 00226 virtual void unlock(void) 00227 { 00228 assert(isLocked() && "Cannot unlock this buffer, it is not locked!"); 00229 00230 // If we used the shadow buffer this time... 00231 if (mUseShadowBuffer && mpShadowBuffer->isLocked()) 00232 { 00233 mpShadowBuffer->unlock(); 00234 // Potentially update the 'real' buffer from the shadow buffer 00235 _updateFromShadow(); 00236 } 00237 else 00238 { 00239 // Otherwise, unlock the real one 00240 unlockImpl(); 00241 mIsLocked = false; 00242 } 00243 00244 } 00245 00252 virtual void readData(size_t offset, size_t length, void* pDest) = 0; 00261 virtual void writeData(size_t offset, size_t length, const void* pSource, 00262 bool discardWholeBuffer = false) = 0; 00263 00274 virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, 00275 size_t dstOffset, size_t length, bool discardWholeBuffer = false) 00276 { 00277 const void *srcData = srcBuffer.lock( 00278 srcOffset, length, HBL_READ_ONLY); 00279 this->writeData(dstOffset, length, srcData, discardWholeBuffer); 00280 srcBuffer.unlock(); 00281 } 00282 00288 virtual void copyData(HardwareBuffer& srcBuffer) 00289 { 00290 size_t sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes()); 00291 copyData(srcBuffer, 0, 0, sz, true); 00292 } 00293 00295 virtual void _updateFromShadow(void) 00296 { 00297 if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate) 00298 { 00299 // Do this manually to avoid locking problems 00300 const void *srcData = mpShadowBuffer->lockImpl( 00301 mLockStart, mLockSize, HBL_READ_ONLY); 00302 // Lock with discard if the whole buffer was locked, otherwise normal 00303 LockOptions lockOpt; 00304 if (mLockStart == 0 && mLockSize == mSizeInBytes) 00305 lockOpt = HBL_DISCARD; 00306 else 00307 lockOpt = HBL_NORMAL; 00308 00309 void *destData = this->lockImpl( 00310 mLockStart, mLockSize, lockOpt); 00311 // Copy shadow to real 00312 memcpy(destData, srcData, mLockSize); 00313 this->unlockImpl(); 00314 mpShadowBuffer->unlockImpl(); 00315 mShadowUpdated = false; 00316 } 00317 } 00318 00320 size_t getSizeInBytes(void) const { return mSizeInBytes; } 00322 Usage getUsage(void) const { return mUsage; } 00324 bool isSystemMemory(void) const { return mSystemMemory; } 00326 bool hasShadowBuffer(void) const { return mUseShadowBuffer; } 00328 bool isLocked(void) const { 00329 return mIsLocked || (mUseShadowBuffer && mpShadowBuffer->isLocked()); 00330 } 00332 void suppressHardwareUpdate(bool suppress) { 00333 mSuppressHardwareUpdate = suppress; 00334 if (!suppress) 00335 _updateFromShadow(); 00336 } 00337 00338 00339 00340 00341 00342 }; 00345 } 00346 #endif 00347 00348
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:51