Allow read-only locking of textures, which may improve the performance due to optimized access to the data and skipped updates when unlocking.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1456 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2008-08-07 11:59:42 +00:00
parent d3491565ed
commit f25d01b31b
11 changed files with 43 additions and 33 deletions

View File

@ -111,12 +111,17 @@ public:
/** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels
are done, you must call unlock().
Locks are not accumulating, hence one unlock will do for an arbitrary
number of previous locks.
\param readOnly Specifies that no changes to the locked texture are
made. Unspecified behavior will arise if still write access happens.
\return Returns a pointer to the pixel data. The format of the pixel can
be determinated by using getColorFormat(). NULL is returned, if
be determined by using getColorFormat(). 0 is returned, if
the texture cannot be locked. */
virtual void* lock() = 0;
virtual void* lock(bool readOnly = false) = 0;
//! Unlock function. Must be called after a lock() to the texture.
/** One should avoid to call unlock more than once before another lock. */
virtual void unlock() = 0;
//! Returns original size of the texture.

View File

@ -217,7 +217,7 @@ bool CD3D8Texture::copyTexture(video::IImage* image)
//! lock function
void* CD3D8Texture::lock()
void* CD3D8Texture::lock(bool readOnly)
{
if (!Texture)
return 0;
@ -226,7 +226,7 @@ void* CD3D8Texture::lock()
D3DLOCKED_RECT rect;
if(!IsRenderTarget)
{
hr = Texture->LockRect(0, &rect, 0, 0);
hr = Texture->LockRect(0, &rect, 0, readOnly?D3DLOCK_READONLY:0);
}
else
{
@ -242,21 +242,21 @@ void* CD3D8Texture::lock()
}
}
IDirect3DSurface8 *surface = NULL;
IDirect3DSurface8 *surface = 0;
hr = Texture->GetSurfaceLevel(0, &surface);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
hr = Device->CopyRects(surface, NULL, 0, RTTSurface, NULL);
hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0);
surface->Release();
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
hr = RTTSurface->LockRect(&rect, NULL, 0);
hr = RTTSurface->LockRect(&rect, 0, readOnly?D3DLOCK_READONLY:0);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
@ -274,7 +274,6 @@ void* CD3D8Texture::lock()
}
//! unlock function
void CD3D8Texture::unlock()
{

View File

@ -37,7 +37,7 @@ public:
virtual ~CD3D8Texture();
//! lock function
virtual void* lock();
virtual void* lock(bool readOnly = false);
//! unlock function
virtual void unlock();

View File

@ -424,7 +424,7 @@ bool CD3D9Texture::copyTexture(IImage * image)
//! lock function
void* CD3D9Texture::lock()
void* CD3D9Texture::lock(bool readOnly)
{
if (!Texture)
return 0;
@ -433,7 +433,7 @@ void* CD3D9Texture::lock()
D3DLOCKED_RECT rect;
if(!IsRenderTarget)
{
hr = Texture->LockRect(0, &rect, 0, 0);
hr = Texture->LockRect(0, &rect, 0, readOnly?D3DLOCK_READONLY:0);
}
else
{
@ -441,7 +441,7 @@ void* CD3D9Texture::lock()
Texture->GetLevelDesc(0, &desc);
if (!RTTSurface)
{
hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, NULL);
hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, 0);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
@ -449,7 +449,7 @@ void* CD3D9Texture::lock()
}
}
IDirect3DSurface9 *surface = NULL;
IDirect3DSurface9 *surface = 0;
hr = Texture->GetSurfaceLevel(0, &surface);
if (FAILED(hr))
{
@ -463,7 +463,7 @@ void* CD3D9Texture::lock()
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
hr = RTTSurface->LockRect(&rect, NULL, 0);
hr = RTTSurface->LockRect(&rect, 0, readOnly?D3DLOCK_READONLY:0);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
@ -481,7 +481,6 @@ void* CD3D9Texture::lock()
}
//! unlock function
void CD3D9Texture::unlock()
{

View File

@ -36,7 +36,7 @@ public:
virtual ~CD3D9Texture();
//! lock function
virtual void* lock();
virtual void* lock(bool readOnly = false);
//! unlock function
virtual void unlock();

View File

@ -546,7 +546,7 @@ namespace video
{
SDummyTexture(const char* name) : ITexture(name), size(0,0) {};
virtual void* lock() { return 0; };
virtual void* lock(bool readOnly = false) { return 0; };
virtual void unlock(){}
virtual const core::dimension2d<s32>& getOriginalSize() const { return size; }
virtual const core::dimension2d<s32>& getSize() const { return size; }

View File

@ -27,11 +27,12 @@ static bool checkFBOStatus(COpenGLDriver* Driver);
//! constructor for usual textures
COpenGLTexture::COpenGLTexture(IImage* origImage, const char* name, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
PixelType(GL_UNSIGNED_BYTE),
ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0),
HasMipMaps(true), IsRenderTarget(false), AutomaticMipmapUpdate(false), UseStencil(false)
: ITexture(name), Driver(driver), Image(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
PixelType(GL_UNSIGNED_BYTE),
ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0),
HasMipMaps(true), IsRenderTarget(false), AutomaticMipmapUpdate(false),
UseStencil(false), ReadOnlyLock(false)
{
#ifdef _DEBUG
setDebugName("COpenGLTexture");
@ -53,11 +54,12 @@ COpenGLTexture::COpenGLTexture(const core::dimension2d<s32>& size,
const char* name,
COpenGLDriver* driver,
bool useStencil)
: ITexture(name), ImageSize(size), Driver(driver), Image(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA),
PixelType(GL_UNSIGNED_BYTE),
ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0),
HasMipMaps(false), IsRenderTarget(true), AutomaticMipmapUpdate(false), UseStencil(useStencil)
: ITexture(name), ImageSize(size), Driver(driver), Image(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA),
PixelType(GL_UNSIGNED_BYTE),
ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0),
HasMipMaps(false), IsRenderTarget(true), AutomaticMipmapUpdate(false),
UseStencil(useStencil), ReadOnlyLock(false)
{
#ifdef _DEBUG
setDebugName("COpenGLTexture_FBO");
@ -375,8 +377,10 @@ inline s32 COpenGLTexture::getTextureSizeFromSurfaceSize(s32 size) const
//! lock function
void* COpenGLTexture::lock()
void* COpenGLTexture::lock(bool readOnly)
{
ReadOnlyLock |= readOnly;
if (!Image)
Image = new CImage(ECF_A8R8G8B8, ImageSize);
if (IsRenderTarget)
@ -432,7 +436,9 @@ void* COpenGLTexture::lock()
void COpenGLTexture::unlock()
{
Image->unlock();
copyTexture(false);
if (!ReadOnlyLock)
copyTexture(false);
ReadOnlyLock = false;
}

View File

@ -56,7 +56,7 @@ public:
virtual ~COpenGLTexture();
//! lock function
virtual void* lock();
virtual void* lock(bool readOnly = false);
//! unlock function
virtual void unlock();
@ -133,6 +133,7 @@ private:
bool IsRenderTarget;
bool AutomaticMipmapUpdate;
bool UseStencil;
bool ReadOnlyLock;
};

View File

@ -59,7 +59,7 @@ CSoftwareTexture::~CSoftwareTexture()
//! lock function
void* CSoftwareTexture::lock()
void* CSoftwareTexture::lock(bool readOnly)
{
return Image->lock();
}

View File

@ -27,7 +27,7 @@ public:
virtual ~CSoftwareTexture();
//! lock function
virtual void* lock();
virtual void* lock(bool readOnly = false);
//! unlock function
virtual void unlock();

View File

@ -29,7 +29,7 @@ public:
virtual ~CSoftwareTexture2();
//! lock function
virtual void* lock()
virtual void* lock(bool readOnly = false)
{
return MipMap[MipMapLOD]->lock();
}