Add support for setting thread priority in embedder.h and update windows embedding to do so (flutter/engine#31778)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "flutter/fml/closure.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/fml/native_library.h"
|
||||
#include "flutter/fml/thread.h"
|
||||
#include "third_party/dart/runtime/bin/elf_loader.h"
|
||||
#include "third_party/dart/runtime/include/dart_native_api.h"
|
||||
|
||||
@@ -1450,10 +1451,33 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr);
|
||||
auto thread_config_callback = [&custom_task_runners](
|
||||
const fml::Thread::ThreadConfig& config) {
|
||||
fml::Thread::SetCurrentThreadName(config);
|
||||
if (!custom_task_runners || !custom_task_runners->thread_priority_setter) {
|
||||
return;
|
||||
}
|
||||
FlutterThreadPriority priority = FlutterThreadPriority::kNormal;
|
||||
switch (config.priority) {
|
||||
case fml::Thread::ThreadPriority::BACKGROUND:
|
||||
priority = FlutterThreadPriority::kBackground;
|
||||
break;
|
||||
case fml::Thread::ThreadPriority::NORMAL:
|
||||
priority = FlutterThreadPriority::kNormal;
|
||||
break;
|
||||
case fml::Thread::ThreadPriority::DISPLAY:
|
||||
priority = FlutterThreadPriority::kDisplay;
|
||||
break;
|
||||
case fml::Thread::ThreadPriority::RASTER:
|
||||
priority = FlutterThreadPriority::kRaster;
|
||||
break;
|
||||
}
|
||||
custom_task_runners->thread_priority_setter(priority);
|
||||
};
|
||||
auto thread_host =
|
||||
flutter::EmbedderThreadHost::CreateEmbedderOrEngineManagedThreadHost(
|
||||
SAFE_ACCESS(args, custom_task_runners, nullptr));
|
||||
custom_task_runners, thread_config_callback);
|
||||
|
||||
if (!thread_host || !thread_host->IsValid()) {
|
||||
return LOG_EMBEDDER_ERROR(kInvalidArguments,
|
||||
|
||||
@@ -226,6 +226,18 @@ typedef enum {
|
||||
kFlutterTextDirectionLTR = 2,
|
||||
} FlutterTextDirection;
|
||||
|
||||
/// Valid values for priority of Thread.
|
||||
typedef enum {
|
||||
/// Suitable for threads that shouldn't disrupt high priority work.
|
||||
kBackground = 0,
|
||||
/// Default priority level.
|
||||
kNormal = 1,
|
||||
/// Suitable for threads which generate data for the display.
|
||||
kDisplay = 2,
|
||||
/// Suitable for thread which raster data.
|
||||
kRaster = 3,
|
||||
} FlutterThreadPriority;
|
||||
|
||||
typedef struct _FlutterEngine* FLUTTER_API_SYMBOL(FlutterEngine);
|
||||
|
||||
typedef struct {
|
||||
@@ -1061,6 +1073,9 @@ typedef struct {
|
||||
/// and platform task runners. This makes the Flutter engine use the same
|
||||
/// thread for both task runners.
|
||||
const FlutterTaskRunnerDescription* render_task_runner;
|
||||
/// Specify a callback that is used to set the thread priority for embedder
|
||||
/// task runners.
|
||||
void (*thread_priority_setter)(FlutterThreadPriority);
|
||||
} FlutterCustomTaskRunners;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -261,6 +261,8 @@ bool FlutterWindowsEngine::RunWithEntrypoint(const char* entrypoint) {
|
||||
FlutterCustomTaskRunners custom_task_runners = {};
|
||||
custom_task_runners.struct_size = sizeof(FlutterCustomTaskRunners);
|
||||
custom_task_runners.platform_task_runner = &platform_task_runner;
|
||||
custom_task_runners.thread_priority_setter =
|
||||
&WindowsPlatformThreadPrioritySetter;
|
||||
|
||||
FlutterProjectArgs args = {};
|
||||
args.struct_size = sizeof(FlutterProjectArgs);
|
||||
|
||||
@@ -32,6 +32,32 @@ namespace flutter {
|
||||
|
||||
class FlutterWindowsView;
|
||||
|
||||
// Update the thread priority for the Windows engine.
|
||||
static void WindowsPlatformThreadPrioritySetter(
|
||||
FlutterThreadPriority priority) {
|
||||
// TODO(99502): Add support for tracing to the windows embedding so we can
|
||||
// mark thread priorities and success/failure.
|
||||
switch (priority) {
|
||||
case FlutterThreadPriority::kBackground: {
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
break;
|
||||
}
|
||||
case FlutterThreadPriority::kDisplay: {
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
break;
|
||||
}
|
||||
case FlutterThreadPriority::kRaster: {
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
break;
|
||||
}
|
||||
case FlutterThreadPriority::kNormal: {
|
||||
// For normal or default priority we do not need to set the priority
|
||||
// class.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Manages state associated with the underlying FlutterEngine that isn't
|
||||
// related to its display.
|
||||
//
|
||||
@@ -163,9 +189,7 @@ class FlutterWindowsEngine {
|
||||
void UpdateSemanticsEnabled(bool enabled);
|
||||
|
||||
// Returns true if the semantics tree is enabled.
|
||||
bool semantics_enabled() const {
|
||||
return semantics_enabled_;
|
||||
}
|
||||
bool semantics_enabled() const { return semantics_enabled_; }
|
||||
|
||||
// Returns the native accessibility node with the given id.
|
||||
gfx::NativeViewAccessible GetNativeAccessibleFromId(AccessibilityNodeId id);
|
||||
|
||||
@@ -66,9 +66,14 @@ TEST(FlutterWindowsEngine, RunDoesExpectedInitialization) {
|
||||
EXPECT_EQ(strcmp(args->dart_entrypoint_argv[1], "arg2"), 0);
|
||||
EXPECT_NE(args->platform_message_callback, nullptr);
|
||||
EXPECT_NE(args->custom_task_runners, nullptr);
|
||||
EXPECT_NE(args->custom_task_runners->thread_priority_setter, nullptr);
|
||||
EXPECT_EQ(args->custom_dart_entrypoint, nullptr);
|
||||
EXPECT_NE(args->vsync_callback, nullptr);
|
||||
|
||||
args->custom_task_runners->thread_priority_setter(
|
||||
FlutterThreadPriority::kRaster);
|
||||
EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
|
||||
THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
return kSuccess;
|
||||
}));
|
||||
|
||||
@@ -318,6 +323,27 @@ TEST(FlutterWindowsEngine, DispatchSemanticsAction) {
|
||||
EXPECT_TRUE(called);
|
||||
}
|
||||
|
||||
TEST(FlutterWindowsEngine, SetsThreadPriority) {
|
||||
WindowsPlatformThreadPrioritySetter(FlutterThreadPriority::kBackground);
|
||||
EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
|
||||
THREAD_PRIORITY_BELOW_NORMAL);
|
||||
|
||||
WindowsPlatformThreadPrioritySetter(FlutterThreadPriority::kDisplay);
|
||||
EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
|
||||
THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
WindowsPlatformThreadPrioritySetter(FlutterThreadPriority::kRaster);
|
||||
EXPECT_EQ(GetThreadPriority(GetCurrentThread()),
|
||||
THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
// FlutterThreadPriority::kNormal does not change thread priority, reset to 0
|
||||
// here.
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
|
||||
|
||||
WindowsPlatformThreadPrioritySetter(FlutterThreadPriority::kNormal);
|
||||
EXPECT_EQ(GetThreadPriority(GetCurrentThread()), THREAD_PRIORITY_NORMAL);
|
||||
}
|
||||
|
||||
TEST(FlutterWindowsEngine, AddPluginRegistrarDestructionCallback) {
|
||||
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
|
||||
EngineModifier modifier(engine.get());
|
||||
|
||||
Reference in New Issue
Block a user