From d03881b83a58a564612f3515647ba1057ebe6c06 Mon Sep 17 00:00:00 2001 From: cutealien Date: Thu, 26 Aug 2021 16:45:20 +0000 Subject: [PATCH] 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 --- include/IRenderTarget.h | 44 ++++++++++++++++------- source/Irrlicht/CD3D9RenderTarget.cpp | 10 +++--- source/Irrlicht/CD3D9RenderTarget.h | 2 +- source/Irrlicht/COpenGLCoreRenderTarget.h | 12 +++---- source/Irrlicht/CSoftwareTexture.cpp | 6 ++-- source/Irrlicht/CSoftwareTexture.h | 2 +- source/Irrlicht/CSoftwareTexture2.cpp | 6 ++-- source/Irrlicht/CSoftwareTexture2.h | 2 +- 8 files changed, 51 insertions(+), 33 deletions(-) diff --git a/include/IRenderTarget.h b/include/IRenderTarget.h index b95f7019..b6a046a8 100644 --- a/include/IRenderTarget.h +++ b/include/IRenderTarget.h @@ -48,6 +48,12 @@ namespace video return DepthStencil; } + //! Returns an array of active surface for cube textures + const core::array& 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& texture, ITexture* depthStencil, const core::array& cubeSurfaces = core::array()) = 0; + void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces = core::array()) + { + 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 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 textureArray(1); - textureArray.push_back(texture); - - core::array 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 Textures; diff --git a/source/Irrlicht/CD3D9RenderTarget.cpp b/source/Irrlicht/CD3D9RenderTarget.cpp index f39fb519..4e30400e 100644 --- a/source/Irrlicht/CD3D9RenderTarget.cpp +++ b/source/Irrlicht/CD3D9RenderTarget.cpp @@ -49,17 +49,17 @@ namespace irr DepthStencil->drop(); } - void CD3D9RenderTarget::setTexture(const core::array& textures, ITexture* depthStencil, const core::array& 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(Driver->ActiveRenderTarget.size())); + const u32 size = core::min_(numTextures, static_cast(Driver->ActiveRenderTarget.size())); for (u32 i = 0; i < Surfaces.size(); ++i) { diff --git a/source/Irrlicht/CD3D9RenderTarget.h b/source/Irrlicht/CD3D9RenderTarget.h index f473ce99..680f2b54 100644 --- a/source/Irrlicht/CD3D9RenderTarget.h +++ b/source/Irrlicht/CD3D9RenderTarget.h @@ -29,7 +29,7 @@ namespace irr CD3D9RenderTarget(CD3D9Driver* driver); virtual ~CD3D9RenderTarget(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& 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& getSize() const; diff --git a/source/Irrlicht/COpenGLCoreRenderTarget.h b/source/Irrlicht/COpenGLCoreRenderTarget.h index 7432b0f7..247d2db5 100644 --- a/source/Irrlicht/COpenGLCoreRenderTarget.h +++ b/source/Irrlicht/COpenGLCoreRenderTarget.h @@ -58,18 +58,18 @@ public: DepthStencil->drop(); } - virtual void setTexture(const core::array& textures, ITexture* depthStencil, const core::array& 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 prevTextures(Textures); - if (textures.size() > static_cast(ColorAttachment)) + if (numTextures > static_cast(ColorAttachment)) { core::stringc message = "This GPU supports up to "; message += static_cast(ColorAttachment); @@ -78,7 +78,7 @@ public: os::Printer::log(message.c_str(), ELL_WARNING); } - Textures.set_used(core::min_(textures.size(), static_cast(ColorAttachment))); + Textures.set_used(core::min_(numTextures, static_cast(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; } diff --git a/source/Irrlicht/CSoftwareTexture.cpp b/source/Irrlicht/CSoftwareTexture.cpp index 11eb8978..4d36a2a6 100644 --- a/source/Irrlicht/CSoftwareTexture.cpp +++ b/source/Irrlicht/CSoftwareTexture.cpp @@ -129,15 +129,15 @@ CSoftwareRenderTarget::~CSoftwareRenderTarget() Textures[0]->drop(); } -void CSoftwareRenderTarget::setTexture(const core::array& textures, ITexture* depthStencil, const core::array& 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) { diff --git a/source/Irrlicht/CSoftwareTexture.h b/source/Irrlicht/CSoftwareTexture.h index 5d6d97e4..e67c50f8 100644 --- a/source/Irrlicht/CSoftwareTexture.h +++ b/source/Irrlicht/CSoftwareTexture.h @@ -57,7 +57,7 @@ public: CSoftwareRenderTarget(CSoftwareDriver* driver); virtual ~CSoftwareRenderTarget(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& 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; diff --git a/source/Irrlicht/CSoftwareTexture2.cpp b/source/Irrlicht/CSoftwareTexture2.cpp index 254c6315..1dff8c5c 100644 --- a/source/Irrlicht/CSoftwareTexture2.cpp +++ b/source/Irrlicht/CSoftwareTexture2.cpp @@ -395,15 +395,15 @@ CSoftwareRenderTarget2::~CSoftwareRenderTarget2() Textures[0]->drop(); } -void CSoftwareRenderTarget2::setTexture(const core::array& textures, ITexture* depthStencil, const core::array& 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) { diff --git a/source/Irrlicht/CSoftwareTexture2.h b/source/Irrlicht/CSoftwareTexture2.h index 37bd1c7d..5f64ee02 100644 --- a/source/Irrlicht/CSoftwareTexture2.h +++ b/source/Irrlicht/CSoftwareTexture2.h @@ -166,7 +166,7 @@ public: CSoftwareRenderTarget2(CBurningVideoDriver* driver); virtual ~CSoftwareRenderTarget2(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& 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;