Historique des modifications - Message

Message #11692

Sujet: chargement texture différé pour le multithreading


Type Date Auteur Contenu
Création du message 09-08-2015 18:38:09 Magun
Salut personne smile
bon voila l'autre jours j'ai poster un topic sur le chargement des scenes en thread séparé
mais bon on n'a pas vraiement regarder de prêt a ce que j'avais fait comme code d'example !

du coup j'ai fait un petit patch pour faire ça

Index: include/IVideoDriver.h
===================================================================
--- include/IVideoDriver.h	(revision 5114)
+++ include/IVideoDriver.h	(working copy)
@@ -19,6 +19,7 @@
 #include "EDriverTypes.h"
 #include "EDriverFeatures.h"
 #include "SExposedVideoData.h"
+#include "IImage.h"
 
 namespace irr
 {
@@ -467,7 +468,7 @@
 		The value is a safe approximation, i.e. can be larger than the
 		actual value of pixels. */
 		virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const =0;
-		
+
 		//! Create render target.
 		virtual IRenderTarget* addRenderTarget() = 0;
 
@@ -1449,6 +1450,19 @@
 		*/
 		virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN,
 				void* dP, ECOLOR_FORMAT dF) const =0;
+
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */
+    virtual void setDeferredTextureLoader(bool) = 0;
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */
+    virtual bool useDeferredTextureLoader() const = 0;
 	};
 
 } // end namespace video
Index: source/Irrlicht/CNullDriver.cpp
===================================================================
--- source/Irrlicht/CNullDriver.cpp	(revision 5114)
+++ source/Irrlicht/CNullDriver.cpp	(working copy)
@@ -23,6 +23,60 @@
 namespace video
 {
 
+    FakeTexture::FakeTexture(irr::video::IVideoDriver *driver, IImage* surface,
+        const io::path& name, void* mipmapData) :
+        ITexture(name), Image(surface), MipData(mipmapData), Driver(driver)
+    {
+        Image->grab();
+    }
+    FakeTexture::~FakeTexture()
+    {
+        // Image droped when this object is transformed to a driver dependent texture
+    }
+    void* FakeTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) _IRR_OVERRIDE_
+    {
+        return Image->lock();
+    }
+    void FakeTexture::unlock() _IRR_OVERRIDE_
+    {
+        return Image->unlock();
+    }
+    void FakeTexture::regenerateMipMapLevels(void* mipmapData)
+    {
+    }
+    const core::dimension2d<u32>& FakeTexture::getOriginalSize() const
+    {
+      return Image->getDimension();
+    }
+    const core::dimension2d<u32>& FakeTexture::getSize() const
+    {
+      return Image->getDimension();
+    }
+    E_DRIVER_TYPE FakeTexture::getDriverType() const
+    {
+      return Driver->getDriverType();
+    };
+    ECOLOR_FORMAT FakeTexture::getColorFormat() const
+    {
+      return Image->getColorFormat();
+    }
+    u32 FakeTexture::getPitch() const
+    {
+      return Image->getPitch();
+    }
+    bool FakeTexture::hasMipMaps() const
+    {
+      return MipData;
+    }
+    bool FakeTexture::hasAlpha() const
+    {
+      return true; /* ??? */
+    }
+    bool FakeTexture::isRenderTarget() const
+    {
+      return false;
+    }
+
 //! creates a loader which is able to load windows bitmaps
 IImageLoader* createImageLoaderBMP();
 
@@ -85,7 +139,7 @@
 CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
 	: SharedRenderTarget(0), CurrentRenderTarget(0), CurrentRenderTargetSize(0, 0), FileSystem(io), MeshManipulator(0),
 	ViewPort(0, 0, 0, 0), ScreenSize(screenSize), PrimitivesDrawn(0), MinVertexCountForVBO(500),
-	TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
+	TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false), DeferredLoader(false)
 {
 	#ifdef _DEBUG
 	setDebugName("CNullDriver");
@@ -626,6 +680,25 @@
 }
 
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/
+void CNullDriver::setDeferredTextureLoader(bool i)
+{
+    DeferredLoader = i;
+}
+
+/**
+return the current state of "DefferedTextureLoader"
+*/
+bool CNullDriver::useDeferredTextureLoader() const
+{
+    return DeferredLoader;
+}
+
 //! set a render target
 bool CNullDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, bool clearBackBuffer,
 	bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
Index: source/Irrlicht/CNullDriver.h
===================================================================
--- source/Irrlicht/CNullDriver.h	(revision 5114)
+++ source/Irrlicht/CNullDriver.h	(working copy)
@@ -38,6 +38,44 @@
 	class IImageLoader;
 	class IImageWriter;
 
+
+  class IVideoDriver;
+
+  class FakeTexture : public ITexture
+  {
+  public:
+    FakeTexture(irr::video::IVideoDriver *driver, IImage* surface,
+        const io::path& name, void* mipmapData);
+
+    virtual ~FakeTexture();
+
+    virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_;
+
+    virtual void unlock() _IRR_OVERRIDE_;
+
+    virtual void regenerateMipMapLevels(void* mipmapData = 0);
+
+    virtual const core::dimension2d<u32>& getOriginalSize() const;
+
+    virtual const core::dimension2d<u32>& getSize() const;
+
+    virtual E_DRIVER_TYPE getDriverType() const;
+
+    virtual ECOLOR_FORMAT getColorFormat() const;
+
+    virtual u32 getPitch() const;
+
+    virtual bool hasMipMaps() const;
+
+    virtual bool hasAlpha() const;
+
+    virtual bool isRenderTarget() const;
+  public:
+    IImage* Image;
+    void* MipData;
+    IVideoDriver* Driver;
+  };
+
 	class CNullDriver : public IVideoDriver, public IGPUProgrammingServices
 	{
 	public:
@@ -678,6 +716,19 @@
 				const c8* name=0);
 
 		virtual bool checkDriverReset() _IRR_OVERRIDE_ {return false;}
+
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */
+    virtual void setDeferredTextureLoader(bool);
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */
+    virtual bool useDeferredTextureLoader() const;
 	protected:
 
 		//! deletes all textures
@@ -880,6 +931,9 @@
 		bool AllowZWriteOnTransparent;
 
 		bool FeatureEnabled[video::EVDF_COUNT];
+    bool DeferredLoader;
+
+    core::list<FakeTexture*> CachedDefferedLoader;
 	};
 
 } // end namespace video
Index: source/Irrlicht/COpenGLDriver.cpp
===================================================================
--- source/Irrlicht/COpenGLDriver.cpp	(revision 5114)
+++ source/Irrlicht/COpenGLDriver.cpp	(working copy)
@@ -2492,7 +2492,7 @@
 	else if (texture->getDriverType() != EDT_OPENGL)
 	{
 		CurrentTexture.set(stage, 0);
-		os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
+		//os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
 		return false;
 	}
 
@@ -2549,10 +2549,49 @@
 //! returns a device dependent texture from a software surface (IImage)
 video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
 {
-	return new COpenGLTexture(surface, name, mipmapData, this);
+    if(DeferredLoader)
+    {
+        //! sizeof(FakeTexture) < sizeof(COpenGLTexture)
+        video::FakeTexture *tmp = (FakeTexture*) ::operator new (sizeof(COpenGLTexture));
+        new ((void*)tmp) FakeTexture(this, surface, name, mipmapData);
+        CachedDefferedLoader.push_back(tmp);
+        return tmp;
+    }
+    return new COpenGLTexture(surface, name, mipmapData, this);
 }
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/
+void COpenGLDriver::setDeferredTextureLoader(bool i)
+{
+    CNullDriver::setDeferredTextureLoader(i);
+    if(!i)
+    {
+        os::Printer::log("load deferred texture", ELL_WARNING);
 
+        for(core::list<FakeTexture*>::Iterator it = CachedDefferedLoader.begin();
+            it != CachedDefferedLoader.end(); ++it)
+        {
+            video::FakeTexture *tmp = *it;
+
+            IImage* Image = tmp->Image;
+            void* MipData = tmp->MipData;
+            const io::SNamedPath& name = tmp->getName();
+
+            tmp->~FakeTexture();
+
+            new ((void*)tmp) COpenGLTexture(Image, name, MipData, this);
+            Image->drop();
+        }
+        CachedDefferedLoader.clear();
+    }
+}
+
+
 //! Sets a material. All 3d drawing functions draw geometry now using this material.
 void COpenGLDriver::setMaterial(const SMaterial& material)
 {
Index: source/Irrlicht/COpenGLDriver.h
===================================================================
--- source/Irrlicht/COpenGLDriver.h	(revision 5114)
+++ source/Irrlicht/COpenGLDriver.h	(working copy)
@@ -425,6 +425,13 @@
 		//! Get bridge calls.
 		COpenGLCallBridge* getBridgeCalls() const;
 
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */
+    virtual void setDeferredTextureLoader(bool);
 	private:
 
 		bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);

et est donc utiliser de cette façon

Code c++ :



bool loading = true;
 
loadScreen.setVisible(true);
driver->setDeferredTextureLoader(true);
 
task = std::async(std::launch::async, [&]{
    smgr->loadScene("......");
    loading = false;
});
// then in your loading class or main while do
if(!loading)
{
    loadScreen.setVisible(false);
    driver->setDeferredTextureLoader(false);
    switchToGameState();
}


http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=50900&p=294720#p294720

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
157 invités en ligne
membre en ligne: -
RSS Feed