Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
2d42c74a
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,发现更多精彩内容 >>
未验证
提交
2d42c74a
编写于
3月 20, 2020
作者:
C
Chris Yang
提交者:
GitHub
3月 20, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Replace Pipeline's `ProduceToFront` with `ProduceIfEmpty` to handle thread merging. (#17122)
上级
77e6d32a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
31 addition
and
35 deletion
+31
-35
shell/common/pipeline.h
shell/common/pipeline.h
+22
-13
shell/common/pipeline_unittests.cc
shell/common/pipeline_unittests.cc
+8
-20
shell/common/rasterizer.cc
shell/common/rasterizer.cc
+1
-2
未找到文件。
shell/common/pipeline.h
浏览文件 @
2d42c74a
...
...
@@ -111,16 +111,22 @@ class Pipeline : public fml::RefCountedThreadSafe<Pipeline<R>> {
GetNextPipelineTraceID
()};
// trace id
}
// Pushes task to the front of the pipeline.
//
// If we exceed the depth completing this continuation, we drop the
// last frame to preserve the depth of the pipeline.
//
// Note: Use |Pipeline::Produce| where possible. This should only be
// used to en-queue high-priority resources.
ProducerContinuation
ProduceToFront
()
{
// Create a `ProducerContinuation` that will only push the task if the queue
// is empty.
// Prefer using |Produce|. ProducerContinuation returned by this method
// doesn't guarantee that the frame will be rendered.
ProducerContinuation
ProduceIfEmpty
()
{
if
(
!
empty_
.
TryWait
())
{
return
{};
}
++
inflight_
;
FML_TRACE_COUNTER
(
"flutter"
,
"Pipeline Depth"
,
reinterpret_cast
<
int64_t
>
(
this
),
//
"frames in flight"
,
inflight_
.
load
()
//
);
return
ProducerContinuation
{
std
::
bind
(
&
Pipeline
::
ProducerCommit
Front
,
this
,
std
::
placeholders
::
_1
,
std
::
bind
(
&
Pipeline
::
ProducerCommit
IfEmpty
,
this
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
),
// continuation
GetNextPipelineTraceID
()};
// trace id
}
...
...
@@ -181,13 +187,16 @@ class Pipeline : public fml::RefCountedThreadSafe<Pipeline<R>> {
available_
.
Signal
();
}
void
ProducerCommit
Front
(
ResourcePtr
resource
,
size_t
trace_id
)
{
void
ProducerCommit
IfEmpty
(
ResourcePtr
resource
,
size_t
trace_id
)
{
{
std
::
scoped_lock
lock
(
queue_mutex_
);
queue_
.
emplace_front
(
std
::
move
(
resource
),
trace_id
);
while
(
queue_
.
size
()
>
depth_
)
{
queue_
.
pop_back
();
if
(
!
queue_
.
empty
())
{
// Bail if the queue is not empty, opens up spaces to produce other
// frames.
empty_
.
Signal
();
return
;
}
queue_
.
emplace_back
(
std
::
move
(
resource
),
trace_id
);
}
// Ensure the queue mutex is not held as that would be a pessimization.
...
...
shell/common/pipeline_unittests.cc
浏览文件 @
2d42c74a
...
...
@@ -89,46 +89,34 @@ TEST(PipelineTest, PushingMultiProcessesInOrder) {
ASSERT_EQ
(
consume_result_2
,
PipelineConsumeResult
::
Done
);
}
TEST
(
PipelineTest
,
P
ushingToFrontOverridesOrder
)
{
TEST
(
PipelineTest
,
P
roduceIfEmptyDoesNotConsumeWhenQueueIsNotEmpty
)
{
const
int
depth
=
2
;
fml
::
RefPtr
<
IntPipeline
>
pipeline
=
fml
::
MakeRefCounted
<
IntPipeline
>
(
depth
);
Continuation
continuation_1
=
pipeline
->
Produce
();
Continuation
continuation_2
=
pipeline
->
Produce
ToFront
();
Continuation
continuation_2
=
pipeline
->
Produce
IfEmpty
();
const
int
test_val_1
=
1
,
test_val_2
=
2
;
continuation_1
.
Complete
(
std
::
make_unique
<
int
>
(
test_val_1
));
continuation_2
.
Complete
(
std
::
make_unique
<
int
>
(
test_val_2
));
PipelineConsumeResult
consume_result_1
=
pipeline
->
Consume
(
[
&
test_val_2
](
std
::
unique_ptr
<
int
>
v
)
{
ASSERT_EQ
(
*
v
,
test_val_2
);
});
ASSERT_EQ
(
consume_result_1
,
PipelineConsumeResult
::
MoreAvailable
);
PipelineConsumeResult
consume_result_2
=
pipeline
->
Consume
(
[
&
test_val_1
](
std
::
unique_ptr
<
int
>
v
)
{
ASSERT_EQ
(
*
v
,
test_val_1
);
});
ASSERT_EQ
(
consume_result_
2
,
PipelineConsumeResult
::
Done
);
ASSERT_EQ
(
consume_result_
1
,
PipelineConsumeResult
::
Done
);
}
TEST
(
PipelineTest
,
P
ushingToFrontDropsLastResource
)
{
const
int
depth
=
2
;
TEST
(
PipelineTest
,
P
roduceIfEmptySuccessfulIfQueueIsEmpty
)
{
const
int
depth
=
1
;
fml
::
RefPtr
<
IntPipeline
>
pipeline
=
fml
::
MakeRefCounted
<
IntPipeline
>
(
depth
);
Continuation
continuation_1
=
pipeline
->
Produce
();
Continuation
continuation_2
=
pipeline
->
Produce
();
Continuation
continuation_3
=
pipeline
->
ProduceToFront
();
Continuation
continuation_1
=
pipeline
->
ProduceIfEmpty
();
const
int
test_val_1
=
1
,
test_val_2
=
2
,
test_val_3
=
3
;
const
int
test_val_1
=
1
;
continuation_1
.
Complete
(
std
::
make_unique
<
int
>
(
test_val_1
));
continuation_2
.
Complete
(
std
::
make_unique
<
int
>
(
test_val_2
));
continuation_3
.
Complete
(
std
::
make_unique
<
int
>
(
test_val_3
));
PipelineConsumeResult
consume_result_1
=
pipeline
->
Consume
(
[
&
test_val_3
](
std
::
unique_ptr
<
int
>
v
)
{
ASSERT_EQ
(
*
v
,
test_val_3
);
});
ASSERT_EQ
(
consume_result_1
,
PipelineConsumeResult
::
MoreAvailable
);
PipelineConsumeResult
consume_result_2
=
pipeline
->
Consume
(
[
&
test_val_1
](
std
::
unique_ptr
<
int
>
v
)
{
ASSERT_EQ
(
*
v
,
test_val_1
);
});
ASSERT_EQ
(
consume_result_
2
,
PipelineConsumeResult
::
Done
);
ASSERT_EQ
(
consume_result_
1
,
PipelineConsumeResult
::
Done
);
}
}
// namespace testing
...
...
shell/common/rasterizer.cc
浏览文件 @
2d42c74a
...
...
@@ -127,9 +127,8 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
// if the raster status is to resubmit the frame, we push the frame to the
// front of the queue and also change the consume status to more available.
if
(
raster_status
==
RasterStatus
::
kResubmit
)
{
auto
front_continuation
=
pipeline
->
Produce
ToFront
();
auto
front_continuation
=
pipeline
->
Produce
IfEmpty
();
front_continuation
.
Complete
(
std
::
move
(
resubmitted_layer_tree_
));
consume_result
=
PipelineConsumeResult
::
MoreAvailable
;
}
else
if
(
raster_status
==
RasterStatus
::
kEnqueuePipeline
)
{
consume_result
=
PipelineConsumeResult
::
MoreAvailable
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录