未验证 提交 2bd75ae8 编写于 作者: L liyuqian 提交者: GitHub

Support querying display refresh rate in engine (#7002)

The current implementation only deals with Android devices and we'll add iOS devices support soon.
上级 e5195ee4
......@@ -30,6 +30,8 @@ const fml::StringView ServiceProtocol::kFlushUIThreadTasksExtensionName =
"_flutter.flushUIThreadTasks";
const fml::StringView ServiceProtocol::kSetAssetBundlePathExtensionName =
"_flutter.setAssetBundlePath";
const fml::StringView ServiceProtocol::kGetDisplayRefreshRateExtensionName =
"_flutter.getDisplayRefreshRate";
static constexpr fml::StringView kViewIdPrefx = "_flutterView/";
static constexpr fml::StringView kListViewsExtensionName = "_flutter.listViews";
......@@ -45,6 +47,7 @@ ServiceProtocol::ServiceProtocol()
kRunInViewExtensionName,
kFlushUIThreadTasksExtensionName,
kSetAssetBundlePathExtensionName,
kGetDisplayRefreshRateExtensionName,
}),
handlers_mutex_(fml::SharedMutex::Create()) {}
......
......@@ -27,6 +27,7 @@ class ServiceProtocol {
static const fml::StringView kRunInViewExtensionName;
static const fml::StringView kFlushUIThreadTasksExtensionName;
static const fml::StringView kSetAssetBundlePathExtensionName;
static const fml::StringView kGetDisplayRefreshRateExtensionName;
class Handler {
public:
......
......@@ -39,6 +39,10 @@ Animator::Animator(Delegate& delegate,
Animator::~Animator() = default;
float Animator::GetDisplayRefreshRate() const {
return waiter_->GetDisplayRefreshRate();
}
void Animator::Stop() {
paused_ = true;
}
......
......@@ -36,6 +36,8 @@ class Animator final {
~Animator();
float GetDisplayRefreshRate() const;
void RequestFrame(bool regenerate_layer_tree = true);
void Render(std::unique_ptr<flow::LayerTree> layer_tree);
......
......@@ -69,6 +69,10 @@ Engine::Engine(Delegate& delegate,
Engine::~Engine() = default;
float Engine::GetDisplayRefreshRate() const {
return animator_->GetDisplayRefreshRate();
}
fml::WeakPtr<Engine> Engine::GetWeakPtr() const {
return weak_factory_.GetWeakPtr();
}
......
......@@ -66,6 +66,8 @@ class Engine final : public blink::RuntimeDelegate {
~Engine() override;
float GetDisplayRefreshRate() const;
fml::WeakPtr<Engine> GetWeakPtr() const;
FML_WARN_UNUSED_RESULT
......
......@@ -293,6 +293,11 @@ Shell::Shell(blink::TaskRunners task_runners, blink::Settings settings)
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolSetAssetBundlePath, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_
[blink::ServiceProtocol::kGetDisplayRefreshRateExtensionName.ToString()] =
{task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolGetDisplayRefreshRate, this,
std::placeholders::_1, std::placeholders::_2)};
}
Shell::~Shell() {
......@@ -939,6 +944,16 @@ bool Shell::OnServiceProtocolFlushUIThreadTasks(
return true;
}
bool Shell::OnServiceProtocolGetDisplayRefreshRate(
const blink::ServiceProtocol::Handler::ServiceProtocolMap& params,
rapidjson::Document& response) {
FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
response.SetObject();
response.AddMember("fps", engine_->GetDisplayRefreshRate(),
response.GetAllocator());
return true;
}
// Service protocol handler
bool Shell::OnServiceProtocolSetAssetBundlePath(
const blink::ServiceProtocol::Handler::ServiceProtocolMap& params,
......
......@@ -225,6 +225,11 @@ class Shell final : public PlatformView::Delegate,
const blink::ServiceProtocol::Handler::ServiceProtocolMap& params,
rapidjson::Document& response);
// Service protocol handler
bool OnServiceProtocolGetDisplayRefreshRate(
const blink::ServiceProtocol::Handler::ServiceProtocolMap& params,
rapidjson::Document& response);
FML_DISALLOW_COPY_AND_ASSIGN(Shell);
};
......
......@@ -14,6 +14,8 @@
namespace shell {
constexpr float kUnknownRefreshRateFPS = 0.0;
class VsyncWaiter : public std::enable_shared_from_this<VsyncWaiter> {
public:
using Callback = std::function<void(fml::TimePoint frame_start_time,
......@@ -26,6 +28,10 @@ class VsyncWaiter : public std::enable_shared_from_this<VsyncWaiter> {
void FireCallback(fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time);
// Get the display's maximum refresh rate in the unit of frame per second.
// Return 0.0 if the refresh rate is unkonwn.
virtual float GetDisplayRefreshRate() const { return 0.0; }
protected:
const blink::TaskRunners task_runners_;
std::mutex callback_mutex_;
......
......@@ -806,6 +806,7 @@ public class FlutterView extends SurfaceView
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
float fps = wm.getDefaultDisplay().getRefreshRate();
VsyncWaiter.refreshPeriodNanos = (long) (1000000000.0 / fps);
VsyncWaiter.refreshRateFPS = fps;
}
// Called by native to update the semantics/accessibility tree.
......
......@@ -10,6 +10,10 @@ public class VsyncWaiter {
// This estimate will be updated by FlutterView when it is attached to a Display.
public static long refreshPeriodNanos = 1000000000 / 60;
// This should also be updated by FlutterView when it is attached to a Display.
// The initial value of 0.0 indicates unkonwn refresh rate.
public static float refreshRateFPS = 0.0f;
public static void asyncWaitForVsync(final long cookie) {
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
@Override
......
......@@ -81,6 +81,22 @@ bool VsyncWaiterAndroid::Register(JNIEnv* env) {
return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
}
float VsyncWaiterAndroid::GetDisplayRefreshRate() const {
JNIEnv* env = fml::jni::AttachCurrentThread();
if (g_vsync_waiter_class == nullptr) {
return kUnknownRefreshRateFPS;
}
jclass clazz = g_vsync_waiter_class->obj();
if (clazz == nullptr) {
return kUnknownRefreshRateFPS;
}
jfieldID fid = env->GetStaticFieldID(clazz, "refreshRateFPS", "F");
// We can safely read this 32-bit float from Java in any thread because
// 32-bits read and write are guaranteed to be atomic:
// https://stackoverflow.com/questions/11459543/should-getters-and-setters-be-synchronized/11459616#11459616
return env->GetStaticFloatField(clazz, fid);
}
static void ConsumePendingCallback(jlong java_baton,
fml::TimePoint frame_start_time,
fml::TimePoint frame_target_time) {
......
......@@ -21,6 +21,8 @@ class VsyncWaiterAndroid final : public VsyncWaiter {
~VsyncWaiterAndroid() override;
float GetDisplayRefreshRate() const override;
private:
// |shell::VsyncWaiter|
void AwaitVSync() override;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册