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
This commit is contained in:
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 /** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels pixels. After lock() has been called and all operations on the pixels
are done, you must call unlock(). 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 \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. */ 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. //! 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; virtual void unlock() = 0;
//! Returns original size of the texture. //! Returns original size of the texture.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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