Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
12012f13
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
12012f13
编写于
4月 24, 2020
作者:
R
Robert Ancell
提交者:
GitHub
4月 24, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor FlutterEngine usage in Linux shell (#17363)
上级
371a8a05
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
656 addition
and
182 deletion
+656
-182
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+7
-0
shell/platform/linux/BUILD.gn
shell/platform/linux/BUILD.gn
+3
-0
shell/platform/linux/fl_engine.cc
shell/platform/linux/fl_engine.cc
+159
-0
shell/platform/linux/fl_engine_private.h
shell/platform/linux/fl_engine_private.h
+85
-0
shell/platform/linux/fl_renderer.cc
shell/platform/linux/fl_renderer.cc
+139
-0
shell/platform/linux/fl_renderer.h
shell/platform/linux/fl_renderer.h
+114
-0
shell/platform/linux/fl_renderer_x11.cc
shell/platform/linux/fl_renderer_x11.cc
+33
-0
shell/platform/linux/fl_renderer_x11.h
shell/platform/linux/fl_renderer_x11.h
+39
-0
shell/platform/linux/fl_view.cc
shell/platform/linux/fl_view.cc
+37
-182
shell/platform/linux/public/flutter_linux/fl_engine.h
shell/platform/linux/public/flutter_linux/fl_engine.h
+28
-0
shell/platform/linux/public/flutter_linux/fl_view.h
shell/platform/linux/public/flutter_linux/fl_view.h
+11
-0
shell/platform/linux/public/flutter_linux/flutter_linux.h
shell/platform/linux/public/flutter_linux/flutter_linux.h
+1
-0
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
12012f13
...
...
@@ -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
...
...
shell/platform/linux/BUILD.gn
浏览文件 @
12012f13
...
...
@@ -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",
]
...
...
shell/platform/linux/fl_engine.cc
0 → 100644
浏览文件 @
12012f13
// 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
);
}
shell/platform/linux/fl_engine_private.h
0 → 100644
浏览文件 @
12012f13
// 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_
shell/platform/linux/fl_renderer.cc
0 → 100644
浏览文件 @
12012f13
// 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 "fl_renderer.h"
#include "flutter/shell/platform/embedder/embedder.h"
G_DEFINE_QUARK
(
fl_renderer_error_quark
,
fl_renderer_error
)
typedef
struct
{
EGLDisplay
egl_display
;
EGLSurface
egl_surface
;
EGLContext
egl_context
;
}
FlRendererPrivate
;
G_DEFINE_TYPE_WITH_PRIVATE
(
FlRenderer
,
fl_renderer
,
G_TYPE_OBJECT
)
// Default implementation for the start virtual method.
// Provided so subclasses can chain up to here.
static
gboolean
fl_renderer_real_start
(
FlRenderer
*
self
,
GError
**
error
)
{
FlRendererPrivate
*
priv
=
static_cast
<
FlRendererPrivate
*>
(
fl_renderer_get_instance_private
(
self
));
// Note the use of EGL_DEFAULT_DISPLAY rather than sharing an existing display
// connection (e.g. an X11 connection from GTK). This is because this EGL
// display is going to be accessed by a thread from Flutter. In the case
// of GTK/X11 the display connection is not thread safe and this would cause
// a crash.
//
priv
->
egl_display
=
eglGetDisplay
(
EGL_DEFAULT_DISPLAY
);
if
(
!
eglInitialize
(
priv
->
egl_display
,
nullptr
,
nullptr
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to initialze EGL"
);
return
FALSE
;
}
EGLint
attributes
[]
=
{
EGL_RENDERABLE_TYPE
,
EGL_OPENGL_ES2_BIT
,
EGL_RED_SIZE
,
8
,
EGL_GREEN_SIZE
,
8
,
EGL_BLUE_SIZE
,
8
,
EGL_ALPHA_SIZE
,
8
,
EGL_NONE
};
EGLConfig
egl_config
;
EGLint
n_config
;
if
(
!
eglChooseConfig
(
priv
->
egl_display
,
attributes
,
&
egl_config
,
1
,
&
n_config
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to choose EGL config"
);
return
FALSE
;
}
if
(
n_config
==
0
)
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to find appropriate EGL config"
);
return
FALSE
;
}
if
(
!
eglBindAPI
(
EGL_OPENGL_ES_API
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to bind EGL OpenGL ES API"
);
return
FALSE
;
}
priv
->
egl_surface
=
FL_RENDERER_GET_CLASS
(
self
)
->
create_surface
(
self
,
priv
->
egl_display
,
egl_config
);
EGLint
context_attributes
[]
=
{
EGL_CONTEXT_CLIENT_VERSION
,
2
,
EGL_NONE
};
priv
->
egl_context
=
eglCreateContext
(
priv
->
egl_display
,
egl_config
,
EGL_NO_CONTEXT
,
context_attributes
);
EGLint
value
;
eglQueryContext
(
priv
->
egl_display
,
priv
->
egl_context
,
EGL_CONTEXT_CLIENT_VERSION
,
&
value
);
return
TRUE
;
}
static
void
fl_renderer_class_init
(
FlRendererClass
*
klass
)
{
klass
->
start
=
fl_renderer_real_start
;
}
static
void
fl_renderer_init
(
FlRenderer
*
self
)
{}
gboolean
fl_renderer_start
(
FlRenderer
*
self
,
GError
**
error
)
{
return
FL_RENDERER_GET_CLASS
(
self
)
->
start
(
self
,
error
);
}
void
*
fl_renderer_get_proc_address
(
FlRenderer
*
self
,
const
char
*
name
)
{
return
reinterpret_cast
<
void
*>
(
eglGetProcAddress
(
name
));
}
gboolean
fl_renderer_make_current
(
FlRenderer
*
self
,
GError
**
error
)
{
FlRendererPrivate
*
priv
=
static_cast
<
FlRendererPrivate
*>
(
fl_renderer_get_instance_private
(
self
));
if
(
!
eglMakeCurrent
(
priv
->
egl_display
,
priv
->
egl_surface
,
priv
->
egl_surface
,
priv
->
egl_context
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to make EGL context current"
);
return
FALSE
;
}
return
TRUE
;
}
gboolean
fl_renderer_clear_current
(
FlRenderer
*
self
,
GError
**
error
)
{
FlRendererPrivate
*
priv
=
static_cast
<
FlRendererPrivate
*>
(
fl_renderer_get_instance_private
(
self
));
if
(
!
eglMakeCurrent
(
priv
->
egl_display
,
EGL_NO_SURFACE
,
EGL_NO_SURFACE
,
EGL_NO_CONTEXT
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to clear EGL context"
);
return
FALSE
;
}
return
TRUE
;
}
guint32
fl_renderer_get_fbo
(
FlRenderer
*
self
)
{
// There is only one frame buffer object - always return that
return
0
;
}
gboolean
fl_renderer_present
(
FlRenderer
*
self
,
GError
**
error
)
{
FlRendererPrivate
*
priv
=
static_cast
<
FlRendererPrivate
*>
(
fl_renderer_get_instance_private
(
self
));
if
(
!
eglSwapBuffers
(
priv
->
egl_display
,
priv
->
egl_surface
))
{
g_set_error
(
error
,
fl_renderer_error_quark
(),
FL_RENDERER_ERROR_FAILED
,
"Failed to swap EGL buffers"
);
return
FALSE
;
}
return
TRUE
;
}
shell/platform/linux/fl_renderer.h
0 → 100644
浏览文件 @
12012f13
// 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_RENDERER_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_H_
#include <EGL/egl.h>
#include <glib-object.h>
#include "flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h"
G_BEGIN_DECLS
/**
* FlRendererError:
* Errors for #FlRenderer objects to set on failures.
*/
typedef
enum
{
FL_RENDERER_ERROR_FAILED
,
}
FlRendererError
;
GQuark
fl_renderer_error_quark
(
void
)
G_GNUC_CONST
;
G_DECLARE_DERIVABLE_TYPE
(
FlRenderer
,
fl_renderer
,
FL
,
RENDERER
,
GObject
)
/**
* FlRenderer:
*
* #FlRenderer is an abstract class that allows Flutter to draw pixels.
*/
struct
_FlRendererClass
{
GObjectClass
parent_class
;
// Virtual methods
gboolean
(
*
start
)(
FlRenderer
*
renderer
,
GError
**
error
);
EGLSurface
(
*
create_surface
)(
FlRenderer
*
renderer
,
EGLDisplay
display
,
EGLConfig
config
);
};
G_END_DECLS
/**
* fl_renderer_start:
* @renderer: a #FlRenderer
* @error: (allow-none): #GError location to store the error occurring, or %NULL
* to ignore.
*
* Returns: %TRUE if successfully started.
*/
gboolean
fl_renderer_start
(
FlRenderer
*
self
,
GError
**
error
);
/**
* fl_renderer_get_proc_address:
* @renderer: a #FlRenderer
* @name: a function name
*
* Gets the rendering API function that matches the given name.
*
* Returns: a function pointer
*/
void
*
fl_renderer_get_proc_address
(
FlRenderer
*
renderer
,
const
char
*
name
);
/**
* fl_renderer_make_current:
* @renderer: a #FlRenderer
* @error: (allow-none): #GError location to store the error occurring, or %NULL
* to ignore.
*
* Makes the rendering context current.
*
* Returns %TRUE if successful
*/
gboolean
fl_renderer_make_current
(
FlRenderer
*
renderer
,
GError
**
error
);
/**
* fl_renderer_clear_current:
* @renderer: a #FlRenderer
* @error: (allow-none): #GError location to store the error occurring, or %NULL
* to ignore.
*
* Clears the current rendering context.
*
* Returns %TRUE if successful
*/
gboolean
fl_renderer_clear_current
(
FlRenderer
*
renderer
,
GError
**
error
);
/**
* fl_renderer_get_fbo:
* @renderer: a #FlRenderer
*
* Gets the frame buffer object to render to.
*
* Returns: a frame buffer object index
*/
guint32
fl_renderer_get_fbo
(
FlRenderer
*
renderer
);
/**
* fl_renderer_present:
* @renderer: a #FlRenderer
* @error: (allow-none): #GError location to store the error occurring, or %NULL
* to ignore.
*
* Presents the current frame.
*
* Returns %TRUE if successful
*/
gboolean
fl_renderer_present
(
FlRenderer
*
renderer
,
GError
**
error
);
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_H_
shell/platform/linux/fl_renderer_x11.cc
0 → 100644
浏览文件 @
12012f13
// 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 "fl_renderer_x11.h"
struct
_FlRendererX11
{
FlRenderer
parent_instance
;
Window
xid
;
};
G_DEFINE_TYPE
(
FlRendererX11
,
fl_renderer_x11
,
fl_renderer_get_type
())
static
EGLSurface
fl_renderer_x11_create_surface
(
FlRenderer
*
renderer
,
EGLDisplay
display
,
EGLConfig
config
)
{
FlRendererX11
*
self
=
FL_RENDERER_X11
(
renderer
);
return
eglCreateWindowSurface
(
display
,
config
,
self
->
xid
,
nullptr
);
}
static
void
fl_renderer_x11_class_init
(
FlRendererX11Class
*
klass
)
{
FL_RENDERER_CLASS
(
klass
)
->
create_surface
=
fl_renderer_x11_create_surface
;
}
static
void
fl_renderer_x11_init
(
FlRendererX11
*
self
)
{}
FlRendererX11
*
fl_renderer_x11_new
(
Window
xid
)
{
FlRendererX11
*
self
=
static_cast
<
FlRendererX11
*>
(
g_object_new
(
fl_renderer_x11_get_type
(),
nullptr
));
self
->
xid
=
xid
;
return
self
;
}
shell/platform/linux/fl_renderer_x11.h
0 → 100644
浏览文件 @
12012f13
// 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_RENDERER_X11_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_X11_H_
#include <gdk/gdkx.h>
#include "flutter/shell/platform/linux/fl_renderer.h"
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE
(
FlRendererX11
,
fl_renderer_x11
,
FL
,
RENDERER_X11
,
FlRenderer
)
/**
* FlRendererX11:
*
* #FlRendererX11 is an implementation of a #FlRenderer that renders to X11
* windows.
*/
/**
* fl_renderer_x11_new:
* @xid: The X window to render to.
*
* Create an object that allows Flutter to render to X11 windows.
*
* Returns: a #FlRendererX11
*/
FlRendererX11
*
fl_renderer_x11_new
(
Window
xid
);
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_RENDERER_X11_H_
shell/platform/linux/fl_view.cc
浏览文件 @
12012f13
...
...
@@ -4,22 +4,19 @@
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_renderer_x11.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include <gdk/gdkx.h>
#
include "flutter/shell/platform/embedder/embedder.h"
#
define NSEC_PER_MSEC 1000000
struct
_FlView
{
GtkWidget
parent_instance
;
EGLDisplay
egl_display
;
EGLSurface
egl_surface
;
EGLContext
egl_context
;
FlDartProject
*
flutter_project
;
FLUTTER_API_SYMBOL
(
FlutterEngine
)
flutter_engine
;
FlDartProject
*
project
;
FlEngine
*
engine
;
int64_t
button_state
;
};
...
...
@@ -27,139 +24,9 @@ enum { PROP_FLUTTER_PROJECT = 1, PROP_LAST };
G_DEFINE_TYPE
(
FlView
,
fl_view
,
GTK_TYPE_WIDGET
)
static
gboolean
initialize_egl
(
FlView
*
self
)
{
/* Note that we don't provide the XDisplay from GTK, this would make both
* GTK and EGL share the same X connection and this would crash when used by
* a Flutter thread. So the EGL display and GTK both have separate
* connections.
*/
self
->
egl_display
=
eglGetDisplay
(
EGL_DEFAULT_DISPLAY
);
EGLint
egl_major
,
egl_minor
;
if
(
!
eglInitialize
(
self
->
egl_display
,
&
egl_major
,
&
egl_minor
))
{
g_warning
(
"Failed to initialze EGL"
);
return
FALSE
;
}
// TODO(robert-ancell): It would probably be useful to store the EGL version
// for debugging purposes
EGLint
attributes
[]
=
{
EGL_RENDERABLE_TYPE
,
EGL_OPENGL_ES2_BIT
,
EGL_RED_SIZE
,
8
,
EGL_GREEN_SIZE
,
8
,
EGL_BLUE_SIZE
,
8
,
EGL_ALPHA_SIZE
,
8
,
EGL_NONE
};
EGLConfig
egl_config
;
EGLint
n_config
;
if
(
!
eglChooseConfig
(
self
->
egl_display
,
attributes
,
&
egl_config
,
1
,
&
n_config
))
{
g_warning
(
"Failed to choose EGL config"
);
return
FALSE
;
}
if
(
n_config
==
0
)
{
g_warning
(
"Failed to find appropriate EGL config"
);
return
FALSE
;
}
if
(
!
eglBindAPI
(
EGL_OPENGL_ES_API
))
{
g_warning
(
"Failed to bind EGL OpenGL ES API"
);
return
FALSE
;
}
Window
xid
=
gdk_x11_window_get_xid
(
gtk_widget_get_window
(
GTK_WIDGET
(
self
)));
self
->
egl_surface
=
eglCreateWindowSurface
(
self
->
egl_display
,
egl_config
,
xid
,
nullptr
);
EGLint
context_attributes
[]
=
{
EGL_CONTEXT_CLIENT_VERSION
,
2
,
EGL_NONE
};
self
->
egl_context
=
eglCreateContext
(
self
->
egl_display
,
egl_config
,
EGL_NO_CONTEXT
,
context_attributes
);
EGLint
value
;
eglQueryContext
(
self
->
egl_display
,
self
->
egl_context
,
EGL_CONTEXT_CLIENT_VERSION
,
&
value
);
return
TRUE
;
}
static
void
*
fl_view_gl_proc_resolver
(
void
*
user_data
,
const
char
*
name
)
{
return
reinterpret_cast
<
void
*>
(
eglGetProcAddress
(
name
));
}
static
bool
fl_view_gl_make_current
(
void
*
user_data
)
{
FlView
*
self
=
static_cast
<
FlView
*>
(
user_data
);
if
(
!
eglMakeCurrent
(
self
->
egl_display
,
self
->
egl_surface
,
self
->
egl_surface
,
self
->
egl_context
))
g_warning
(
"Failed to make EGL context current"
);
return
true
;
}
static
bool
fl_view_gl_clear_current
(
void
*
user_data
)
{
FlView
*
self
=
static_cast
<
FlView
*>
(
user_data
);
if
(
!
eglMakeCurrent
(
self
->
egl_display
,
EGL_NO_SURFACE
,
EGL_NO_SURFACE
,
EGL_NO_CONTEXT
))
g_warning
(
"Failed to make EGL context current"
);
return
true
;
}
static
uint32_t
fl_view_gl_fbo_callback
(
void
*
user_data
)
{
/* There is only one frame buffer object - always return that */
return
0
;
}
static
bool
fl_view_gl_present
(
void
*
user_data
)
{
FlView
*
self
=
static_cast
<
FlView
*>
(
user_data
);
if
(
!
eglSwapBuffers
(
self
->
egl_display
,
self
->
egl_surface
))
g_warning
(
"Failed to swap EGL buffers"
);
return
true
;
}
static
gboolean
run_flutter_engine
(
FlView
*
self
)
{
FlutterRendererConfig
config
=
{};
config
.
type
=
kOpenGL
;
config
.
open_gl
.
struct_size
=
sizeof
(
FlutterOpenGLRendererConfig
);
config
.
open_gl
.
gl_proc_resolver
=
fl_view_gl_proc_resolver
;
config
.
open_gl
.
make_current
=
fl_view_gl_make_current
;
config
.
open_gl
.
clear_current
=
fl_view_gl_clear_current
;
config
.
open_gl
.
fbo_callback
=
fl_view_gl_fbo_callback
;
config
.
open_gl
.
present
=
fl_view_gl_present
;
g_autofree
gchar
*
assets_path
=
fl_dart_project_get_assets_path
(
self
->
flutter_project
);
g_autofree
gchar
*
icu_data_path
=
fl_dart_project_get_icu_data_path
(
self
->
flutter_project
);
FlutterProjectArgs
args
=
{};
args
.
struct_size
=
sizeof
(
FlutterProjectArgs
);
args
.
assets_path
=
assets_path
;
args
.
icu_data_path
=
icu_data_path
;
FlutterEngineResult
result
=
FlutterEngineInitialize
(
FLUTTER_ENGINE_VERSION
,
&
config
,
&
args
,
self
,
&
self
->
flutter_engine
);
if
(
result
!=
kSuccess
)
return
FALSE
;
result
=
FlutterEngineRunInitialized
(
self
->
flutter_engine
);
if
(
result
!=
kSuccess
)
return
FALSE
;
return
TRUE
;
}
/* Convert a GDK button event into a Flutter event and send to the engine */
// Convert a GDK button event into a Flutter event and send to the engine
static
gboolean
fl_view_send_pointer_button_event
(
FlView
*
self
,
GdkEventButton
*
event
)
{
FlutterPointerEvent
fl_event
=
{};
fl_event
.
struct_size
=
sizeof
(
fl_event
);
fl_event
.
timestamp
=
event
->
time
*
1000
;
int64_t
button
;
switch
(
event
->
button
)
{
case
1
:
...
...
@@ -175,31 +42,29 @@ static gboolean fl_view_send_pointer_button_event(FlView* self,
return
FALSE
;
}
int
old_button_state
=
self
->
button_state
;
FlutterPointerPhase
phase
;
if
(
event
->
type
==
GDK_BUTTON_PRESS
)
{
// Drop the event if Flutter already thinks the button is down
if
((
self
->
button_state
&
button
)
!=
0
)
return
FALSE
;
self
->
button_state
^=
button
;
fl_event
.
phase
=
old_button_state
==
0
?
kDown
:
kMove
;
phase
=
old_button_state
==
0
?
kDown
:
kMove
;
}
else
if
(
event
->
type
==
GDK_BUTTON_RELEASE
)
{
// Drop the event if Flutter already thinks the button is up
if
((
self
->
button_state
&
button
)
==
0
)
return
FALSE
;
self
->
button_state
^=
button
;
fl_event
.
phase
=
self
->
button_state
==
0
?
kUp
:
kMove
;
phase
=
self
->
button_state
==
0
?
kUp
:
kMove
;
}
if
(
self
->
flutter_
engine
==
nullptr
)
if
(
self
->
engine
==
nullptr
)
return
FALSE
;
fl_event
.
x
=
event
->
x
;
fl_event
.
y
=
event
->
y
;
fl_event
.
device_kind
=
kFlutterPointerDeviceKindMouse
;
fl_event
.
buttons
=
self
->
button_state
;
FlutterEngineSendPointerEvent
(
self
->
flutter_engine
,
&
fl_event
,
1
);
fl_engine_send_mouse_pointer_event
(
self
->
engine
,
phase
,
event
->
time
*
NSEC_PER_MSEC
,
event
->
x
,
event
->
y
,
self
->
button_state
);
return
TRUE
;
}
...
...
@@ -211,7 +76,7 @@ static void fl_view_set_property(GObject* object,
switch
(
prop_id
)
{
case
PROP_FLUTTER_PROJECT
:
g_set_object
(
&
self
->
flutter_
project
,
g_set_object
(
&
self
->
project
,
static_cast
<
FlDartProject
*>
(
g_value_get_object
(
value
)));
break
;
default:
...
...
@@ -228,7 +93,7 @@ static void fl_view_get_property(GObject* object,
switch
(
prop_id
)
{
case
PROP_FLUTTER_PROJECT
:
g_value_set_object
(
value
,
self
->
flutter_
project
);
g_value_set_object
(
value
,
self
->
project
);
break
;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID
(
object
,
prop_id
,
pspec
);
...
...
@@ -239,17 +104,8 @@ static void fl_view_get_property(GObject* object,
static
void
fl_view_dispose
(
GObject
*
object
)
{
FlView
*
self
=
FL_VIEW
(
object
);
FlutterEngineDeinitialize
(
self
->
flutter_engine
);
FlutterEngineShutdown
(
self
->
flutter_engine
);
if
(
!
eglDestroyContext
(
self
->
egl_display
,
self
->
egl_context
))
g_warning
(
"Failed to destroy EGL context"
);
if
(
!
eglDestroySurface
(
self
->
egl_display
,
self
->
egl_surface
))
g_warning
(
"Failed to destroy EGL surface"
);
if
(
!
eglTerminate
(
self
->
egl_display
))
g_warning
(
"Failed to terminate EGL display"
);
g_clear_object
(
&
self
->
flutter_project
);
g_clear_object
(
&
self
->
project
);
g_clear_object
(
&
self
->
engine
);
G_OBJECT_CLASS
(
fl_view_parent_class
)
->
dispose
(
object
);
}
...
...
@@ -282,8 +138,12 @@ static void fl_view_realize(GtkWidget* widget) {
gtk_widget_register_window
(
widget
,
window
);
gtk_widget_set_window
(
widget
,
window
);
if
(
initialize_egl
(
self
))
run_flutter_engine
(
self
);
Window
xid
=
gdk_x11_window_get_xid
(
gtk_widget_get_window
(
GTK_WIDGET
(
self
)));
g_autoptr
(
FlRendererX11
)
renderer
=
fl_renderer_x11_new
(
xid
);
self
->
engine
=
fl_engine_new
(
self
->
project
,
FL_RENDERER
(
renderer
));
g_autoptr
(
GError
)
error
=
nullptr
;
if
(
!
fl_engine_start
(
self
->
engine
,
&
error
))
g_printerr
(
"Failed to start Flutter engine: %s"
,
error
->
message
);
}
static
void
fl_view_size_allocate
(
GtkWidget
*
widget
,
...
...
@@ -297,13 +157,9 @@ static void fl_view_size_allocate(GtkWidget* widget,
allocation
->
y
,
allocation
->
width
,
allocation
->
height
);
FlutterWindowMetricsEvent
event
=
{};
event
.
struct_size
=
sizeof
(
FlutterWindowMetricsEvent
);
event
.
width
=
allocation
->
width
;
event
.
height
=
allocation
->
height
;
event
.
pixel_ratio
=
1
;
// TODO(robert-ancell): This won't work on hidpi displays
FlutterEngineSendWindowMetricsEvent
(
self
->
flutter_engine
,
&
event
);
// TODO(robert-ancell): This pixel ratio won't work on hidpi displays
fl_engine_send_window_metrics_event
(
self
->
engine
,
allocation
->
width
,
allocation
->
height
,
1
);
}
static
gboolean
fl_view_button_press_event
(
GtkWidget
*
widget
,
...
...
@@ -329,18 +185,12 @@ static gboolean fl_view_motion_notify_event(GtkWidget* widget,
GdkEventMotion
*
event
)
{
FlView
*
self
=
FL_VIEW
(
widget
);
if
(
self
->
flutter_
engine
==
nullptr
)
if
(
self
->
engine
==
nullptr
)
return
FALSE
;
FlutterPointerEvent
fl_event
=
{};
fl_event
.
struct_size
=
sizeof
(
fl_event
);
fl_event
.
timestamp
=
event
->
time
*
1000
;
fl_event
.
phase
=
self
->
button_state
!=
0
?
kMove
:
kHover
;
fl_event
.
x
=
event
->
x
;
fl_event
.
y
=
event
->
y
;
fl_event
.
device_kind
=
kFlutterPointerDeviceKindMouse
;
fl_event
.
buttons
=
self
->
button_state
;
FlutterEngineSendPointerEvent
(
self
->
flutter_engine
,
&
fl_event
,
1
);
fl_engine_send_mouse_pointer_event
(
self
->
engine
,
self
->
button_state
!=
0
?
kMove
:
kHover
,
event
->
time
*
NSEC_PER_MSEC
,
event
->
x
,
event
->
y
,
self
->
button_state
);
return
TRUE
;
}
...
...
@@ -370,3 +220,8 @@ G_MODULE_EXPORT FlView* fl_view_new(FlDartProject* project) {
return
static_cast
<
FlView
*>
(
g_object_new
(
fl_view_get_type
(),
"flutter-project"
,
project
,
nullptr
));
}
G_MODULE_EXPORT
FlEngine
*
fl_view_get_engine
(
FlView
*
view
)
{
g_return_val_if_fail
(
FL_IS_VIEW
(
view
),
nullptr
);
return
view
->
engine
;
}
shell/platform/linux/public/flutter_linux/fl_engine.h
0 → 100644
浏览文件 @
12012f13
// 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_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_H_
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
#endif
#include <glib-object.h>
#include "fl_dart_project.h"
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE
(
FlEngine
,
fl_engine
,
FL
,
ENGINE
,
GObject
)
/**
* FlEngine:
*
* #FlEngine is an object that contains a running Flutter engine.
*/
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_ENGINE_H_
shell/platform/linux/public/flutter_linux/fl_view.h
浏览文件 @
12012f13
...
...
@@ -12,6 +12,7 @@
#include <gtk/gtk.h>
#include "fl_dart_project.h"
#include "fl_engine.h"
G_BEGIN_DECLS
...
...
@@ -33,6 +34,16 @@ G_DECLARE_FINAL_TYPE(FlView, fl_view, FL, VIEW, GtkWidget)
*/
FlView
*
fl_view_new
(
FlDartProject
*
project
);
/**
* fl_view_get_engine:
* @view: a #FlView
*
* Gets the engine being rendered in the view.
*
* Returns: a #FlEngine
*/
FlEngine
*
fl_view_get_engine
(
FlView
*
view
);
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_VIEW_H_
shell/platform/linux/public/flutter_linux/flutter_linux.h
浏览文件 @
12012f13
...
...
@@ -8,6 +8,7 @@
#define __FLUTTER_LINUX_INSIDE__
#include <flutter_linux/fl_dart_project.h>
#include <flutter_linux/fl_engine.h>
#include <flutter_linux/fl_view.h>
#undef __FLUTTER_LINUX_INSIDE__
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录