forked from firka/flutter
Add waitUIThreadIdle service RPC (flutter/engine#3898)
In https://github.com/flutter/engine/pull/3833 the `_flutter.listViews` RPC moved from thread based to lock based synchronization. The thread based synchronization side effect was used by flutter benchmarks in https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/vmservice.dart#L1223 and https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/run_hot.dart#L156 to ensure the completeness of the restart/reload and so correct timing. A new RPC `_flutter.flushUIThreadTasks` is introduced to allow the flutter benchmarks to reintroduce thread based synchronization. Related https://github.com/flutter/flutter/issues/11241
This commit is contained in:
committed by
GitHub
parent
eb44210a77
commit
e7cd520490
@@ -128,6 +128,9 @@ void PlatformViewServiceProtocol::RegisterHook(bool running_precompiled_code) {
|
||||
}
|
||||
Dart_RegisterRootServiceRequestCallback(kRunInViewExtensionName, &RunInView,
|
||||
nullptr);
|
||||
// [benchmark helper] Wait for the UI Thread to idle.
|
||||
Dart_RegisterRootServiceRequestCallback(kFlushUIThreadTasksExtensionName,
|
||||
&FlushUIThreadTasks, nullptr);
|
||||
}
|
||||
|
||||
const char* PlatformViewServiceProtocol::kRunInViewExtensionName =
|
||||
@@ -202,11 +205,10 @@ bool PlatformViewServiceProtocol::ListViews(const char* method,
|
||||
intptr_t num_params,
|
||||
void* user_data,
|
||||
const char** json_object) {
|
||||
// Ask the Shell for the list of platform views. This will run a task on
|
||||
// the UI thread before returning.
|
||||
// Ask the Shell for the list of platform views.
|
||||
Shell& shell = Shell::Shared();
|
||||
std::vector<Shell::PlatformViewInfo> platform_views;
|
||||
shell.WaitForPlatformViewIds(&platform_views);
|
||||
shell.GetPlatformViewIds(&platform_views);
|
||||
|
||||
std::stringstream response;
|
||||
|
||||
@@ -314,4 +316,32 @@ void PlatformViewServiceProtocol::ScreenshotGpuTask(SkBitmap* bitmap) {
|
||||
canvas->flush();
|
||||
}
|
||||
|
||||
const char* PlatformViewServiceProtocol::kFlushUIThreadTasksExtensionName =
|
||||
"_flutter.flushUIThreadTasks";
|
||||
|
||||
// This API should not be invoked by production code.
|
||||
// It can potentially starve the service isolate if the main isolate pauses
|
||||
// at a breakpoint or is in an infinite loop.
|
||||
//
|
||||
// It should be invoked from the VM Service and and blocks it until UI thread
|
||||
// tasks are processed.
|
||||
bool PlatformViewServiceProtocol::FlushUIThreadTasks(const char* method,
|
||||
const char** param_keys,
|
||||
const char** param_values,
|
||||
intptr_t num_params,
|
||||
void* user_data,
|
||||
const char** json_object) {
|
||||
ftl::AutoResetWaitableEvent latch;
|
||||
blink::Threads::UI()->PostTask([&latch]() {
|
||||
// This task is empty because we just need to synchronize this RPC with the
|
||||
// UI Thread
|
||||
latch.Signal();
|
||||
});
|
||||
|
||||
latch.Wait();
|
||||
|
||||
*json_object = strdup("{\"type\":\"Success\"}");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -20,6 +20,8 @@ class PlatformViewServiceProtocol {
|
||||
|
||||
private:
|
||||
static const char* kRunInViewExtensionName;
|
||||
// It should be invoked from the VM Service and and blocks it until previous
|
||||
// UI thread tasks are processed.
|
||||
static bool RunInView(const char* method,
|
||||
const char** param_keys,
|
||||
const char** param_values,
|
||||
@@ -36,6 +38,8 @@ class PlatformViewServiceProtocol {
|
||||
const char** json_object);
|
||||
|
||||
static const char* kScreenshotExtensionName;
|
||||
// It should be invoked from the VM Service and and blocks it until previous
|
||||
// GPU thread tasks are processed.
|
||||
static bool Screenshot(const char* method,
|
||||
const char** param_keys,
|
||||
const char** param_values,
|
||||
@@ -43,6 +47,20 @@ class PlatformViewServiceProtocol {
|
||||
void* user_data,
|
||||
const char** json_object);
|
||||
static void ScreenshotGpuTask(SkBitmap* bitmap);
|
||||
|
||||
// This API should not be invoked by production code.
|
||||
// It can potentially starve the service isolate if the main isolate pauses
|
||||
// at a breakpoint or is in an infinite loop.
|
||||
//
|
||||
// It should be invoked from the VM Service and and blocks it until previous
|
||||
// GPU thread tasks are processed.
|
||||
static const char* kFlushUIThreadTasksExtensionName;
|
||||
static bool FlushUIThreadTasks(const char* method,
|
||||
const char** param_keys,
|
||||
const char** param_values,
|
||||
intptr_t num_params,
|
||||
void* user_data,
|
||||
const char** json_object);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -262,7 +262,7 @@ void Shell::GetPlatformViews(
|
||||
*platform_views = platform_views_;
|
||||
}
|
||||
|
||||
void Shell::WaitForPlatformViewIds(
|
||||
void Shell::GetPlatformViewIds(
|
||||
std::vector<PlatformViewInfo>* platform_view_ids) {
|
||||
std::lock_guard<std::mutex> lk(platform_views_mutex_);
|
||||
for (auto it = platform_views_.begin(); it != platform_views_.end(); it++) {
|
||||
|
||||
@@ -44,7 +44,7 @@ class Shell {
|
||||
|
||||
// List of PlatformViews.
|
||||
|
||||
// These APIs must only be accessed on UI thread.
|
||||
// These APIs can be called from any thread.
|
||||
void AddPlatformView(const std::shared_ptr<PlatformView>& platform_view);
|
||||
void PurgePlatformViews();
|
||||
void GetPlatformViews(
|
||||
@@ -58,7 +58,7 @@ class Shell {
|
||||
|
||||
// These APIs can be called from any thread.
|
||||
// Return the list of platform view ids at the time of this call.
|
||||
void WaitForPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
|
||||
void GetPlatformViewIds(std::vector<PlatformViewInfo>* platform_view_ids);
|
||||
|
||||
// Attempt to run a script inside a flutter view indicated by |view_id|.
|
||||
// Will set |view_existed| to true if the view was found and false otherwise.
|
||||
|
||||
Reference in New Issue
Block a user