OgreHardwareBuffer.h
Go to the documentation of this file.
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2013 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#ifndef __HardwareBuffer__
#define __HardwareBuffer__
// Precompiler options
#include "OgrePrerequisites.h"
#include "OgreException.h"
namespace Ogre {
class _OgreExport HardwareBuffer : public BufferAlloc
{
public:
enum Usage
{
HBU_STATIC = 1,
HBU_DYNAMIC = 2,
HBU_WRITE_ONLY = 4,
HBU_DISCARDABLE = 8,
HBU_STATIC_WRITE_ONLY = 5,
HBU_DYNAMIC_WRITE_ONLY = 6,
HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE = 14
};
enum LockOptions
{
HBL_NORMAL,
HBL_DISCARD,
HBL_READ_ONLY,
HBL_NO_OVERWRITE,
HBL_WRITE_ONLY
};
protected:
size_t mSizeInBytes;
Usage mUsage;
bool mIsLocked;
size_t mLockStart;
size_t mLockSize;
bool mSystemMemory;
bool mUseShadowBuffer;
HardwareBuffer* mShadowBuffer;
bool mShadowUpdated;
bool mSuppressHardwareUpdate;
virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0;
virtual void unlockImpl(void) = 0;
public:
HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer)
: mUsage(usage), mIsLocked(false), mLockStart(0), mLockSize(0), mSystemMemory(systemMemory),
mUseShadowBuffer(useShadowBuffer), mShadowBuffer(NULL), mShadowUpdated(false),
mSuppressHardwareUpdate(false)
{
// If use shadow buffer, upgrade to WRITE_ONLY on hardware side
if (useShadowBuffer && usage == HBU_DYNAMIC)
{
mUsage = HBU_DYNAMIC_WRITE_ONLY;
}
else if (useShadowBuffer && usage == HBU_STATIC)
{
mUsage = HBU_STATIC_WRITE_ONLY;
}
}
virtual ~HardwareBuffer() {}
virtual void* lock(size_t offset, size_t length, LockOptions options)
{
assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
void* ret = NULL;
if ((length + offset) > mSizeInBytes)
{
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
"Lock request out of bounds.",
"HardwareBuffer::lock");
}
else if (mUseShadowBuffer)
{
if (options != HBL_READ_ONLY)
{
// we have to assume a read / write lock so we use the shadow buffer
// and tag for sync on unlock()
mShadowUpdated = true;
}
ret = mShadowBuffer->lock(offset, length, options);
}
else
{
// Lock the real buffer if there is no shadow buffer
ret = lockImpl(offset, length, options);
mIsLocked = true;
}
mLockStart = offset;
mLockSize = length;
return ret;
}
void* lock(LockOptions options)
{
return this->lock(0, mSizeInBytes, options);
}
virtual void unlock(void)
{
assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
// If we used the shadow buffer this time...
if (mUseShadowBuffer && mShadowBuffer->isLocked())
{
mShadowBuffer->unlock();
// Potentially update the 'real' buffer from the shadow buffer
_updateFromShadow();
}
else
{
// Otherwise, unlock the real one
unlockImpl();
mIsLocked = false;
}
}
virtual void readData(size_t offset, size_t length, void* pDest) = 0;
virtual void writeData(size_t offset, size_t length, const void* pSource,
bool discardWholeBuffer = false) = 0;
virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset,
size_t dstOffset, size_t length, bool discardWholeBuffer = false)
{
const void *srcData = srcBuffer.lock(
srcOffset, length, HBL_READ_ONLY);
this->writeData(dstOffset, length, srcData, discardWholeBuffer);
srcBuffer.unlock();
}
virtual void copyData(HardwareBuffer& srcBuffer)
{
size_t sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes());
copyData(srcBuffer, 0, 0, sz, true);
}
virtual void _updateFromShadow(void)
{
if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate)
{
// Do this manually to avoid locking problems
const void *srcData = mShadowBuffer->lockImpl(
mLockStart, mLockSize, HBL_READ_ONLY);
// Lock with discard if the whole buffer was locked, otherwise normal
LockOptions lockOpt;
if (mLockStart == 0 && mLockSize == mSizeInBytes)
lockOpt = HBL_DISCARD;
else
lockOpt = HBL_NORMAL;
void *destData = this->lockImpl(
mLockStart, mLockSize, lockOpt);
// Copy shadow to real
memcpy(destData, srcData, mLockSize);
this->unlockImpl();
mShadowBuffer->unlockImpl();
mShadowUpdated = false;
}
}
size_t getSizeInBytes(void) const { return mSizeInBytes; }
Usage getUsage(void) const { return mUsage; }
bool isSystemMemory(void) const { return mSystemMemory; }
bool hasShadowBuffer(void) const { return mUseShadowBuffer; }
bool isLocked(void) const {
return mIsLocked || (mUseShadowBuffer && mShadowBuffer->isLocked());
}
void suppressHardwareUpdate(bool suppress) {
mSuppressHardwareUpdate = suppress;
if (!suppress)
_updateFromShadow();
}
};
template <typename T> struct HardwareBufferLockGuard
{
HardwareBufferLockGuard(const T& p, HardwareBuffer::LockOptions options)
: pBuf(p)
{
pData = pBuf->lock(options);
}
HardwareBufferLockGuard(const T& p, size_t offset, size_t length, HardwareBuffer::LockOptions options)
: pBuf(p)
{
pData = pBuf->lock(offset, length, options);
}
~HardwareBufferLockGuard()
{
pBuf->unlock();
}
const T& pBuf;
void* pData;
};
}
#endif
Ogre::HardwareBuffer::lock
virtual void * lock(size_t offset, size_t length, LockOptions options)
Lock the buffer for (potentially) reading / writing.
Definition: OgreHardwareBuffer.h:183
Ogre::HardwareBuffer::HBL_READ_ONLY
Lock the buffer for reading only.
Definition: OgreHardwareBuffer.h:133
_OgreExport
#define _OgreExport
Definition: OgrePlatform.h:257
Ogre::HardwareBuffer::isLocked
bool isLocked(void) const
Returns whether or not this buffer is currently locked.
Definition: OgreHardwareBuffer.h:338
Ogre::HardwareBuffer::unlock
virtual void unlock(void)
Releases the lock on this buffer.
Definition: OgreHardwareBuffer.h:236
Ogre::HardwareBufferLockGuard::pData
void * pData
Definition: OgreHardwareBuffer.h:375
Ogre::HardwareBufferLockGuard::HardwareBufferLockGuard
HardwareBufferLockGuard(const T &p, size_t offset, size_t length, HardwareBuffer::LockOptions options)
Definition: OgreHardwareBuffer.h:364
Ogre::HardwareBuffer::mLockSize
size_t mLockSize
Definition: OgreHardwareBuffer.h:147
Ogre::HardwareBuffer::mSuppressHardwareUpdate
bool mSuppressHardwareUpdate
Definition: OgreHardwareBuffer.h:152
Ogre::HardwareBuffer::copyData
virtual void copyData(HardwareBuffer &srcBuffer, size_t srcOffset, size_t dstOffset, size_t length, bool discardWholeBuffer=false)
Copy data from another buffer into this one.
Definition: OgreHardwareBuffer.h:284
Ogre::HardwareBuffer::mShadowUpdated
bool mShadowUpdated
Definition: OgreHardwareBuffer.h:151
Ogre::HardwareBufferLockGuard::~HardwareBufferLockGuard
~HardwareBufferLockGuard()
Definition: OgreHardwareBuffer.h:369
Ogre::HardwareBuffer::lockImpl
virtual void * lockImpl(size_t offset, size_t length, LockOptions options)=0
Internal implementation of lock()
Ogre::HardwareBuffer::HBL_NO_OVERWRITE
As HBL_DISCARD, except the application guarantees not to overwrite any region of the buffer which has...
Definition: OgreHardwareBuffer.h:137
Ogre::HardwareBuffer::getUsage
Usage getUsage(void) const
Returns the Usage flags with which this buffer was created.
Definition: OgreHardwareBuffer.h:332
OgrePrerequisites.h
Ogre::HardwareBuffer::HardwareBuffer
HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer)
Constructor, to be called by HardwareBufferManager only.
Definition: OgreHardwareBuffer.h:161
Ogre::HardwareBuffer::isSystemMemory
bool isSystemMemory(void) const
Returns whether this buffer is held in system memory.
Definition: OgreHardwareBuffer.h:334
Ogre::HardwareBufferLockGuard::pBuf
const T & pBuf
Definition: OgreHardwareBuffer.h:374
Ogre::HardwareBuffer::Usage
Usage
Enums describing buffer usage; not mutually exclusive.
Definition: OgreHardwareBuffer.h:79
Ogre::HardwareBuffer
Abstract class defining common features of hardware buffers.
Definition: OgreHardwareBuffer.h:74
Ogre::HardwareBuffer::mShadowBuffer
HardwareBuffer * mShadowBuffer
Definition: OgreHardwareBuffer.h:150
Ogre::HardwareBuffer::mLockStart
size_t mLockStart
Definition: OgreHardwareBuffer.h:146
Ogre::HardwareBuffer::unlockImpl
virtual void unlockImpl(void)=0
Internal implementation of unlock()
Ogre::HardwareBufferLockGuard
Locking helper.
Definition: OgreHardwareBuffer.h:357
Ogre::HardwareBuffer::HBL_NORMAL
Normal mode, ie allows read/write and contents are preserved.
Definition: OgreHardwareBuffer.h:124
Ogre::HardwareBuffer::LockOptions
LockOptions
Locking options.
Definition: OgreHardwareBuffer.h:121
OGRE_EXCEPT
#define OGRE_EXCEPT(num, desc, src)
Definition: OgreException.h:334
Ogre::Exception::ERR_INVALIDPARAMS
Definition: OgreException.h:103
Ogre::HardwareBuffer::hasShadowBuffer
bool hasShadowBuffer(void) const
Returns whether this buffer has a system memory shadow for quicker reading.
Definition: OgreHardwareBuffer.h:336
Ogre
Definition: OgreAndroidLogListener.h:34
Ogre::HardwareBuffer::mSizeInBytes
size_t mSizeInBytes
Definition: OgreHardwareBuffer.h:143
OgreException.h
Ogre::HardwareBuffer::suppressHardwareUpdate
void suppressHardwareUpdate(bool suppress)
Pass true to suppress hardware upload of shadow buffer changes.
Definition: OgreHardwareBuffer.h:342
Ogre::HardwareBuffer::mSystemMemory
bool mSystemMemory
Definition: OgreHardwareBuffer.h:148
Ogre::HardwareBuffer::mUsage
Usage mUsage
Definition: OgreHardwareBuffer.h:144
Ogre::HardwareBufferLockGuard::HardwareBufferLockGuard
HardwareBufferLockGuard(const T &p, HardwareBuffer::LockOptions options)
Definition: OgreHardwareBuffer.h:359
Ogre::HardwareBuffer::getSizeInBytes
size_t getSizeInBytes(void) const
Returns the size of this buffer in bytes.
Definition: OgreHardwareBuffer.h:330
Ogre::HardwareBuffer::mIsLocked
bool mIsLocked
Definition: OgreHardwareBuffer.h:145
Ogre::HardwareBuffer::copyData
virtual void copyData(HardwareBuffer &srcBuffer)
Copy all data from another buffer into this one.
Definition: OgreHardwareBuffer.h:298
Ogre::HardwareBuffer::HBL_DISCARD
Discards the entire buffer while locking; this allows optimisation to be performed because synchronis...
Definition: OgreHardwareBuffer.h:129
Ogre::HardwareBuffer::lock
void * lock(LockOptions options)
Lock the entire buffer for (potentially) reading / writing.
Definition: OgreHardwareBuffer.h:220
Ogre::HardwareBuffer::mUseShadowBuffer
bool mUseShadowBuffer
Definition: OgreHardwareBuffer.h:149
Ogre::AllocatedObject
Superclass for all objects that wish to use custom memory allocators when their new / delete operator...
Definition: OgreMemoryAllocatedObject.h:58
Ogre::HardwareBuffer::_updateFromShadow
virtual void _updateFromShadow(void)
Updates the real buffer from the shadow buffer, if required.
Definition: OgreHardwareBuffer.h:305
Ogre::HardwareBuffer::~HardwareBuffer
virtual ~HardwareBuffer()
Definition: OgreHardwareBuffer.h:176

Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.