Commit f25d01b3 authored by hybrid's avatar hybrid

Allow read-only locking of textures, which may improve the performance due to...

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
parent d3491565
...@@ -111,12 +111,17 @@ public: ...@@ -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.
......
...@@ -217,7 +217,7 @@ bool CD3D8Texture::copyTexture(video::IImage* image) ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -274,7 +274,6 @@ void* CD3D8Texture::lock()
} }
//! unlock function //! unlock function
void CD3D8Texture::unlock() void CD3D8Texture::unlock()
{ {
......
...@@ -37,7 +37,7 @@ public: ...@@ -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();
......
...@@ -424,7 +424,7 @@ bool CD3D9Texture::copyTexture(IImage * image) ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -481,7 +481,6 @@ void* CD3D9Texture::lock()
} }
//! unlock function //! unlock function
void CD3D9Texture::unlock() void CD3D9Texture::unlock()
{ {
......
...@@ -36,7 +36,7 @@ public: ...@@ -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();
......
...@@ -546,7 +546,7 @@ namespace video ...@@ -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; }
......
...@@ -27,11 +27,12 @@ static bool checkFBOStatus(COpenGLDriver* Driver); ...@@ -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, ...@@ -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 ...@@ -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() ...@@ -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;
} }
......
...@@ -56,7 +56,7 @@ public: ...@@ -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: ...@@ -133,6 +133,7 @@ private:
bool IsRenderTarget; bool IsRenderTarget;
bool AutomaticMipmapUpdate; bool AutomaticMipmapUpdate;
bool UseStencil; bool UseStencil;
bool ReadOnlyLock;
}; };
......
...@@ -59,7 +59,7 @@ CSoftwareTexture::~CSoftwareTexture() ...@@ -59,7 +59,7 @@ CSoftwareTexture::~CSoftwareTexture()
//! lock function //! lock function
void* CSoftwareTexture::lock() void* CSoftwareTexture::lock(bool readOnly)
{ {
return Image->lock(); return Image->lock();
} }
......
...@@ -27,7 +27,7 @@ public: ...@@ -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();
......
...@@ -29,7 +29,7 @@ public: ...@@ -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();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment