From 826facdc11437d9000c52e30265126344510e87b Mon Sep 17 00:00:00 2001 From: liamcli Date: Sun, 25 Jun 2023 17:24:32 +0800 Subject: [PATCH] support disk cache of SequenceComposition --- .../src/main/java/org/libpag/PAGPlayer.java | 6 +-- .../src/main/java/org/libpag/PAGView.java | 10 ++--- include/pag/pag.h | 6 +-- src/platform/android/JPAGPlayer.cpp | 9 ++-- src/platform/cocoa/PAGPlayer.h | 6 +-- src/platform/cocoa/PAGPlayer.m | 8 ++-- src/platform/cocoa/private/PAGPlayerImpl.h | 4 +- src/platform/cocoa/private/PAGPlayerImpl.mm | 8 ++-- src/platform/ios/PAGView.h | 6 +-- src/platform/ios/PAGView.m | 8 ++-- src/rendering/PAGPlayer.cpp | 8 ++-- src/rendering/caches/RenderCache.cpp | 2 +- src/rendering/caches/RenderCache.h | 12 +++--- .../sequences/DiskSequenceReader.cpp | 41 ++++++++++++++----- src/rendering/sequences/DiskSequenceReader.h | 4 ++ src/rendering/sequences/SequenceInfo.cpp | 20 ++++----- src/rendering/sequences/SequenceInfo.h | 6 +-- 17 files changed, 94 insertions(+), 70 deletions(-) diff --git a/android/libpag/src/main/java/org/libpag/PAGPlayer.java b/android/libpag/src/main/java/org/libpag/PAGPlayer.java index 9e9723670d..471abb2734 100644 --- a/android/libpag/src/main/java/org/libpag/PAGPlayer.java +++ b/android/libpag/src/main/java/org/libpag/PAGPlayer.java @@ -73,12 +73,12 @@ public void setSurface(PAGSurface surface) { * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ - public native boolean diskCacheEnabled(); + public native boolean useDiskCache(); /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ - public native void setDiskCacheEnabled(boolean value); + public native void setUseDiskCache(boolean value); /** * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The diff --git a/android/libpag/src/main/java/org/libpag/PAGView.java b/android/libpag/src/main/java/org/libpag/PAGView.java index 998b28dc09..34f19a1b91 100644 --- a/android/libpag/src/main/java/org/libpag/PAGView.java +++ b/android/libpag/src/main/java/org/libpag/PAGView.java @@ -286,15 +286,15 @@ public void setCacheEnabled(boolean value) { * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ - public boolean diskCacheEnabled() { - return pagPlayer.diskCacheEnabled(); + public boolean useDiskCache() { + return pagPlayer.useDiskCache(); } /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ - public void setDiskCacheEnabled(boolean value) { - pagPlayer.setDiskCacheEnabled(value); + public void setUseDiskCache(boolean value) { + pagPlayer.setUseDiskCache(value); } /** diff --git a/include/pag/pag.h b/include/pag/pag.h index fd3990e465..68cf8ca93e 100644 --- a/include/pag/pag.h +++ b/include/pag/pag.h @@ -1333,12 +1333,12 @@ class PAG_API PAGPlayer { * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ - bool diskCacheEnabled(); + bool useDiskCache(); /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ - void setDiskCacheEnabled(bool value); + void setUseDiskCache(bool value); /** * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The diff --git a/src/platform/android/JPAGPlayer.cpp b/src/platform/android/JPAGPlayer.cpp index 408157cf01..803591ba87 100644 --- a/src/platform/android/JPAGPlayer.cpp +++ b/src/platform/android/JPAGPlayer.cpp @@ -316,20 +316,19 @@ PAG_API jboolean Java_org_libpag_PAGPlayer_hitTestPoint(JNIEnv* env, jobject thi return (jboolean)player->hitTestPoint(pagLayer, x, y, pixelHitTest); } -PAG_API void Java_org_libpag_PAGPlayer_setDiskCacheEnabled(JNIEnv* env, jobject thiz, - jboolean value) { +PAG_API void Java_org_libpag_PAGPlayer_setUseDiskCache(JNIEnv* env, jobject thiz, jboolean value) { auto player = getPAGPlayer(env, thiz); if (player == nullptr) { return; } - player->setDiskCacheEnabled(value); + player->setUseDiskCache(value); } -PAG_API jboolean Java_org_libpag_PAGPlayer_diskCacheEnabled(JNIEnv* env, jobject thiz) { +PAG_API jboolean Java_org_libpag_PAGPlayer_useDiskCache(JNIEnv* env, jobject thiz) { auto player = getPAGPlayer(env, thiz); if (player == nullptr) { return JNI_FALSE; } - return player->diskCacheEnabled(); + return player->useDiskCache(); } } diff --git a/src/platform/cocoa/PAGPlayer.h b/src/platform/cocoa/PAGPlayer.h index 71b85c9413..a24d9b34a1 100644 --- a/src/platform/cocoa/PAGPlayer.h +++ b/src/platform/cocoa/PAGPlayer.h @@ -74,12 +74,12 @@ PAG_API @interface PAGPlayer : NSObject * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ -- (BOOL)diskCacheEnabled; +- (BOOL)useDiskCache; /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ -- (void)setDiskCacheEnabled:(BOOL)value; +- (void)setUseDiskCache:(BOOL)value; /** * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The diff --git a/src/platform/cocoa/PAGPlayer.m b/src/platform/cocoa/PAGPlayer.m index 076d220d43..b9ca972c47 100644 --- a/src/platform/cocoa/PAGPlayer.m +++ b/src/platform/cocoa/PAGPlayer.m @@ -88,12 +88,12 @@ - (void)setCacheEnabled:(BOOL)value { [pagPlayer setCacheEnabled:value]; } -- (BOOL)diskCacheEnabled { - return [pagPlayer diskCacheEnabled]; +- (BOOL)useDiskCache { + return [pagPlayer useDiskCache]; } -- (void)setDiskCacheEnabled:(BOOL)value { - [pagPlayer setDiskCacheEnabled:value]; +- (void)setUseDiskCache:(BOOL)value { + [pagPlayer setUseDiskCache:value]; } - (float)cacheScale { diff --git a/src/platform/cocoa/private/PAGPlayerImpl.h b/src/platform/cocoa/private/PAGPlayerImpl.h index 934ff64412..5b6b7b818f 100644 --- a/src/platform/cocoa/private/PAGPlayerImpl.h +++ b/src/platform/cocoa/private/PAGPlayerImpl.h @@ -35,9 +35,9 @@ - (void)setCacheEnabled:(BOOL)value; -- (BOOL)diskCacheEnabled; +- (BOOL)useDiskCache; -- (void)setDiskCacheEnabled:(BOOL)value; +- (void)setUseDiskCache:(BOOL)value; - (float)cacheScale; diff --git a/src/platform/cocoa/private/PAGPlayerImpl.mm b/src/platform/cocoa/private/PAGPlayerImpl.mm index eb6cbfd09c..5aaeb97705 100644 --- a/src/platform/cocoa/private/PAGPlayerImpl.mm +++ b/src/platform/cocoa/private/PAGPlayerImpl.mm @@ -82,12 +82,12 @@ - (void)setCacheEnabled:(BOOL)value { pagPlayer->setCacheEnabled(value); } -- (BOOL)diskCacheEnabled { - return pagPlayer->diskCacheEnabled(); +- (BOOL)useDiskCache { + return pagPlayer->useDiskCache(); } -- (void)setDiskCacheEnabled:(BOOL)value { - pagPlayer->setDiskCacheEnabled(value); +- (void)setUseDiskCache:(BOOL)value { + pagPlayer->setUseDiskCache(value); } - (float)cacheScale { diff --git a/src/platform/ios/PAGView.h b/src/platform/ios/PAGView.h index b7be7c782a..ee39d2ee09 100644 --- a/src/platform/ios/PAGView.h +++ b/src/platform/ios/PAGView.h @@ -169,12 +169,12 @@ PAG_API @interface PAGView : UIView * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ -- (BOOL)diskCacheEnabled; +- (BOOL)useDiskCache; /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ -- (void)setDiskCacheEnabled:(BOOL)value; +- (void)setUseDiskCache:(BOOL)value; /** * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The diff --git a/src/platform/ios/PAGView.m b/src/platform/ios/PAGView.m index 631b37f880..0fa612d783 100644 --- a/src/platform/ios/PAGView.m +++ b/src/platform/ios/PAGView.m @@ -237,12 +237,12 @@ - (void)setCacheEnabled:(BOOL)value { [pagPlayer setCacheEnabled:value]; } -- (BOOL)diskCacheEnabled { - return [pagPlayer diskCacheEnabled]; +- (BOOL)useDiskCache { + return [pagPlayer useDiskCache]; } -- (void)setDiskCacheEnabled:(BOOL)value { - [pagPlayer setDiskCacheEnabled:value]; +- (void)setUseDiskCache:(BOOL)value { + [pagPlayer setUseDiskCache:value]; } - (float)cacheScale { diff --git a/src/rendering/PAGPlayer.cpp b/src/rendering/PAGPlayer.cpp index e0420f161c..a5c57d1ec5 100644 --- a/src/rendering/PAGPlayer.cpp +++ b/src/rendering/PAGPlayer.cpp @@ -122,14 +122,14 @@ void PAGPlayer::setCacheEnabled(bool value) { renderCache->setSnapshotEnabled(value); } -bool PAGPlayer::diskCacheEnabled() { +bool PAGPlayer::useDiskCache() { LockGuard autoLock(rootLocker); - return renderCache->diskCacheEnabled(); + return renderCache->useDiskCache(); } -void PAGPlayer::setDiskCacheEnabled(bool value) { +void PAGPlayer::setUseDiskCache(bool value) { LockGuard autoLock(rootLocker); - renderCache->setDiskCacheEnabled(value); + renderCache->setUseDiskCache(value); } float PAGPlayer::cacheScale() { diff --git a/src/rendering/caches/RenderCache.cpp b/src/rendering/caches/RenderCache.cpp index 644372b22a..6aa64d8fc6 100644 --- a/src/rendering/caches/RenderCache.cpp +++ b/src/rendering/caches/RenderCache.cpp @@ -94,7 +94,7 @@ void RenderCache::preparePreComposeLayer(PreComposeLayer* layer) { } usedAssets.insert(composition->uniqueID); auto sequence = Sequence::Get(composition); - auto info = SequenceInfo::Make(sequence, _diskCacheEnabled); + auto info = SequenceInfo::Make(sequence, _useDiskCache); if (composition->staticContent()) { SequenceImageProxy proxy(info, 0); prepareAssetImage(composition->uniqueID, &proxy); diff --git a/src/rendering/caches/RenderCache.h b/src/rendering/caches/RenderCache.h index e9b7ddcc8d..492c5d7cd3 100644 --- a/src/rendering/caches/RenderCache.h +++ b/src/rendering/caches/RenderCache.h @@ -101,15 +101,15 @@ class RenderCache : public Performance { * when first rendering BitmapComposition and VideoComposition, * which will reduces memory consumption, and increases stability. */ - bool diskCacheEnabled() const { - return _diskCacheEnabled; + bool useDiskCache() const { + return _useDiskCache; } /** - * Set the value of diskCacheEnabled property. + * Set the value of useDiskCache property. */ - void setDiskCacheEnabled(bool value) { - _diskCacheEnabled = value; + void setUseDiskCache(bool value) { + _useDiskCache = value; } /** @@ -187,7 +187,7 @@ class RenderCache : public Performance { size_t graphicsMemory = 0; bool _videoEnabled = true; bool _snapshotEnabled = true; - bool _diskCacheEnabled = false; + bool _useDiskCache = false; std::unordered_set usedAssets = {}; std::unordered_map snapshotCaches = {}; std::list snapshotLRU = {}; diff --git a/src/rendering/sequences/DiskSequenceReader.cpp b/src/rendering/sequences/DiskSequenceReader.cpp index 20977020b9..17be1042c6 100644 --- a/src/rendering/sequences/DiskSequenceReader.cpp +++ b/src/rendering/sequences/DiskSequenceReader.cpp @@ -19,6 +19,7 @@ #include "DiskSequenceReader.h" #include "base/utils/TGFXCast.h" #include "platform/Platform.h" +#include "tgfx/utils/Buffer.h" namespace pag { @@ -43,6 +44,8 @@ int DiskSequenceReader::height() const { } std::shared_ptr DiskSequenceReader::onMakeBuffer(Frame targetFrame) { + // Need a locker here in case there are other threads are decoding at the same time. + std::lock_guard autoLock(locker); if (pagDecoder == nullptr) { auto root = PAGComposition::Make(sequence->width, sequence->height); auto composition = std::make_shared( @@ -64,29 +67,47 @@ std::shared_ptr DiskSequenceReader::onMakeBuffer(Frame target if (pagDecoder == nullptr) { return nullptr; } - if (bitmap == nullptr) { - bitmap = std::make_shared(pagDecoder->width(), pagDecoder->height(), false, true); + if (bitmap == nullptr && pixels == nullptr) { + if (tgfx::HardwareBufferAvailable()) { + auto hardwareBuffer = + tgfx::HardwareBufferAllocate(pagDecoder->width(), pagDecoder->height(), false); + if (hardwareBuffer) { + bitmap = std::make_shared(hardwareBuffer); + tgfx::HardwareBufferRelease(hardwareBuffer); + } + } + if (bitmap == nullptr) { + info = tgfx::ImageInfo::Make(pagDecoder->width(), pagDecoder->height(), + tgfx::ColorType::RGBA_8888); + tgfx::Buffer buffer(info.byteSize()); + buffer.clear(); + pixels = buffer.release(); + } } + if (!pagDecoder->checkFrameChanged(targetFrame)) { - return bitmap->makeBuffer(); + return imageBuffer; } bool success = false; - if (bitmap->isHardwareBacked()) { + if (bitmap) { success = pagDecoder->readFrame(targetFrame, bitmap->getHardwareBuffer()); } else { - auto pixels = bitmap->lockPixels(); if (pixels) { - success = pagDecoder->readFrame(targetFrame, pixels, bitmap->info().rowBytes(), - ToPAG(bitmap->info().colorType()), - ToPAG(bitmap->info().alphaType())); - bitmap->unlockPixels(); + success = + pagDecoder->readFrame(targetFrame, const_cast(pixels->data()), info.rowBytes(), + ToPAG(info.colorType()), ToPAG(info.alphaType())); } } if (!success) { LOGE("DiskSequenceReader: Error on readFrame.\n"); return nullptr; } - return bitmap->makeBuffer(); + if (bitmap) { + imageBuffer = bitmap->makeBuffer(); + } else { + imageBuffer = tgfx::ImageBuffer::MakeFrom(info, pixels); + } + return imageBuffer; } void DiskSequenceReader::onReportPerformance(Performance*, int64_t) { diff --git a/src/rendering/sequences/DiskSequenceReader.h b/src/rendering/sequences/DiskSequenceReader.h index 3db4fd510b..9612ac45ce 100644 --- a/src/rendering/sequences/DiskSequenceReader.h +++ b/src/rendering/sequences/DiskSequenceReader.h @@ -37,5 +37,9 @@ class DiskSequenceReader : public SequenceReader { std::shared_ptr file; std::shared_ptr onMakeBuffer(Frame targetFrame) override; void onReportPerformance(Performance* performance, int64_t decodingTime) override; + std::shared_ptr imageBuffer = nullptr; + std::mutex locker = {}; + tgfx::ImageInfo info = {}; + std::shared_ptr pixels = nullptr; }; } // namespace pag diff --git a/src/rendering/sequences/SequenceInfo.cpp b/src/rendering/sequences/SequenceInfo.cpp index daea6bb756..4432acfc6b 100644 --- a/src/rendering/sequences/SequenceInfo.cpp +++ b/src/rendering/sequences/SequenceInfo.cpp @@ -28,9 +28,9 @@ namespace pag { static std::shared_ptr MakeSequenceImage( - std::shared_ptr generator, Sequence* sequence, bool diskCacheEnabled) { + std::shared_ptr generator, Sequence* sequence, bool useDiskCache) { auto image = tgfx::Image::MakeFrom(std::move(generator)); - if (!diskCacheEnabled && sequence->composition->type() == CompositionType::Video) { + if (!useDiskCache && sequence->composition->type() == CompositionType::Video) { auto videoSequence = static_cast(sequence); image = image->makeRGBAAA(sequence->width, sequence->height, videoSequence->alphaStartX, videoSequence->alphaStartY); @@ -38,19 +38,19 @@ static std::shared_ptr MakeSequenceImage( return image; } -std::shared_ptr SequenceInfo::Make(Sequence* sequence, bool diskCacheEnabled) { +std::shared_ptr SequenceInfo::Make(Sequence* sequence, bool useDiskCache) { if (sequence == nullptr) { return nullptr; } - auto factory = std::shared_ptr(new SequenceInfo(sequence, diskCacheEnabled)); + auto factory = std::shared_ptr(new SequenceInfo(sequence, useDiskCache)); factory->weakThis = factory; return factory; } -SequenceInfo::SequenceInfo(Sequence* sequence, bool diskCacheEnabled) - : sequence(sequence), diskCacheEnabled(diskCacheEnabled) { +SequenceInfo::SequenceInfo(Sequence* sequence, bool useDiskCache) + : sequence(sequence), useDiskCache(useDiskCache) { #ifdef PAG_BUILD_FOR_WEB - diskCacheEnabled = false; + useDiskCache = false; #endif } @@ -61,7 +61,7 @@ std::shared_ptr SequenceInfo::makeReader(std::shared_ptr f } std::shared_ptr reader = nullptr; auto composition = sequence->composition; - if (diskCacheEnabled) { + if (useDiskCache) { reader = DiskSequenceReader::Make(std::move(file), sequence); if (reader) { return reader; @@ -96,7 +96,7 @@ std::shared_ptr SequenceInfo::makeStaticImage(std::shared_ptr } auto generator = std::make_shared(std::move(file), weakThis.lock(), width, height); - return MakeSequenceImage(std::move(generator), sequence, diskCacheEnabled); + return MakeSequenceImage(std::move(generator), sequence, useDiskCache); } std::shared_ptr SequenceInfo::makeFrameImage(std::shared_ptr reader, @@ -105,7 +105,7 @@ std::shared_ptr SequenceInfo::makeFrameImage(std::shared_ptr(std::move(reader), targetFrame); - return MakeSequenceImage(std::move(generator), sequence, diskCacheEnabled); + return MakeSequenceImage(std::move(generator), sequence, useDiskCache); } bool SequenceInfo::staticContent() const { diff --git a/src/rendering/sequences/SequenceInfo.h b/src/rendering/sequences/SequenceInfo.h index 40b4c645fb..7a998911d2 100644 --- a/src/rendering/sequences/SequenceInfo.h +++ b/src/rendering/sequences/SequenceInfo.h @@ -27,7 +27,7 @@ namespace pag { class SequenceInfo { public: - static std::shared_ptr Make(Sequence* sequence, bool diskCacheEnabled); + static std::shared_ptr Make(Sequence* sequence, bool useDiskCache); virtual ~SequenceInfo() = default; @@ -50,11 +50,11 @@ class SequenceInfo { std::weak_ptr weakThis; protected: - explicit SequenceInfo(Sequence* sequence, bool diskCacheEnabled); + explicit SequenceInfo(Sequence* sequence, bool useDiskCache); private: Sequence* sequence; - bool diskCacheEnabled = false; + bool useDiskCache = false; }; class StaticSequenceGenerator : public tgfx::ImageGenerator {