Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
7b5f79f1
E
engine
项目概览
weixin_43355755
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
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,体验更适合开发者的 AI 搜索 >>
未验证
提交
7b5f79f1
编写于
11月 25, 2020
作者:
D
David Worsham
提交者:
GitHub
11月 25, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fuchsia: Ensure full-screen input interceptor (#22687)
上级
5131aa40
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
99 addition
and
126 deletion
+99
-126
flow/layers/container_layer.cc
flow/layers/container_layer.cc
+1
-1
flow/layers/layer_tree.cc
flow/layers/layer_tree.cc
+2
-6
flow/scene_update_context.cc
flow/scene_update_context.cc
+38
-16
flow/scene_update_context.h
flow/scene_update_context.h
+4
-41
shell/platform/fuchsia/flutter/component.cc
shell/platform/fuchsia/flutter/component.cc
+2
-0
shell/platform/fuchsia/flutter/flutter_runner_product_configuration.cc
...m/fuchsia/flutter/flutter_runner_product_configuration.cc
+6
-1
shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
...latform/fuchsia/flutter/fuchsia_external_view_embedder.cc
+43
-22
shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
...platform/fuchsia/flutter/fuchsia_external_view_embedder.h
+3
-39
未找到文件。
flow/layers/container_layer.cc
浏览文件 @
7b5f79f1
...
...
@@ -114,7 +114,7 @@ void ContainerLayer::UpdateSceneChildren(
if
(
child_layer_exists_below_
)
{
frame
.
emplace
(
context
,
SkRRect
::
MakeRect
(
paint_bounds
()),
SK_ColorTRANSPARENT
,
SkScalarRoundToInt
(
context
->
alphaf
()
*
255
),
"flutter::
Container
Layer"
);
SkScalarRoundToInt
(
context
->
alphaf
()
*
255
),
"flutter::Layer"
);
frame
->
AddPaintLayer
(
this
);
}
...
...
flow/layers/layer_tree.cc
浏览文件 @
7b5f79f1
...
...
@@ -66,23 +66,19 @@ void LayerTree::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
TRACE_EVENT0
(
"flutter"
,
"LayerTree::UpdateScene"
);
// Reset for a new Scene.
context
->
Reset
();
const
float
inv_dpr
=
1.0
f
/
device_pixel_ratio_
;
SceneUpdateContext
::
Transform
transform
(
context
,
inv_dpr
,
inv_dpr
,
1.0
f
);
context
->
Reset
(
frame_size_
,
device_pixel_ratio_
);
SceneUpdateContext
::
Frame
frame
(
context
,
SkRRect
::
MakeRect
(
SkRect
::
MakeWH
(
frame_size_
.
width
(),
frame_size_
.
height
())),
SK_ColorTRANSPARENT
,
SK_AlphaOPAQUE
,
"flutter::Layer
Tree
"
);
SK_ColorTRANSPARENT
,
SK_AlphaOPAQUE
,
"flutter::Layer"
);
if
(
root_layer_
->
needs_system_composite
())
{
root_layer_
->
UpdateScene
(
context
);
}
if
(
!
root_layer_
->
is_empty
())
{
frame
.
AddPaintLayer
(
root_layer_
.
get
());
}
context
->
root_node
().
AddChild
(
transform
.
entity_node
());
}
#endif
...
...
flow/scene_update_context.cc
浏览文件 @
7b5f79f1
...
...
@@ -76,10 +76,26 @@ SceneUpdateContext::SceneUpdateContext(std::string debug_label,
std
::
move
(
view_ref_pair
.
control_ref
),
std
::
move
(
view_ref_pair
.
view_ref
),
debug_label
),
root_node_
(
session_
.
get
()),
intercept_all_input_
(
intercept_all_input
)
{
root_view_
.
AddChild
(
root_node_
);
root_node_
.
SetEventMask
(
fuchsia
::
ui
::
gfx
::
kMetricsEventMask
);
metrics_node_
(
session
.
get
()),
layer_tree_node_
(
session_
.
get
())
{
layer_tree_node_
.
SetLabel
(
"Flutter::LayerTree"
);
metrics_node_
.
SetLabel
(
"Flutter::MetricsWatcher"
);
metrics_node_
.
SetEventMask
(
fuchsia
::
ui
::
gfx
::
kMetricsEventMask
);
metrics_node_
.
AddChild
(
layer_tree_node_
);
root_view_
.
AddChild
(
metrics_node_
);
// Set up the input interceptor at the top of the scene, if applicable. It
// will capture all input, and any unwanted input will be reinjected into
// embedded views.
if
(
intercept_all_input
)
{
input_interceptor_node_
.
emplace
(
session_
.
get
());
input_interceptor_node_
->
SetLabel
(
"Flutter::InputInterceptor"
);
input_interceptor_node_
->
SetHitTestBehavior
(
fuchsia
::
ui
::
gfx
::
HitTestBehavior
::
kDefault
);
input_interceptor_node_
->
SetSemanticVisibility
(
false
);
metrics_node_
.
AddChild
(
input_interceptor_node_
.
value
());
}
session_
.
Present
();
}
...
...
@@ -97,7 +113,8 @@ void SceneUpdateContext::EnableWireframe(bool enable) {
scenic
::
NewSetEnableDebugViewBoundsCmd
(
root_view_
.
id
(),
enable
));
}
void
SceneUpdateContext
::
Reset
()
{
void
SceneUpdateContext
::
Reset
(
const
SkISize
&
frame_size
,
float
device_pixel_ratio
)
{
paint_tasks_
.
clear
();
top_entity_
=
nullptr
;
top_scale_x_
=
1.
f
;
...
...
@@ -106,9 +123,22 @@ void SceneUpdateContext::Reset() {
next_elevation_
=
0.
f
;
alpha_
=
1.
f
;
// Adjust scene scaling to match the device pixel ratio.
const
float
inv_dpr
=
1.0
f
/
device_pixel_ratio
;
metrics_node_
.
SetScale
(
inv_dpr
,
inv_dpr
,
1.0
f
);
// Set up the input interceptor at the top of the scene, if applicable.
if
(
input_interceptor_node_
.
has_value
())
{
// TODO(fxb/): Don't hardcode elevation.
input_interceptor_node_
->
SetTranslation
(
frame_size
.
width
()
*
0.5
f
,
frame_size
.
height
()
*
0.5
f
,
-
100.
f
);
input_interceptor_node_
->
SetShape
(
scenic
::
Rectangle
(
session_
.
get
(),
frame_size
.
width
(),
frame_size
.
height
()));
}
// We are going to be sending down a fresh node hierarchy every frame. So just
// enqueue a detach op on the
imported root
node.
session_
.
get
()
->
Enqueue
(
scenic
::
NewDetachChildrenCmd
(
root_node_
.
id
())
);
// enqueue a detach op on the
layer tree
node.
layer_tree_node_
.
DetachChildren
(
);
}
void
SceneUpdateContext
::
CreateFrame
(
scenic
::
EntityNode
&
entity_node
,
...
...
@@ -235,7 +265,7 @@ SceneUpdateContext::Entity::~Entity() {
if
(
previous_entity_
)
{
previous_entity_
->
embedder_node
().
AddChild
(
entity_node_
);
}
else
{
context_
->
root
_node_
.
AddChild
(
entity_node_
);
context_
->
layer_tree
_node_
.
AddChild
(
entity_node_
);
}
FML_DCHECK
(
context_
->
top_entity_
==
this
);
...
...
@@ -326,14 +356,6 @@ SceneUpdateContext::Frame::Frame(std::shared_ptr<SceneUpdateContext> context,
// with opacity != 1. For now, clamp to a infinitesimally smaller value than
// 1, which does not cause visual problems in practice.
opacity_node_
.
SetOpacity
(
std
::
min
(
kOneMinusEpsilon
,
opacity_
/
255.0
f
));
if
(
context
->
intercept_all_input_
)
{
context
->
input_interceptor_
.
emplace
(
context
->
session_
.
get
());
context
->
input_interceptor_
->
UpdateDimensions
(
context
->
session_
.
get
(),
rrect
.
width
(),
rrect
.
height
(),
-
(
local_elevation
+
kScenicZElevationBetweenLayers
*
0.5
f
));
entity_node
().
AddChild
(
context
->
input_interceptor_
->
node
());
}
}
SceneUpdateContext
::
Frame
::~
Frame
()
{
...
...
flow/scene_update_context.h
浏览文件 @
7b5f79f1
...
...
@@ -126,8 +126,6 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
bool
intercept_all_input
=
false
);
~
SceneUpdateContext
()
=
default
;
scenic
::
ContainerNode
&
root_node
()
{
return
root_node_
;
}
// The cumulative alpha value based on all the parent OpacityLayers.
void
set_alphaf
(
float
alpha
)
{
alpha_
=
alpha
;
}
float
alphaf
()
{
return
alpha_
;
}
...
...
@@ -139,7 +137,7 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
void
EnableWireframe
(
bool
enable
);
// Reset state for a new frame.
void
Reset
();
void
Reset
(
const
SkISize
&
frame_size
,
float
device_pixel_ratio
);
// |ExternalViewEmbedder|
SkCanvas
*
GetRootCanvas
()
override
{
return
nullptr
;
}
...
...
@@ -178,40 +176,6 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
std
::
optional
<
bool
>
override_hit_testable
=
std
::
nullopt
);
private:
// Helper class for setting up an invisible rectangle to catch all input.
// Rejected input will then be re-injected into a suitable platform view
// controlled by this Engine instance.
class
InputInterceptor
{
public:
InputInterceptor
(
scenic
::
Session
*
session
)
:
opacity_node_
(
session
),
shape_node_
(
session
)
{
opacity_node_
.
SetLabel
(
"Flutter::InputInterceptor"
);
opacity_node_
.
SetOpacity
(
0.
f
);
// Set the shape node to capture all input. Any unwanted input will be
// reinjected.
shape_node_
.
SetHitTestBehavior
(
fuchsia
::
ui
::
gfx
::
HitTestBehavior
::
kDefault
);
shape_node_
.
SetSemanticVisibility
(
false
);
opacity_node_
.
AddChild
(
shape_node_
);
}
void
UpdateDimensions
(
scenic
::
Session
*
session
,
float
width
,
float
height
,
float
elevation
)
{
opacity_node_
.
SetTranslation
(
width
*
0.5
f
,
height
*
0.5
f
,
elevation
);
shape_node_
.
SetShape
(
scenic
::
Rectangle
(
session
,
width
,
height
));
}
const
scenic
::
Node
&
node
()
{
return
opacity_node_
;
}
private:
scenic
::
OpacityNodeHACK
opacity_node_
;
scenic
::
ShapeNode
shape_node_
;
};
void
CreateFrame
(
scenic
::
EntityNode
&
entity_node
,
const
SkRRect
&
rrect
,
SkColor
color
,
...
...
@@ -222,7 +186,9 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
SessionWrapper
&
session_
;
scenic
::
View
root_view_
;
scenic
::
EntityNode
root_node_
;
scenic
::
EntityNode
metrics_node_
;
scenic
::
EntityNode
layer_tree_node_
;
std
::
optional
<
scenic
::
ShapeNode
>
input_interceptor_node_
;
std
::
vector
<
PaintTask
>
paint_tasks_
;
...
...
@@ -234,9 +200,6 @@ class SceneUpdateContext : public flutter::ExternalViewEmbedder {
float
next_elevation_
=
0.
f
;
float
alpha_
=
1.
f
;
std
::
optional
<
InputInterceptor
>
input_interceptor_
;
bool
intercept_all_input_
=
false
;
FML_DISALLOW_COPY_AND_ASSIGN
(
SceneUpdateContext
);
};
...
...
shell/platform/fuchsia/flutter/component.cc
浏览文件 @
7b5f79f1
...
...
@@ -352,6 +352,8 @@ Application::Application(
std
::
string
json_string
;
if
(
dart_utils
::
ReadFileToString
(
kRunnerConfigPath
,
&
json_string
))
{
product_config_
=
FlutterRunnerProductConfiguration
(
json_string
);
FML_LOG
(
INFO
)
<<
"Successfully loaded runner configuration: "
<<
json_string
;
}
else
{
FML_LOG
(
WARNING
)
<<
"Failed to load runner configuration from "
<<
kRunnerConfigPath
<<
"; using default config values."
;
...
...
shell/platform/fuchsia/flutter/flutter_runner_product_configuration.cc
浏览文件 @
7b5f79f1
...
...
@@ -3,8 +3,10 @@
// found in the LICENSE file.
#include "flutter_runner_product_configuration.h"
#include <zircon/assert.h>
#include "flutter/fml/logging.h"
#include "rapidjson/document.h"
namespace
flutter_runner
{
...
...
@@ -14,8 +16,11 @@ FlutterRunnerProductConfiguration::FlutterRunnerProductConfiguration(
rapidjson
::
Document
document
;
document
.
Parse
(
json_string
);
if
(
!
document
.
IsObject
())
if
(
!
document
.
IsObject
())
{
FML_LOG
(
ERROR
)
<<
"Failed to parse configuration; using defaults: "
<<
json_string
;
return
;
}
// Parse out all values we're expecting.
if
(
document
.
HasMember
(
"vsync_offset_in_us"
))
{
...
...
shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
浏览文件 @
7b5f79f1
...
...
@@ -21,6 +21,7 @@ namespace {
// Z-fighting.
constexpr
float
kScenicZElevationBetweenLayers
=
0.0001
f
;
constexpr
float
kScenicZElevationForPlatformView
=
100.
f
;
constexpr
float
kScenicElevationForInputInterceptor
=
500.
f
;
}
// namespace
...
...
@@ -39,18 +40,24 @@ FuchsiaExternalViewEmbedder::FuchsiaExternalViewEmbedder(
std
::
move
(
view_ref_pair
.
view_ref
),
debug_label
),
metrics_node_
(
session_
.
get
()),
root_node_
(
session_
.
get
()),
intercept_all_input_
(
intercept_all_input
)
{
root_view_
.
AddChild
(
metrics_node_
);
metrics_node_
.
SetEventMask
(
fuchsia
::
ui
::
gfx
::
kMetricsEventMask
);
layer_tree_node_
(
session_
.
get
())
{
layer_tree_node_
.
SetLabel
(
"Flutter::LayerTree"
);
metrics_node_
.
SetLabel
(
"Flutter::MetricsWatcher"
);
metrics_node_
.
AddChild
(
root_node_
);
root_node_
.
SetLabel
(
"Flutter::LayerTree"
);
metrics_node_
.
SetEventMask
(
fuchsia
::
ui
::
gfx
::
kMetricsEventMask
);
metrics_node_
.
AddChild
(
layer_tree_node_
);
root_view_
.
AddChild
(
metrics_node_
);
// Set up the input interceptor at the top of the scene, if applicable.
if
(
intercept_all_input_
)
{
input_interceptor_
.
emplace
(
session_
.
get
());
metrics_node_
.
AddChild
(
input_interceptor_
->
node
());
// Set up the input interceptor at the top of the scene, if applicable. It
// will capture all input, and any unwanted input will be reinjected into
// embedded views.
if
(
intercept_all_input
)
{
input_interceptor_node_
.
emplace
(
session_
.
get
());
input_interceptor_node_
->
SetLabel
(
"Flutter::InputInterceptor"
);
input_interceptor_node_
->
SetHitTestBehavior
(
fuchsia
::
ui
::
gfx
::
HitTestBehavior
::
kDefault
);
input_interceptor_node_
->
SetSemanticVisibility
(
false
);
metrics_node_
.
AddChild
(
input_interceptor_node_
.
value
());
}
session_
.
Present
();
...
...
@@ -124,12 +131,28 @@ void FuchsiaExternalViewEmbedder::BeginFrame(
frame_composition_order_
.
push_back
(
kRootLayerId
);
// Set up the input interceptor at the top of the scene, if applicable.
if
(
input_interceptor_
.
has_value
())
{
// TODO: Don't hardcode elevation.
const
float
kMaximumElevation
=
-
100.
f
;
input_interceptor_
->
UpdateDimensions
(
session_
.
get
(),
frame_size
.
width
(),
frame_size
.
height
(),
kMaximumElevation
);
if
(
input_interceptor_node_
.
has_value
())
{
const
uint64_t
rect_hash
=
(
static_cast
<
uint64_t
>
(
frame_size_
.
width
())
<<
32
)
+
frame_size_
.
height
();
// Create a new rect if needed for the interceptor.
auto
found_rect
=
scenic_interceptor_rects_
.
find
(
rect_hash
);
if
(
found_rect
==
scenic_interceptor_rects_
.
end
())
{
auto
[
emplaced_rect
,
success
]
=
scenic_interceptor_rects_
.
emplace
(
std
::
make_pair
(
rect_hash
,
scenic
::
Rectangle
(
session_
.
get
(),
frame_size_
.
width
(),
frame_size_
.
height
())));
FML_DCHECK
(
success
);
found_rect
=
std
::
move
(
emplaced_rect
);
}
// TODO(fxb/): Don't hardcode elevation.
input_interceptor_node_
->
SetTranslation
(
frame_size
.
width
()
*
0.5
f
,
frame_size
.
height
()
*
0.5
f
,
-
kScenicElevationForInputInterceptor
);
input_interceptor_node_
->
SetShape
(
found_rect
->
second
);
}
}
...
...
@@ -179,7 +202,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
// First re-scale everything according to the DPR.
const
float
inv_dpr
=
1.0
f
/
frame_dpr_
;
root
_node_
.
SetScale
(
inv_dpr
,
inv_dpr
,
1.0
f
);
layer_tree
_node_
.
SetScale
(
inv_dpr
,
inv_dpr
,
1.0
f
);
bool
first_layer
=
true
;
for
(
const
auto
&
layer_id
:
frame_composition_order_
)
{
...
...
@@ -267,7 +290,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
}
// Attach the ScenicView to the main scene graph.
root
_node_
.
AddChild
(
view_holder
.
opacity_node
);
layer_tree
_node_
.
AddChild
(
view_holder
.
opacity_node
);
// Account for the ScenicView's height when positioning the next layer.
embedded_views_height
+=
kScenicZElevationForPlatformView
;
...
...
@@ -355,7 +378,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
first_layer
=
false
;
// Attach the ScenicLayer to the main scene graph.
root
_node_
.
AddChild
(
scenic_layer
.
shape_node
);
layer_tree
_node_
.
AddChild
(
scenic_layer
.
shape_node
);
// Account for the ScenicLayer's height when positioning the next layer.
scenic_layer_index
++
;
...
...
@@ -461,14 +484,12 @@ void FuchsiaExternalViewEmbedder::Reset() {
frame_dpr_
=
1.
f
;
// Detach the root node to prepare for the next frame.
session_
.
get
()
->
Enqueue
(
scenic
::
NewDetachChildrenCmd
(
root_node_
.
id
())
);
layer_tree_node_
.
DetachChildren
(
);
// Clear images on all layers so they aren't cached unnecesarily.
for
(
auto
&
layer
:
scenic_layers_
)
{
layer
.
material
.
SetTexture
(
0
);
}
input_interceptor_
.
reset
();
}
}
// namespace flutter_runner
shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
浏览文件 @
7b5f79f1
...
...
@@ -134,40 +134,6 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder {
scenic
::
Material
material
;
};
// Helper class for setting up an invisible rectangle to catch all input.
// Rejected input will then be re-injected into a suitable platform view
// controlled by this Engine instance.
class
InputInterceptor
{
public:
InputInterceptor
(
scenic
::
Session
*
session
)
:
opacity_node_
(
session
),
shape_node_
(
session
)
{
opacity_node_
.
SetLabel
(
"Flutter::InputInterceptor"
);
opacity_node_
.
SetOpacity
(
0.5
f
);
// Set the shape node to capture all input. Any unwanted input will be
// reinjected.
shape_node_
.
SetHitTestBehavior
(
fuchsia
::
ui
::
gfx
::
HitTestBehavior
::
kDefault
);
shape_node_
.
SetSemanticVisibility
(
false
);
opacity_node_
.
AddChild
(
shape_node_
);
}
void
UpdateDimensions
(
scenic
::
Session
*
session
,
float
width
,
float
height
,
float
elevation
)
{
opacity_node_
.
SetTranslation
(
width
*
0.5
f
,
height
*
0.5
f
,
elevation
);
shape_node_
.
SetShape
(
scenic
::
Rectangle
(
session
,
width
,
height
));
}
const
scenic
::
Node
&
node
()
{
return
opacity_node_
;
}
private:
scenic
::
OpacityNodeHACK
opacity_node_
;
scenic
::
ShapeNode
shape_node_
;
};
using
EmbedderLayerId
=
std
::
optional
<
uint32_t
>
;
constexpr
static
EmbedderLayerId
kRootLayerId
=
EmbedderLayerId
{};
...
...
@@ -176,21 +142,19 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder {
scenic
::
View
root_view_
;
scenic
::
EntityNode
metrics_node_
;
scenic
::
EntityNode
root_node_
;
scenic
::
EntityNode
layer_tree_node_
;
std
::
optional
<
scenic
::
ShapeNode
>
input_interceptor_node_
;
std
::
unordered_map
<
uint64_t
,
scenic
::
Rectangle
>
scenic_interceptor_rects_
;
std
::
unordered_map
<
uint64_t
,
std
::
vector
<
scenic
::
Rectangle
>>
scenic_rects_
;
std
::
unordered_map
<
int64_t
,
ScenicView
>
scenic_views_
;
std
::
vector
<
ScenicLayer
>
scenic_layers_
;
std
::
optional
<
InputInterceptor
>
input_interceptor_
;
std
::
unordered_map
<
EmbedderLayerId
,
EmbedderLayer
>
frame_layers_
;
std
::
vector
<
EmbedderLayerId
>
frame_composition_order_
;
SkISize
frame_size_
=
SkISize
::
Make
(
0
,
0
);
float
frame_dpr_
=
1.
f
;
bool
intercept_all_input_
=
false
;
FML_DISALLOW_COPY_AND_ASSIGN
(
FuchsiaExternalViewEmbedder
);
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录