Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thread safety checks for PAGView and PAGImageView. #2572

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions src/platform/ios/PAGImageView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ @implementation PAGImageView {
PAGDecoder* pagDecoder;
NSInteger duartion;
float renderScaleFactor;
NSInteger width;
NSInteger height;
NSUInteger numFrames;

NSMutableDictionary<NSNumber*, UIImage*>* imagesMap;
std::mutex imageViewLock;
Expand All @@ -97,6 +100,9 @@ - (void)initPAG {
self.memeoryCacheFinished = NO;
self.isVisible = NO;
filePath = nil;
width = 0;
height = 0;
numFrames = 0;
self.backgroundColor = [UIColor clearColor];
animator = [[PAGAnimator alloc] initWithUpdater:(id<PAGAnimatorUpdater>)self];

Expand Down Expand Up @@ -162,6 +168,7 @@ - (void)setCompositionInternal:(PAGComposition*)newComposition maxFrameRate:(flo
duartion = [newComposition duration];

[self reset];
[self updatePAGDecoder];
if (self.isVisible) {
[animator setDuration:duartion];
}
Expand All @@ -171,8 +178,8 @@ - (CVPixelBufferRef)getDiskCacheCVPixelBuffer {
if (diskBufferPool == nil) {
NSDictionary* options = @{
(id)kCVPixelBufferIOSurfacePropertiesKey : @{},
(id)kCVPixelBufferWidthKey : @([[self getPAGDecoder] width]),
(id)kCVPixelBufferHeightKey : @([[self getPAGDecoder] height]),
(id)kCVPixelBufferWidthKey : @(width),
(id)kCVPixelBufferHeightKey : @(height),
(id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)
};
CVReturn status = CVPixelBufferPoolCreate(kCFAllocatorDefault, nil, (CFDictionaryRef)options,
Expand All @@ -194,16 +201,15 @@ - (CVPixelBufferRef)getDiskCacheCVPixelBuffer {

- (CVPixelBufferRef)getMemoryCacheCVPixelBuffer {
CVPixelBufferRef pixelBuffer =
pag::PixelBufferUtil::Make(static_cast<int>([[self getPAGDecoder] width]),
static_cast<int>([[self getPAGDecoder] height]));
pag::PixelBufferUtil::Make(static_cast<int>(width), static_cast<int>(height));
if (pixelBuffer == nil) {
NSLog(@"PAGImageView: CVPixelBufferRef create failed!");
return nil;
}
return pixelBuffer;
}

- (PAGDecoder*)getPAGDecoder {
- (void)updatePAGDecoder {
if (pagDecoder == nil) {
float scaleFactor;
if (self.viewSize.width >= self.viewSize.height) {
Expand All @@ -224,10 +230,12 @@ - (PAGDecoder*)getPAGDecoder {
scale:scaleFactor];
}
if (pagDecoder) {
width = [pagDecoder width];
height = [pagDecoder height];
numFrames = [pagDecoder numFrames];
[pagDecoder retain];
}
}
return pagDecoder;
}

- (void)onAnimationFlush:(double)progress {
Expand Down Expand Up @@ -262,14 +270,17 @@ - (BOOL)updateImageViewFrom:(CVPixelBufferRef)pixelBuffer atIndex:(NSInteger)fra
self.currentUIImage = image;
[self submitToImageView];
}
if ([imagesMap count] == (NSUInteger)[[self getPAGDecoder] numFrames]) {
if ([imagesMap count] == numFrames) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你这里还没执行updatePAGDecoder, numFrames可能是0吧?检查一下其他相关的逻辑

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果 pagDeocder 为空,走不这里

self.memeoryCacheFinished = YES;
}
return YES;
}
PAGDecoder* decoder = [self getPAGDecoder];
if ([decoder checkFrameChanged:(int)frameIndex]) {
BOOL status = [decoder readFrame:frameIndex to:pixelBuffer];
[self updatePAGDecoder];
if (pagDecoder == nil) {
return false;
}
if ([pagDecoder checkFrameChanged:(int)frameIndex]) {
BOOL status = [pagDecoder readFrame:frameIndex to:pixelBuffer];
if (!status) {
return status;
}
Expand All @@ -294,6 +305,7 @@ - (BOOL)checkPAGCompositionChanged {
if ([PAGContentVersion Get:pagComposition] != self.pagContentVersion) {
self.pagContentVersion = [PAGContentVersion Get:pagComposition];
[self reset];
[self updatePAGDecoder];
if (self.isVisible) {
[animator setDuration:[pagComposition duration]];
}
Expand All @@ -317,8 +329,7 @@ - (void)applicationDidBecomeActive:(NSNotification*)notification {
}

- (void)freeCache {
if (self.memoryCacheEnabled && self->pagDecoder &&
[self->imagesMap count] == (NSUInteger)[self->pagDecoder numFrames]) {
if (self.memoryCacheEnabled && self->pagDecoder && [self->imagesMap count] == numFrames) {
[self->pagDecoder release];
self->pagDecoder = nil;
}
Expand All @@ -339,6 +350,9 @@ - (void)reset {
[pagDecoder release];
pagDecoder = nil;
}
width = 0;
height = 0;
numFrames = 0;
}

- (UIImage*)imageForCVPixelBuffer:(CVPixelBufferRef)pixelBuffer {
Expand Down Expand Up @@ -370,6 +384,7 @@ - (void)setBounds:(CGRect)bounds {
std::lock_guard<std::mutex> autoLock(imageViewLock);
if (pagComposition || filePath) {
[self reset];
[self updatePAGDecoder];
if (oldBounds.size.width == 0 || oldBounds.size.height == 0) {
[animator update];
}
Expand All @@ -385,6 +400,7 @@ - (void)setFrame:(CGRect)frame {
std::lock_guard<std::mutex> autoLock(imageViewLock);
if (pagComposition || filePath) {
[self reset];
[self updatePAGDecoder];
if (oldRect.size.width == 0 || oldRect.size.height == 0) {
[animator update];
}
Expand All @@ -400,6 +416,7 @@ - (void)setRenderScale:(float)scale {
renderScaleFactor = scale;
if (pagComposition || filePath) {
[self reset];
[self updatePAGDecoder];
}
}

Expand All @@ -415,6 +432,7 @@ - (void)setContentScaleFactor:(CGFloat)scaleFactor {
if (pagComposition || filePath) {
std::lock_guard<std::mutex> autoLock(imageViewLock);
[self reset];
[self updatePAGDecoder];
self.viewSize = CGSizeMake(self.frame.size.width, self.frame.size.height);
}
}
Expand Down Expand Up @@ -457,7 +475,7 @@ - (void)pause {

- (NSUInteger)numFrames {
std::lock_guard<std::mutex> autoLock(imageViewLock);
return [[self getPAGDecoder] numFrames];
return numFrames;
}

- (UIImage*)currentImage {
Expand Down Expand Up @@ -486,6 +504,7 @@ - (void)setRepeatCount:(int)repeatCount {
}

- (NSString*)getPath {
std::lock_guard<std::mutex> autoLock(imageViewLock);
return filePath == nil ? nil : [[filePath retain] autorelease];
}

Expand Down Expand Up @@ -516,6 +535,7 @@ - (void)setPathAsync:(NSString*)path completionBlock:(void (^)(PAGFile*))callbac
- (void)setPathAsync:(NSString*)path
maxFrameRate:(float)maxFrameRate
completionBlock:(void (^)(PAGFile*))callback {
std::lock_guard<std::mutex> autoLock(imageViewLock);
if (filePath != nil) {
[filePath release];
filePath = nil;
Expand All @@ -533,6 +553,7 @@ - (void)setPathAsync:(NSString*)path
}

- (PAGComposition*)getComposition {
std::lock_guard<std::mutex> autoLock(imageViewLock);
if (filePath) {
return nil;
}
Expand All @@ -554,16 +575,21 @@ - (void)setComposition:(PAGComposition*)newComposition maxFrameRate:(float)maxFr

- (void)setCurrentFrame:(NSUInteger)currentFrame {
std::lock_guard<std::mutex> autoLock(imageViewLock);
[animator setProgress:pag::FrameToProgress(currentFrame, [[self getPAGDecoder] numFrames])];
[animator setProgress:pag::FrameToProgress(currentFrame, numFrames)];
}

- (NSUInteger)currentFrame {
return pag::ProgressToFrame([animator progress], [[self getPAGDecoder] numFrames]);
std::lock_guard<std::mutex> autoLock(imageViewLock);
return [self currentFrameInternal];
}

- (NSUInteger)currentFrameInternal {
return pag::ProgressToFrame([animator progress], numFrames);
}

- (BOOL)flush {
std::lock_guard<std::mutex> autoLock(imageViewLock);
NSInteger frameIndex = [self currentFrame];
NSInteger frameIndex = [self currentFrameInternal];
if (self.memeoryCacheFinished) {
if ([self checkPAGCompositionChanged] == NO) {
if (self.currentFrameIndex != frameIndex) {
Expand Down
5 changes: 5 additions & 0 deletions src/platform/ios/PAGView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ @implementation PAGView {
NSString* filePath;
PAGAnimator* animator;
BOOL _isVisible;
std::mutex lock;
}

- (instancetype)initWithFrame:(CGRect)frame {
Expand Down Expand Up @@ -192,10 +193,12 @@ - (void)stop {
}

- (NSString*)getPath {
std::lock_guard<std::mutex> autoLock(lock);
return filePath == nil ? nil : [[filePath retain] autorelease];
}

- (BOOL)setPath:(NSString*)path {
std::lock_guard<std::mutex> autoLock(lock);
if (filePath != nil) {
[filePath release];
filePath = nil;
Expand All @@ -207,6 +210,7 @@ - (BOOL)setPath:(NSString*)path {
}

- (void)setPathAsync:(NSString*)path completionBlock:(void (^)(PAGFile*))callback {
std::lock_guard<std::mutex> autoLock(lock);
if (filePath != nil) {
[filePath release];
filePath = nil;
Expand All @@ -226,6 +230,7 @@ - (PAGComposition*)getComposition {
}

- (void)setComposition:(PAGComposition*)newComposition {
std::lock_guard<std::mutex> autoLock(lock);
if (filePath != nil) {
[filePath release];
filePath = nil;
Expand Down