Historique des modifications - Message

Message #11692

Sujet: chargement texture différé pour le multithreading


TypeDateAuteurContenu
Création du message09-08-2015 18:38:09Magun
Salut personnesmile
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

OptionsLiens officielsCaractéristiquesStatistiquesCommunauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1441 sujets
11339 messages
Dernier membre inscrit: Saidov17
257 invités en ligne
membre en ligne: -
RSS Feed