Reworking IRenderTarget interface to avoid constant memory allocations.

setTexture functions for single textures (more or less the usual case) IRenderTarget no longer need memory allocations 
on each call.
Also calling IRenderTarget::setTexture with a nullpointer no longer sets a rendertarget with an array which contains a single nullpointer but clears the array instead.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6243 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2021-08-26 16:45:20 +00:00
parent 075c64bebb
commit d03881b83a
8 changed files with 51 additions and 33 deletions

@ -48,6 +48,12 @@ namespace video
return DepthStencil;
}
//! Returns an array of active surface for cube textures
const core::array<E_CUBE_SURFACE>& getCubeSurfaces() const
{
return CubeSurfaces;
}
//! Set multiple textures.
/** Set multiple textures for the render target.
\param texture Array of texture objects. These textures are used for a color outputs.
@ -55,27 +61,35 @@ namespace video
or depth-stencil buffer.
\param cubeSurfaces When rendering to cube textures, set the surface to be used for each texture. Can be empty otherwise.
*/
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces = core::array<E_CUBE_SURFACE>()) = 0;
void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces = core::array<E_CUBE_SURFACE>())
{
setTextures(texture.const_pointer(), texture.size(), depthStencil, cubeSurfaces.const_pointer(), cubeSurfaces.size());
}
//! Set one texture.
//! Set one texture
void setTexture(ITexture* texture, ITexture* depthStencil)
{
core::array<ITexture*> textureArray(1);
textureArray.push_back(texture);
setTexture(textureArray, depthStencil);
if ( texture )
{
setTextures(&texture, 1, depthStencil);
}
else
{
setTextures(0, 0, depthStencil);
}
}
//! Set one cube surface texture.
void setTexture(ITexture* texture, ITexture* depthStencil, E_CUBE_SURFACE cubeSurface)
{
core::array<ITexture*> textureArray(1);
textureArray.push_back(texture);
core::array<E_CUBE_SURFACE> cubeSurfaces(1);
cubeSurfaces.push_back(cubeSurface);
setTexture(textureArray, depthStencil, cubeSurfaces);
if ( texture )
{
setTextures(&texture, 1, depthStencil, &cubeSurface, 1);
}
else
{
setTextures(0, 0, depthStencil, &cubeSurface, 1);
}
}
//! Get driver type of render target.
@ -86,6 +100,10 @@ namespace video
protected:
//! Set multiple textures.
// NOTE: working with pointers instead of arrays to avoid unnecessary memory allocations for the single textures case
virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces=0, u32 numCubeSurfaces=0) = 0;
//! Textures assigned to render target.
core::array<ITexture*> Textures;

@ -49,17 +49,17 @@ namespace irr
DepthStencil->drop();
}
void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& textures, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces)
void CD3D9RenderTarget::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
{
bool needSizeUpdate = false;
// Set color attachments.
if ((Textures != textures) || (CubeSurfaces != cubeSurfaces))
if (!Textures.equals(textures, numTextures) || !CubeSurfaces.equals(cubeSurfaces, numCubeSurfaces))
{
needSizeUpdate = true;
CubeSurfaces = cubeSurfaces; // TODO: we can probably avoid some memory allocating/de-allocating if _only_ CubeSurfaces change.
CubeSurfaces.set_data(cubeSurfaces, numCubeSurfaces); // TODO: we can probably avoid some memory allocating/de-allocating if _only_ CubeSurfaces change.
if (textures.size() > Driver->ActiveRenderTarget.size())
if (numTextures > Driver->ActiveRenderTarget.size())
{
core::stringc message = "This GPU supports up to ";
message += Driver->ActiveRenderTarget.size();
@ -68,7 +68,7 @@ namespace irr
os::Printer::log(message.c_str(), ELL_WARNING);
}
const u32 size = core::min_(textures.size(), static_cast<u32>(Driver->ActiveRenderTarget.size()));
const u32 size = core::min_(numTextures, static_cast<u32>(Driver->ActiveRenderTarget.size()));
for (u32 i = 0; i < Surfaces.size(); ++i)
{

@ -29,7 +29,7 @@ namespace irr
CD3D9RenderTarget(CD3D9Driver* driver);
virtual ~CD3D9RenderTarget();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_;
virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) _IRR_OVERRIDE_;
const core::dimension2d<u32>& getSize() const;

@ -58,18 +58,18 @@ public:
DepthStencil->drop();
}
virtual void setTexture(const core::array<ITexture*>& textures, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_
virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) _IRR_OVERRIDE_
{
bool needSizeUpdate = false;
// Set color attachments.
if ((Textures != textures) || (CubeSurfaces != cubeSurfaces))
if (!Textures.equals(textures, numTextures) || !CubeSurfaces.equals(cubeSurfaces, numCubeSurfaces))
{
needSizeUpdate = true;
core::array<ITexture*> prevTextures(Textures);
if (textures.size() > static_cast<u32>(ColorAttachment))
if (numTextures > static_cast<u32>(ColorAttachment))
{
core::stringc message = "This GPU supports up to ";
message += static_cast<u32>(ColorAttachment);
@ -78,7 +78,7 @@ public:
os::Printer::log(message.c_str(), ELL_WARNING);
}
Textures.set_used(core::min_(textures.size(), static_cast<u32>(ColorAttachment)));
Textures.set_used(core::min_(numTextures, static_cast<u32>(ColorAttachment)));
for (u32 i = 0; i < Textures.size(); ++i)
{
@ -111,9 +111,9 @@ public:
RequestTextureUpdate = true;
}
if (CubeSurfaces != cubeSurfaces)
if (!CubeSurfaces.equals(cubeSurfaces, numCubeSurfaces))
{
CubeSurfaces = cubeSurfaces;
CubeSurfaces.set_data(cubeSurfaces, numCubeSurfaces);
RequestTextureUpdate = true;
}

@ -129,15 +129,15 @@ CSoftwareRenderTarget::~CSoftwareRenderTarget()
Textures[0]->drop();
}
void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& textures, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces)
void CSoftwareRenderTarget::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
{
if (Textures != textures)
if (!Textures.equals(textures, numTextures))
{
ITexture* prevTexture = Textures[0];
bool textureDetected = false;
for (u32 i = 0; i < textures.size(); ++i)
for (u32 i = 0; i < numTextures; ++i)
{
if (textures[i] && textures[i]->getDriverType() == EDT_SOFTWARE)
{

@ -57,7 +57,7 @@ public:
CSoftwareRenderTarget(CSoftwareDriver* driver);
virtual ~CSoftwareRenderTarget();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_;
virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) _IRR_OVERRIDE_;
ITexture* getTexture() const;

@ -395,15 +395,15 @@ CSoftwareRenderTarget2::~CSoftwareRenderTarget2()
Textures[0]->drop();
}
void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& textures, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces)
void CSoftwareRenderTarget2::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
{
if (Textures != textures)
if (!Textures.equals(textures, numTextures))
{
ITexture* prevTexture = Textures[0];
bool textureDetected = false;
for (u32 i = 0; i < textures.size(); ++i)
for (u32 i = 0; i < numTextures; ++i)
{
if (textures[i] && textures[i]->getDriverType() == EDT_BURNINGSVIDEO)
{

@ -166,7 +166,7 @@ public:
CSoftwareRenderTarget2(CBurningVideoDriver* driver);
virtual ~CSoftwareRenderTarget2();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_;
virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
E_DRIVER_TYPE DriverType;