Skip to content

Commit

Permalink
impeller: add impeller initial implementation (#355)
Browse files Browse the repository at this point in the history
Signed-off-by: Hidenori Matsubayashi <[email protected]>
  • Loading branch information
HidenoriMatsubayashi authored Aug 4, 2023
1 parent a172143 commit 9f08f4c
Show file tree
Hide file tree
Showing 22 changed files with 155 additions and 48 deletions.
2 changes: 0 additions & 2 deletions src/flutter/shell/platform/common/engine_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ std::vector<std::string> GetSwitchesFromEnvironment() {
// Read engine switches from the environment in debug/profile. If release mode
// support is needed in the future, it should likely use a whitelist.
#ifndef FLUTTER_RELEASE
#ifndef WINUWP
const char* switch_count_key = "FLUTTER_ENGINE_SWITCHES";
const int kMaxSwitchCount = 50;
const char* switch_count_string = std::getenv(switch_count_key);
Expand All @@ -37,7 +36,6 @@ std::vector<std::string> GetSwitchesFromEnvironment() {
<< ", but " << switch_key.str() << " is missing." << std::endl;
}
}
#endif // !WINUWP
#endif // !FLUTTER_RELEASE
return switches;
}
Expand Down
5 changes: 1 addition & 4 deletions src/flutter/shell/platform/linux_embedded/flutter_elinux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,10 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
auto state = std::make_unique<FlutterDesktopViewControllerState>();
state->view =
std::make_unique<flutter::FlutterELinuxView>(std::move(window_wrapper));
if (!state->view->CreateRenderSurface()) {
return nullptr;
}

// Take ownership of the engine, starting it if necessary.
state->view->SetEngine(
std::unique_ptr<flutter::FlutterELinuxEngine>(EngineFromHandle(engine)));
state->view->CreateRenderSurface();
if (!state->view->GetEngine()->running()) {
if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) {
return nullptr;
Expand Down
10 changes: 10 additions & 0 deletions src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project)
}
});

// Check for impeller support.
auto& switches = project_->GetSwitches();
enable_impeller_ = std::find(switches.begin(), switches.end(),
"--enable-impeller=true") != switches.end();

// Set up the legacy structs backing the API handles.
messenger_ = FlutterDesktopMessengerReferenceOwner(
FlutterDesktopMessengerAddRef(new FlutterDesktopMessenger()),
Expand Down Expand Up @@ -173,6 +178,11 @@ FlutterELinuxEngine::~FlutterELinuxEngine() {
Stop();
}

void FlutterELinuxEngine::SetSwitches(
const std::vector<std::string>& switches) {
project_->SetSwitches(switches);
}

bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) {
if (!project_->HasValidPaths()) {
ELINUX_LOG(ERROR) << "Missing or unresolvable paths to assets.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ class FlutterELinuxEngine {
void SetPluginRegistrarDestructionCallback(
FlutterDesktopOnPluginRegistrarDestroyed callback);

// Sets switches member to the given switches.
void SetSwitches(const std::vector<std::string>& switches);

FlutterDesktopMessengerRef messenger() { return messenger_.get(); }

IncomingMessageDispatcher* message_dispatcher() {
Expand Down Expand Up @@ -121,6 +124,9 @@ class FlutterELinuxEngine {
void OnVsync(uint64_t last_frame_time_nanos,
uint64_t vsync_interval_time_nanos);

// Gets the status whether Impeller is enabled.
bool IsImpellerEnabled() const { return enable_impeller_; }

private:
// Allows swapping out embedder_api_ calls in tests.
friend class EngineEmbedderApiModifier;
Expand Down Expand Up @@ -176,6 +182,8 @@ class FlutterELinuxEngine {

// The vsync waiter.
std::unique_ptr<VsyncWaiter> vsync_waiter_;

bool enable_impeller_ = false;
};

} // namespace flutter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,10 @@ bool FlutterELinuxView::MakeResourceCurrent() {

bool FlutterELinuxView::CreateRenderSurface() {
PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
return binding_handler_->CreateRenderSurface(bounds.width, bounds.height);
auto impeller_enable = engine_.get()->IsImpellerEnabled();
std::cout << "impeller: " << impeller_enable << std::endl;
return binding_handler_->CreateRenderSurface(bounds.width, bounds.height,
impeller_enable);
}

void FlutterELinuxView::DestroyRenderSurface() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,23 @@ UniqueAotDataPtr FlutterProjectBundle::LoadAotData(
return UniqueAotDataPtr(data);
}

void FlutterProjectBundle::SetSwitches(
const std::vector<std::string>& switches) {
engine_switches_ = switches;
}

const std::vector<std::string> FlutterProjectBundle::GetSwitches() {
return GetSwitchesFromEnvironment();
if (engine_switches_.size() == 0) {
return GetSwitchesFromEnvironment();
}
std::vector<std::string> switches;
switches.insert(switches.end(), engine_switches_.begin(),
engine_switches_.end());

auto env_switches = GetSwitchesFromEnvironment();
switches.insert(switches.end(), env_switches.begin(), env_switches.end());

return switches;
}

const std::string FlutterProjectBundle::GetExecutableDirectory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class FlutterProjectBundle {
// Returns any switches that should be passed to the engine.
const std::vector<std::string> GetSwitches();

// Sets engine switches.
void SetSwitches(const std::vector<std::string>& switches);

// Attempts to load AOT data for this bundle. The returned data must be
// retained until any engine instance it is passed to has been shut down.
//
Expand All @@ -69,6 +72,9 @@ class FlutterProjectBundle {

// Dart entrypoint arguments.
std::vector<std::string> dart_entrypoint_arguments_;

// Engine switches.
std::vector<std::string> engine_switches_;
};

} // namespace flutter
Expand Down
57 changes: 52 additions & 5 deletions src/flutter/shell/platform/linux_embedded/surface/context_egl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace flutter {

ContextEgl::ContextEgl(std::unique_ptr<EnvironmentEgl> environment,
bool enable_impeller,
EGLint egl_surface_type)
: environment_(std::move(environment)), config_(nullptr) {
EGLint config_count = 0;
Expand All @@ -28,11 +29,57 @@ ContextEgl::ContextEgl(std::unique_ptr<EnvironmentEgl> environment,
EGL_NONE
// clang-format on
};
if (eglChooseConfig(environment_->Display(), attribs, &config_, 1,
&config_count) != EGL_TRUE) {
ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: "
<< get_egl_error_cause();
return;
const EGLint impeller_config_attributes[] = {
// clang-format off
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
#if defined(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER)
EGL_ALPHA_SIZE, 8,
#endif
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 8,
EGL_SAMPLE_BUFFERS, 1,
EGL_SAMPLES, 4,
EGL_NONE
// clang-format on
};
const EGLint impeller_config_attributes_no_msaa[] = {
// clang-format off
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
#if defined(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER)
EGL_ALPHA_SIZE, 8,
#endif
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 8,
EGL_NONE
// clang-format on
};

if (enable_impeller) {
// First try the MSAA configuration.
if ((eglChooseConfig(environment_->Display(), impeller_config_attributes,
&config_, 1, &config_count) == EGL_FALSE) ||
(config_count == 0)) {
// Next fall back to disabled MSAA.
if ((eglChooseConfig(environment_->Display(),
impeller_config_attributes_no_msaa, &config_, 1,
&config_count) == EGL_FALSE) ||
(config_count == 0)) {
ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: "
<< get_egl_error_cause();
return;
}
}
} else {
if (eglChooseConfig(environment_->Display(), attribs, &config_, 1,
&config_count) != EGL_TRUE) {
ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: "
<< get_egl_error_cause();
return;
}
}

if (config_count == 0 || config_ == nullptr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace flutter {
class ContextEgl {
public:
ContextEgl(std::unique_ptr<EnvironmentEgl> environment,
bool enable_impeller,
EGLint egl_surface_type = EGL_WINDOW_BIT);
~ContextEgl() = default;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -109,7 +109,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler {
}

// |FlutterWindowBindingHandler|
bool CreateRenderSurface(int32_t width, int32_t height) override {
bool CreateRenderSurface(int32_t width,
int32_t height,
bool enable_impeller) override {
std::vector<std::string> devices;
auto device_filename = std::getenv(kFlutterDrmDeviceEnvironmentKey);
if (device_filename && device_filename[0] != '\0') {
Expand Down Expand Up @@ -148,7 +150,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler {

display_valid_ = true;

render_surface_ = native_window_->CreateRenderSurface();
render_surface_ = native_window_->CreateRenderSurface(enable_impeller);
if (!render_surface_->SetNativeWindow(native_window_.get())) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -1147,7 +1147,8 @@ bool ELinuxWindowWayland::DispatchEvent() {
}

bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px,
int32_t height_px) {
int32_t height_px,
bool enable_impeller) {
if (!display_valid_) {
ELINUX_LOG(ERROR) << "Wayland display is invalid.";
return false;
Expand Down Expand Up @@ -1225,15 +1226,16 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px,
wl_surface_commit(native_window_->Surface());

render_surface_ = std::make_unique<SurfaceGl>(std::make_unique<ContextEgl>(
std::make_unique<EnvironmentEgl>(wl_display_)));
std::make_unique<EnvironmentEgl>(wl_display_), enable_impeller));
render_surface_->SetNativeWindow(native_window_.get());

if (view_properties_.use_window_decoration) {
int32_t width_dip = width_px / current_scale_;
int32_t height_dip = height_px / current_scale_;
window_decorations_ = std::make_unique<WindowDecorationsWayland>(
wl_display_, wl_compositor_, wl_subcompositor_,
native_window_->Surface(), width_dip, height_dip, current_scale_);
native_window_->Surface(), width_dip, height_dip, current_scale_,
enable_impeller);
}

// Wait for making sure that xdg_surface has been configured.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -45,7 +45,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler {
bool DispatchEvent() override;

// |FlutterWindowBindingHandler|
bool CreateRenderSurface(int32_t width_px, int32_t height_px) override;
bool CreateRenderSurface(int32_t width_px,
int32_t height_px,
bool enable_impeller) override;

// |FlutterWindowBindingHandler|
void DestroyRenderSurface() override;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -121,9 +121,11 @@ bool ELinuxWindowX11::DispatchEvent() {
return true;
}

bool ELinuxWindowX11::CreateRenderSurface(int32_t width, int32_t height) {
auto context_egl =
std::make_unique<ContextEgl>(std::make_unique<EnvironmentEgl>(display_));
bool ELinuxWindowX11::CreateRenderSurface(int32_t width,
int32_t height,
bool enable_impeller) {
auto context_egl = std::make_unique<ContextEgl>(
std::make_unique<EnvironmentEgl>(display_), enable_impeller);

if (current_rotation_ == 90 || current_rotation_ == 270) {
std::swap(width, height);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -26,7 +26,9 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler {
bool DispatchEvent() override;

// |FlutterWindowBindingHandler|
bool CreateRenderSurface(int32_t width, int32_t height) override;
bool CreateRenderSurface(int32_t width,
int32_t height,
bool enable_impeller) override;

// |FlutterWindowBindingHandler|
void DestroyRenderSurface() override;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -31,7 +31,8 @@ class NativeWindowDrm : public NativeWindow {

virtual bool DismissCursor() = 0;

virtual std::unique_ptr<SurfaceGl> CreateRenderSurface() = 0;
virtual std::unique_ptr<SurfaceGl> CreateRenderSurface(
bool enable_impeller) = 0;

protected:
drmModeConnectorPtr FindConnector(drmModeResPtr resources);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -91,7 +91,8 @@ bool NativeWindowDrmEglstream::DismissCursor() {
return true;
}

std::unique_ptr<SurfaceGl> NativeWindowDrmEglstream::CreateRenderSurface() {
std::unique_ptr<SurfaceGl> NativeWindowDrmEglstream::CreateRenderSurface(
bool enable_impeller) {
return std::make_unique<SurfaceGl>(std::make_unique<ContextEglStream>(
std::make_unique<EnvironmentEglStream>()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Sony Corporation. All rights reserved.
// Copyright 2023 Sony Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -32,7 +32,7 @@ class NativeWindowDrmEglstream : public NativeWindowDrm {
bool DismissCursor() override;

// |NativeWindowDrm|
std::unique_ptr<SurfaceGl> CreateRenderSurface() override;
std::unique_ptr<SurfaceGl> CreateRenderSurface(bool enable_impeller) override;

// |NativeWindow|
bool Resize(const size_t width, const size_t height) override;
Expand Down
Loading

0 comments on commit 9f08f4c

Please sign in to comment.