ソースを参照

Merge pull request #2892 from runforu/gltf_memory_leak

Fix: gltf exporting memory leak
Kim Kulling 5 年 前
コミット
651c2ef5fe

+ 3 - 1
code/glTF/glTFAsset.inl

@@ -688,7 +688,9 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
     }
     else { // text file: will be stored as a data uri
-        this->mData.reset(data);
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
         this->mDataLength = length;
     }
 }

+ 4 - 5
code/glTF/glTFExporter.cpp

@@ -100,17 +100,16 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
 {
     aiScene* sceneCopy_tmp;
     SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
-    aiScene *sceneCopy(sceneCopy_tmp);
 
     SplitLargeMeshesProcess_Triangle tri_splitter;
     tri_splitter.SetLimit(0xffff);
-    tri_splitter.Execute(sceneCopy);
+    tri_splitter.Execute(sceneCopy_tmp);
 
     SplitLargeMeshesProcess_Vertex vert_splitter;
     vert_splitter.SetLimit(0xffff);
-    vert_splitter.Execute(sceneCopy);
+    vert_splitter.Execute(sceneCopy_tmp);
 
-    mScene = sceneCopy;
+    mScene.reset(sceneCopy_tmp);
 
     mAsset.reset( new glTF::Asset( pIOSystem ) );
 
@@ -877,7 +876,7 @@ void glTFExporter::ExportMetadata()
 
 	// Copyright
 	aiString copyright_str;
-	if (mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
+	if (mScene->mMetaData != nullptr && mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
 		asset.copyright = copyright_str.C_Str();
 	}
 }

+ 1 - 1
code/glTF/glTFExporter.h

@@ -90,7 +90,7 @@ namespace Assimp
 
         const char* mFilename;
         IOSystem* mIOSystem;
-        const aiScene* mScene;
+        std::shared_ptr<const aiScene> mScene;
         const ExportProperties* mProperties;
 
         std::map<std::string, unsigned int> mTexturesByPath;

+ 5 - 2
code/glTF2/glTF2Asset.inl

@@ -752,6 +752,7 @@ inline uint8_t* Image::StealData()
 	return mData.release();
 }
 
+// Never take over the ownership of data whenever binary or not
 inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
 {
     Ref<Buffer> b = r.GetBodyBuffer();
@@ -764,8 +765,10 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
     }
     else { // text file: will be stored as a data uri
-		this->mData.reset(data);
-		this->mDataLength = length;
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
+        this->mDataLength = length;
     }
 }
 

+ 2 - 4
code/glTF2/glTF2Exporter.cpp

@@ -352,10 +352,8 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
                     if (path[0] == '*') { // embedded
                         aiTexture* tex = mScene->mTextures[atoi(&path[1])];
 
-                        // copy data since lifetime control is handed over to the asset
-                        uint8_t* data = new uint8_t[tex->mWidth];
-                        memcpy(data, tex->pcData, tex->mWidth);
-                        texture->source->SetData(data, tex->mWidth, *mAsset);
+                        // The asset has its own buffer, see Image::SetData
+                        texture->source->SetData(reinterpret_cast<uint8_t*> (tex->pcData), tex->mWidth, *mAsset);
 
                         if (tex->achFormatHint[0]) {
                             std::string mimeType = "image/";