From 6665b68234327e2abd10cfb63bc49f935df6b52e Mon Sep 17 00:00:00 2001 From: h3r3x3 Date: Fri, 4 Mar 2022 14:02:43 +0800 Subject: [PATCH] Fix the crash of ImageTask when accessing the ImageBytes from a deleted pag file. * Fix crash when life cycle of ImageTask is longer than life cycle of file * Fix crash when life cycle of ImageTask is longer than life cycle of file Co-authored-by: licheng --- src/rendering/caches/RenderCache.cpp | 16 ++++++++++------ src/rendering/layers/PAGStage.cpp | 7 ++----- src/rendering/layers/PAGStage.h | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/rendering/caches/RenderCache.cpp b/src/rendering/caches/RenderCache.cpp index 1f10a04693..1a1c192127 100644 --- a/src/rendering/caches/RenderCache.cpp +++ b/src/rendering/caches/RenderCache.cpp @@ -37,11 +37,12 @@ namespace pag { class ImageTask : public Executor { public: - static std::shared_ptr MakeAndRun(std::shared_ptr image) { + static std::shared_ptr MakeAndRun(std::shared_ptr image, + std::shared_ptr file) { if (image == nullptr) { return nullptr; } - auto bitmap = new ImageTask(std::move(image)); + auto bitmap = new ImageTask(std::move(image), file); auto task = Task::Make(std::unique_ptr(bitmap)); task->run(); return task; @@ -54,8 +55,11 @@ class ImageTask : public Executor { private: std::shared_ptr buffer = {}; std::shared_ptr image = nullptr; + // Make a reference to file when image made from imageByte of file. + std::shared_ptr file = nullptr; - explicit ImageTask(std::shared_ptr image) : image(std::move(image)) { + explicit ImageTask(std::shared_ptr image, std::shared_ptr file) + : image(std::move(image)), file(std::move(file)) { } void execute() override { @@ -361,7 +365,7 @@ void RenderCache::prepareImage(ID assetID, std::shared_ptr image) { if (imageTasks.count(assetID) != 0 || snapshotCaches.count(assetID) != 0) { return; } - auto task = ImageTask::MakeAndRun(std::move(image)); + auto task = ImageTask::MakeAndRun(std::move(image), stage->getFileFromReferenceMap(assetID)); if (task) { imageTasks[assetID] = task; } @@ -429,7 +433,7 @@ bool RenderCache::prepareSequenceReader(Sequence* sequence, Frame targetFrame, // 静态的序列帧采用位图的缓存逻辑,如果上层缓存过 Snapshot 就不需要预测。 return false; } - auto file = stage->getSequenceFile(sequence); + auto file = stage->getFileFromReferenceMap(composition->uniqueID); auto reader = MakeSequenceReader(file, sequence, policy); sequenceCaches[composition->uniqueID] = reader; reader->prepareAsync(targetFrame); @@ -460,7 +464,7 @@ std::shared_ptr RenderCache::getSequenceReader(Sequence* sequenc } } if (reader == nullptr) { - auto file = stage->getSequenceFile(sequence); + auto file = stage->getFileFromReferenceMap(composition->uniqueID); reader = MakeSequenceReader(file, sequence, SoftwareToHardwareEnabled() ? DecodingPolicy::SoftwareToHardware : DecodingPolicy::Hardware); diff --git a/src/rendering/layers/PAGStage.cpp b/src/rendering/layers/PAGStage.cpp index ac2b81869d..312fa206a5 100644 --- a/src/rendering/layers/PAGStage.cpp +++ b/src/rendering/layers/PAGStage.cpp @@ -69,11 +69,8 @@ uint32_t PAGStage::getContentVersion() const { return contentVersion; } -std::shared_ptr PAGStage::getSequenceFile(Sequence* sequence) { - if (sequence == nullptr) { - return nullptr; - } - auto result = layerReferenceMap.find(sequence->composition->uniqueID); +std::shared_ptr PAGStage::getFileFromReferenceMap(ID uniqueID) { + auto result = layerReferenceMap.find(uniqueID); if (result == layerReferenceMap.end()) { return nullptr; } diff --git a/src/rendering/layers/PAGStage.h b/src/rendering/layers/PAGStage.h index de6c20060c..5bb1e55ce1 100644 --- a/src/rendering/layers/PAGStage.h +++ b/src/rendering/layers/PAGStage.h @@ -116,7 +116,7 @@ class PAGStage : public PAGComposition { static tgfx::Point GetLayerContentScaleFactor(PAGLayer* pagLayer, bool isPAGImage); PAGStage(int width, int height); - std::shared_ptr getSequenceFile(Sequence* sequence); + std::shared_ptr getFileFromReferenceMap(ID uniqueID); void addToReferenceMap(ID uniqueID, PAGLayer* pagLayer); bool removeFromReferenceMap(ID uniqueID, PAGLayer* pagLayer); float getMaxScaleFactor(ID referenceID);