#define FML_USED_ON_EMBEDDER
#include "flutter/shell/platform/ohos/ohos_shell_holder.h"
#include <pthread.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sstream>
#include <string>
#include <utility>
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/platform/ohos/platform_task_runner_adapter.h"
#include "flutter/shell/platform/ohos/platform_view_ohos.h"
namespace flutter {
OhosShellHolder::OhosShellHolder(
flutter::Settings settings,
bool is_background_view)
: settings_(std::move(settings))
{
static size_t shell_count = 1;
auto thread_label = std::to_string(shell_count++);
uint64_t type_mask = 0;
if (is_background_view) {
type_mask |= ThreadHost::Type::UI;
} else {
if (!settings_.platform_as_ui_thread) {
type_mask |= ThreadHost::Type::UI;
}
if (!settings_.use_system_render_thread) {
type_mask |= ThreadHost::Type::GPU;
}
if (settings_.use_io_thread) {
type_mask |= ThreadHost::Type::IO;
}
type_mask |= ThreadHost::Type::Platform;
thread_host_ = {thread_label, type_mask};
}
fml::WeakPtr<PlatformViewOhos> weak_platform_view;
Shell::CreateCallback<PlatformView> on_create_platform_view =
[&weak_platform_view](Shell& shell) {
std::unique_ptr<PlatformViewOhos> platform_view_ohos;
if (shell.GetSettings().enable_software_rendering) {
platform_view_ohos = std::make_unique<PlatformViewOhos>(shell, shell.GetTaskRunners(), true);
}
weak_platform_view = platform_view_ohos->GetWeakPtr();
return platform_view_ohos;
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
};
fml::MessageLoop::EnsureInitializedForCurrentThread();
fml::RefPtr<fml::TaskRunner> gpu_runner;
fml::RefPtr<fml::TaskRunner> ui_runner;
fml::RefPtr<fml::TaskRunner> io_runner;
fml::RefPtr<fml::TaskRunner> platform_runner = thread_host_.platform_thread->GetTaskRunner();
if (is_background_view) {
auto single_task_runner = thread_host_.ui_thread->GetTaskRunner();
gpu_runner = single_task_runner;
ui_runner = single_task_runner;
io_runner = single_task_runner;
} else {
if (settings_.platform_as_ui_thread) {
ui_runner = platform_runner;
} else {
ui_runner = thread_host_.ui_thread->GetTaskRunner();
}
if (!settings_.use_system_render_thread) {
gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
} else {
gpu_runner = ui_runner;
}
if (settings_.use_io_thread) {
io_runner = thread_host_.io_thread->GetTaskRunner();
} else {
io_runner = ui_runner;
}
}
flutter::TaskRunners task_runners(thread_label,
platform_runner,
gpu_runner,
ui_runner,
io_runner
);
shell_ =
Shell::Create(task_runners,
settings_,
on_create_platform_view,
on_create_rasterizer
);
platform_view_ = weak_platform_view;
FML_DCHECK(platform_view_);
is_valid_ = shell_ != nullptr;
if (is_valid_) {
task_runners.GetGPUTaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
if (::setpriority(PRIO_PROCESS, gettid(), -2) != 0) {
FML_LOG(ERROR) << "Failed to set GPU task runner priority";
}
}
});
task_runners.GetUITaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
FML_LOG(ERROR) << "Failed to set UI task runner priority";
}
});
}
}
OhosShellHolder::~OhosShellHolder()
{
shell_.reset();
thread_host_.Reset();
}
bool OhosShellHolder::IsValid() const
{
return is_valid_;
}
const flutter::Settings& OhosShellHolder::GetSettings() const
{
return settings_;
}
void OhosShellHolder::Launch(RunConfiguration config)
{
if (!IsValid()) {
return;
}
shell_->RunEngine(std::move(config));
}
Rasterizer::Screenshot OhosShellHolder::Screenshot(
Rasterizer::ScreenshotType type,
bool base64_encode)
{
if (!IsValid()) {
return {nullptr, SkISize::MakeEmpty()};
}
return shell_->Screenshot(type, base64_encode);
}
fml::WeakPtr<PlatformViewOhos> OhosShellHolder::GetPlatformView()
{
FML_DCHECK(platform_view_);
return platform_view_;
}
}