Skip to content

Commit

Permalink
Refactor FlutterEngine usage in Linux shell (flutter#17363)
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-ancell authored Apr 23, 2020
1 parent 371a8a0 commit 12012f1
Show file tree
Hide file tree
Showing 12 changed files with 656 additions and 182 deletions.
7 changes: 7 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1162,8 +1162,15 @@ FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.cc
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ source_set("flutter_linux") {

sources = [
"fl_dart_project.cc",
"fl_engine.cc",
"fl_renderer.cc",
"fl_renderer_x11.cc",
"fl_view.cc",
]

Expand Down
159 changes: 159 additions & 0 deletions shell/platform/linux/fl_engine.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_renderer.h"

#include <gmodule.h>

struct _FlEngine {
GObject parent_instance;

FlDartProject* project;
FlRenderer* renderer;
FLUTTER_API_SYMBOL(FlutterEngine) engine;
};

G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error)

G_DEFINE_TYPE(FlEngine, fl_engine, G_TYPE_OBJECT)

// Callback from Flutter engine that are passed to the renderer

static void* fl_engine_gl_proc_resolver(void* user_data, const char* name) {
FlEngine* self = static_cast<FlEngine*>(user_data);
return fl_renderer_get_proc_address(self->renderer, name);
}

static bool fl_engine_gl_make_current(void* user_data) {
FlEngine* self = static_cast<FlEngine*>(user_data);
g_autoptr(GError) error = nullptr;
gboolean result = fl_renderer_make_current(self->renderer, &error);
if (!result)
g_warning("%s", error->message);
return result;
}

static bool fl_engine_gl_clear_current(void* user_data) {
FlEngine* self = static_cast<FlEngine*>(user_data);
g_autoptr(GError) error = nullptr;
gboolean result = fl_renderer_clear_current(self->renderer, &error);
if (!result)
g_warning("%s", error->message);
return result;
}

static uint32_t fl_engine_gl_fbo_callback(void* user_data) {
FlEngine* self = static_cast<FlEngine*>(user_data);
return fl_renderer_get_fbo(self->renderer);
}

static bool fl_engine_gl_present(void* user_data) {
FlEngine* self = static_cast<FlEngine*>(user_data);
g_autoptr(GError) error = nullptr;
gboolean result = fl_renderer_present(self->renderer, &error);
if (!result)
g_warning("%s", error->message);
return result;
}

static void fl_engine_dispose(GObject* object) {
FlEngine* self = FL_ENGINE(object);

g_clear_object(&self->project);
g_clear_object(&self->renderer);

FlutterEngineShutdown(self->engine);

G_OBJECT_CLASS(fl_engine_parent_class)->dispose(object);
}

static void fl_engine_class_init(FlEngineClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_engine_dispose;
}

static void fl_engine_init(FlEngine* self) {}

FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer) {
g_return_val_if_fail(FL_IS_DART_PROJECT(project), nullptr);
g_return_val_if_fail(FL_IS_RENDERER(renderer), nullptr);

FlEngine* self =
static_cast<FlEngine*>(g_object_new(fl_engine_get_type(), nullptr));
self->project = static_cast<FlDartProject*>(g_object_ref(project));
self->renderer = static_cast<FlRenderer*>(g_object_ref(renderer));
return self;
}

gboolean fl_engine_start(FlEngine* self, GError** error) {
g_return_val_if_fail(FL_IS_ENGINE(self), FALSE);

if (!fl_renderer_start(self->renderer, error))
return FALSE;

FlutterRendererConfig config = {};
config.type = kOpenGL;
config.open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig);
config.open_gl.gl_proc_resolver = fl_engine_gl_proc_resolver;
config.open_gl.make_current = fl_engine_gl_make_current;
config.open_gl.clear_current = fl_engine_gl_clear_current;
config.open_gl.fbo_callback = fl_engine_gl_fbo_callback;
config.open_gl.present = fl_engine_gl_present;

FlutterProjectArgs args = {};
args.struct_size = sizeof(FlutterProjectArgs);
args.assets_path = fl_dart_project_get_assets_path(self->project);
args.icu_data_path = fl_dart_project_get_icu_data_path(self->project);

FlutterEngineResult result = FlutterEngineInitialize(
FLUTTER_ENGINE_VERSION, &config, &args, self, &self->engine);
if (result != kSuccess) {
g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
"Failed to initialize Flutter engine");
return FALSE;
}

result = FlutterEngineRunInitialized(self->engine);
if (result != kSuccess) {
g_set_error(error, fl_engine_error_quark(), FL_ENGINE_ERROR_FAILED,
"Failed to run Flutter engine");
return FALSE;
}

return TRUE;
}

void fl_engine_send_window_metrics_event(FlEngine* self,
size_t width,
size_t height,
double pixel_ratio) {
g_return_if_fail(FL_IS_ENGINE(self));

FlutterWindowMetricsEvent event = {};
event.struct_size = sizeof(FlutterWindowMetricsEvent);
event.width = width;
event.height = height;
event.pixel_ratio = pixel_ratio;
FlutterEngineSendWindowMetricsEvent(self->engine, &event);
}

void fl_engine_send_mouse_pointer_event(FlEngine* self,
FlutterPointerPhase phase,
size_t timestamp,
double x,
double y,
int64_t buttons) {
g_return_if_fail(FL_IS_ENGINE(self));

FlutterPointerEvent fl_event = {};
fl_event.struct_size = sizeof(fl_event);
fl_event.phase = phase;
fl_event.timestamp = timestamp;
fl_event.x = x;
fl_event.y = y;
fl_event.device_kind = kFlutterPointerDeviceKindMouse;
fl_event.buttons = buttons;
FlutterEngineSendPointerEvent(self->engine, &fl_event, 1);
}
85 changes: 85 additions & 0 deletions shell/platform/linux/fl_engine_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_

#include <glib-object.h>

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/linux/fl_renderer.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"

G_BEGIN_DECLS

/**
* FlEngineError:
* Errors for #FlEngine objects to set on failures.
*/

typedef enum {
FL_ENGINE_ERROR_FAILED,
} FlEngineError;

GQuark fl_engine_error_quark(void) G_GNUC_CONST;

/**
* fl_engine_new:
* @project: a #FlDartProject
* @renderer: a #FlRenderer
*
* Creates a new Flutter engine.
*
* Returns: a #FlEngine
*/
FlEngine* fl_engine_new(FlDartProject* project, FlRenderer* renderer);

/**
* fl_engine_start:
* @engine: a #FlEngine
* @error: (allow-none): #GError location to store the error occurring, or %NULL
* to ignore.
*
* Starts the Flutter engine.
*
* Returns: %TRUE on success
*/
gboolean fl_engine_start(FlEngine* engine, GError** error);

/**
* fl_engine_send_window_metrics_event:
* @engine: a #FlEngine
* @width: width of the window in pixels.
* @height: height of the window in pixels.
* @pixel_ratio: scale factor for window.
*
* Sends a window metrics event to the engine.
*/
void fl_engine_send_window_metrics_event(FlEngine* engine,
size_t width,
size_t height,
double pixel_ratio);

/**
* fl_engine_send_mouse_pointer_event:
* @engine: a #FlEngine
* @phase: mouse phase.
* @timestamp: time when event occurred in nanoseconds.
* @x: x location of mouse cursor.
* @y: y location of mouse cursor.
* @buttons: buttons that are pressed.
*
* Sends a mouse pointer event to the engine.
*/
void fl_engine_send_mouse_pointer_event(FlEngine* engine,
FlutterPointerPhase phase,
size_t timestamp,
double x,
double y,
int64_t buttons);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_PRIVATE_H_
Loading

0 comments on commit 12012f1

Please sign in to comment.