From 1cae51615f81f11cd4283c3e5792a7c226815111 Mon Sep 17 00:00:00 2001 From: "Hui.Du" Date: Thu, 16 Jan 2020 11:49:00 +1300 Subject: [PATCH] Fix: gltf exporting memory leak --- code/glTF/glTFAsset.inl | 4 +++- code/glTF/glTFExporter.cpp | 9 ++++----- code/glTF/glTFExporter.h | 2 +- code/glTF2/glTF2Asset.inl | 7 +++++-- code/glTF2/glTF2Exporter.cpp | 6 ++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/glTF/glTFAsset.inl b/code/glTF/glTFAsset.inl index 500d49fcb..f93f195bb 100644 --- a/code/glTF/glTFAsset.inl +++ b/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; } } diff --git a/code/glTF/glTFExporter.cpp b/code/glTF/glTFExporter.cpp index cf8ef974a..4772c7dc6 100644 --- a/code/glTF/glTFExporter.cpp +++ b/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(); } } diff --git a/code/glTF/glTFExporter.h b/code/glTF/glTFExporter.h index d6c2e7f04..ffa2ce42e 100644 --- a/code/glTF/glTFExporter.h +++ b/code/glTF/glTFExporter.h @@ -90,7 +90,7 @@ namespace Assimp const char* mFilename; IOSystem* mIOSystem; - const aiScene* mScene; + std::shared_ptr mScene; const ExportProperties* mProperties; std::map mTexturesByPath; diff --git a/code/glTF2/glTF2Asset.inl b/code/glTF2/glTF2Asset.inl index e55857be1..3db37c72b 100644 --- a/code/glTF2/glTF2Asset.inl +++ b/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 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; } } diff --git a/code/glTF2/glTF2Exporter.cpp b/code/glTF2/glTF2Exporter.cpp index d7b16ab04..ee40694f9 100644 --- a/code/glTF2/glTF2Exporter.cpp +++ b/code/glTF2/glTF2Exporter.cpp @@ -352,10 +352,8 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref& 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 (tex->pcData), tex->mWidth, *mAsset); if (tex->achFormatHint[0]) { std::string mimeType = "image/";