Skip to content

Commit

Permalink
Fixed the issue of creating a surface in a non-main thread on the ios…
Browse files Browse the repository at this point in the history
… platform.

* Fixed the issue of creating a surface in a non-main thread.

* Fixing the deadlock when setting Sync

* code format
  • Loading branch information
Hparty authored Dec 28, 2023
1 parent 4d06756 commit 4f599e7
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 12 deletions.
9 changes: 9 additions & 0 deletions src/platform/ios/PAGView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#import "PAGPlayer.h"
#import "PAGSurface.h"
#import "platform/cocoa/private/PAGAnimator.h"
#import "platform/ios/private/GPUDrawable.h"

@implementation PAGView {
PAGPlayer* pagPlayer;
Expand Down Expand Up @@ -53,6 +54,10 @@ - (void)initPAG {
selector:@selector(applicationDidReceiveMemoryWarning:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(AsyncSurfacePrepared:)
name:pag::kAsyncSurfacePreparedNotification
object:self.layer];
}

- (void)dealloc {
Expand Down Expand Up @@ -349,4 +354,8 @@ - (CGRect)getBounds:(PAGLayer*)pagLayer {
}
return CGRectNull;
}

- (void)AsyncSurfacePrepared:(NSNotification*)notification {
[animator update];
}
@end
3 changes: 3 additions & 0 deletions src/platform/ios/private/GPUDrawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

namespace pag {

extern NSString* const kAsyncSurfacePreparedNotification;

class GPUDrawable : public Drawable {
public:
static std::shared_ptr<GPUDrawable> FromLayer(CAEAGLLayer* layer);
Expand All @@ -48,6 +50,7 @@ class GPUDrawable : public Drawable {
int _height = 0;
CAEAGLLayer* layer = nil;
std::shared_ptr<tgfx::EAGLWindow> window = nullptr;
std::atomic<bool> bufferPreparing = false;

explicit GPUDrawable(CAEAGLLayer* layer);

Expand Down
36 changes: 34 additions & 2 deletions src/platform/ios/private/GPUDrawable.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "GPUDrawable.h"

namespace pag {
NSString* const kAsyncSurfacePreparedNotification = @"pag.art.AsyncSurfacePrepared";

std::shared_ptr<GPUDrawable> GPUDrawable::FromLayer(CAEAGLLayer* layer) {
if (layer == nil) {
return nullptr;
Expand Down Expand Up @@ -78,10 +80,40 @@
}

std::shared_ptr<tgfx::Surface> GPUDrawable::onCreateSurface(tgfx::Context* context) {
if (window == nullptr) {
if (window == nullptr || bufferPreparing) {
return nullptr;
}
if (surface) {
return surface;
}
// https://github.com/Tencent/libpag/issues/1870
// Creating a surface in a non-main thread may lead to a crash.
if (NSThread.isMainThread) {
surface = window->getSurface(context);
return surface;
} else {
bufferPreparing = true;
auto strongThis = weakThis.lock();
[layer retain];
dispatch_async(dispatch_get_main_queue(), ^{
auto context = strongThis->window->getDevice()->lockContext();
if (context == nullptr) {
strongThis->bufferPreparing = false;
[strongThis->layer release];
return;
}
strongThis->surface = strongThis->window->getSurface(context);
strongThis->bufferPreparing = false;
strongThis->window->getDevice()->unlock();
if (strongThis->surface) {
[[NSNotificationCenter defaultCenter] postNotificationName:kAsyncSurfacePreparedNotification
object:strongThis->layer
userInfo:nil];
}
[strongThis->layer release];
});
return nullptr;
}
return window->getSurface(context);
}

void GPUDrawable::onFreeSurface() {
Expand Down
16 changes: 7 additions & 9 deletions src/rendering/PAGAnimator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,17 @@ bool PAGAnimator::isSync() {
}

void PAGAnimator::setSync(bool value) {
std::lock_guard<std::mutex> autoLock(locker);
locker.lock();
if (_isSync == value) {
locker.unlock();
return;
}
_isSync = value;
if (_isSync) {
resetTask();
auto tempTask = task;
task = nullptr;
locker.unlock();
if (tempTask) {
tempTask->wait();
}
}

Expand Down Expand Up @@ -327,10 +331,4 @@ void PAGAnimator::resetStartTime() {
_startTime = INT64_MIN;
}

void PAGAnimator::resetTask() {
if (task != nullptr) {
task->wait();
task = nullptr;
}
}
} // namespace pag
1 change: 0 additions & 1 deletion src/rendering/PAGAnimator.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ class PAGAnimator {
void startAnimation();
void cancelAnimation();
void resetStartTime();
void resetTask();

friend class AnimationTicker;
};
Expand Down

0 comments on commit 4f599e7

Please sign in to comment.