forked from firka/flutter
Handle Android vsync callbacks that occur after the VsyncWaiter has been deleted (flutter/engine#5749)
Fixes https://github.com/flutter/flutter/issues/19159
This commit is contained in:
@@ -64,7 +64,7 @@ class Animator final {
|
||||
|
||||
Delegate& delegate_;
|
||||
blink::TaskRunners task_runners_;
|
||||
std::unique_ptr<VsyncWaiter> waiter_;
|
||||
std::shared_ptr<VsyncWaiter> waiter_;
|
||||
|
||||
fxl::TimePoint last_begin_frame_time_;
|
||||
int64_t dart_frame_deadline_;
|
||||
|
||||
@@ -125,7 +125,6 @@ class PlatformView {
|
||||
protected:
|
||||
PlatformView::Delegate& delegate_;
|
||||
const blink::TaskRunners task_runners_;
|
||||
std::unique_ptr<VsyncWaiter> vsync_waiter_;
|
||||
|
||||
SkISize size_;
|
||||
fml::WeakPtrFactory<PlatformView> weak_factory_;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace shell {
|
||||
|
||||
class VsyncWaiter {
|
||||
class VsyncWaiter : public std::enable_shared_from_this<VsyncWaiter> {
|
||||
public:
|
||||
using Callback = std::function<void(fxl::TimePoint frame_start_time,
|
||||
fxl::TimePoint frame_target_time)>;
|
||||
@@ -23,6 +23,9 @@ class VsyncWaiter {
|
||||
|
||||
void AsyncWaitForVsync(Callback callback);
|
||||
|
||||
void FireCallback(fxl::TimePoint frame_start_time,
|
||||
fxl::TimePoint frame_target_time);
|
||||
|
||||
protected:
|
||||
const blink::TaskRunners task_runners_;
|
||||
std::mutex callback_mutex_;
|
||||
@@ -32,9 +35,6 @@ class VsyncWaiter {
|
||||
|
||||
virtual void AwaitVSync() = 0;
|
||||
|
||||
void FireCallback(fxl::TimePoint frame_start_time,
|
||||
fxl::TimePoint frame_target_time);
|
||||
|
||||
FXL_DISALLOW_COPY_AND_ASSIGN(VsyncWaiter);
|
||||
};
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
namespace shell {
|
||||
|
||||
static jlong CreatePendingCallback(VsyncWaiter::Callback callback);
|
||||
|
||||
static void ConsumePendingCallback(jlong java_baton,
|
||||
fxl::TimePoint frame_start_time,
|
||||
fxl::TimePoint frame_target_time);
|
||||
@@ -32,12 +30,9 @@ VsyncWaiterAndroid::~VsyncWaiterAndroid() = default;
|
||||
|
||||
// |shell::VsyncWaiter|
|
||||
void VsyncWaiterAndroid::AwaitVSync() {
|
||||
auto java_baton =
|
||||
CreatePendingCallback(std::bind(&VsyncWaiterAndroid::FireCallback, //
|
||||
this, //
|
||||
std::placeholders::_1, //
|
||||
std::placeholders::_2 //
|
||||
));
|
||||
std::weak_ptr<VsyncWaiter>* weak_this =
|
||||
new std::weak_ptr<VsyncWaiter>(shared_from_this());
|
||||
jlong java_baton = reinterpret_cast<jlong>(weak_this);
|
||||
|
||||
task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() {
|
||||
JNIEnv* env = fml::jni::AttachCurrentThread();
|
||||
@@ -86,27 +81,16 @@ bool VsyncWaiterAndroid::Register(JNIEnv* env) {
|
||||
return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
|
||||
}
|
||||
|
||||
struct PendingCallbackData {
|
||||
VsyncWaiter::Callback callback;
|
||||
|
||||
PendingCallbackData(VsyncWaiter::Callback p_callback)
|
||||
: callback(std::move(p_callback)) {
|
||||
FXL_DCHECK(callback);
|
||||
}
|
||||
};
|
||||
|
||||
static jlong CreatePendingCallback(VsyncWaiter::Callback callback) {
|
||||
// This delete for this new is balanced in the consume call.
|
||||
auto data = new PendingCallbackData(std::move(callback));
|
||||
return reinterpret_cast<jlong>(data);
|
||||
}
|
||||
|
||||
static void ConsumePendingCallback(jlong java_baton,
|
||||
fxl::TimePoint frame_start_time,
|
||||
fxl::TimePoint frame_target_time) {
|
||||
auto data = reinterpret_cast<PendingCallbackData*>(java_baton);
|
||||
data->callback(frame_start_time, frame_target_time);
|
||||
delete data;
|
||||
auto weak_this = reinterpret_cast<std::weak_ptr<VsyncWaiter>*>(java_baton);
|
||||
auto shared_this = weak_this->lock();
|
||||
delete weak_this;
|
||||
|
||||
if (shared_this) {
|
||||
shared_this->FireCallback(frame_start_time, frame_target_time);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define SHELL_PLATFORM_ANDROID_VSYNC_WAITER_ANDROID_H_
|
||||
|
||||
#include <jni.h>
|
||||
#include <memory>
|
||||
#include "flutter/fml/memory/weak_ptr.h"
|
||||
#include "flutter/shell/common/vsync_waiter.h"
|
||||
#include "lib/fxl/macros.h"
|
||||
|
||||
Reference in New Issue
Block a user