Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 909c28a

Browse files
author
Jonah Williams
authored
[engine] Split encode and submit into two different surface frame callbacks. (#54200)
This makes it much easier to implement the deferred submit required for #53826
1 parent 3b9c31f commit 909c28a

18 files changed

+335
-195
lines changed

flow/surface_frame.cc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ namespace flutter {
1717

1818
SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
1919
FramebufferInfo framebuffer_info,
20+
const EncodeCallback& encode_callback,
2021
const SubmitCallback& submit_callback,
2122
SkISize frame_size,
2223
std::unique_ptr<GLContextResult> context_result,
2324
bool display_list_fallback)
2425
: surface_(std::move(surface)),
2526
framebuffer_info_(framebuffer_info),
27+
encode_callback_(encode_callback),
2628
submit_callback_(submit_callback),
2729
context_result_(std::move(context_result)) {
2830
FML_DCHECK(submit_callback_);
@@ -47,8 +49,23 @@ SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
4749
}
4850
}
4951

52+
bool SurfaceFrame::Encode() {
53+
TRACE_EVENT0("flutter", "SurfaceFrame::Encode");
54+
if (encoded_) {
55+
return false;
56+
}
57+
58+
encoded_ = PerformEncode();
59+
60+
return encoded_;
61+
}
62+
5063
bool SurfaceFrame::Submit() {
5164
TRACE_EVENT0("flutter", "SurfaceFrame::Submit");
65+
if (!encoded_ && !Encode()) {
66+
return false;
67+
}
68+
5269
if (submitted_) {
5370
return false;
5471
}
@@ -70,12 +87,24 @@ sk_sp<SkSurface> SurfaceFrame::SkiaSurface() const {
7087
return surface_;
7188
}
7289

90+
bool SurfaceFrame::PerformEncode() {
91+
if (encode_callback_ == nullptr) {
92+
return false;
93+
}
94+
95+
if (encode_callback_(*this, Canvas())) {
96+
return true;
97+
}
98+
99+
return false;
100+
}
101+
73102
bool SurfaceFrame::PerformSubmit() {
74103
if (submit_callback_ == nullptr) {
75104
return false;
76105
}
77106

78-
if (submit_callback_(*this, Canvas())) {
107+
if (submit_callback_(*this)) {
79108
return true;
80109
}
81110

flow/surface_frame.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@
1717
#include "third_party/skia/include/core/SkCanvas.h"
1818
#include "third_party/skia/include/core/SkSurface.h"
1919

20+
namespace impeller {
21+
class Surface;
22+
}
23+
2024
namespace flutter {
2125

2226
// This class represents a frame that has been fully configured for the
2327
// underlying client rendering API. A frame may only be submitted once.
2428
class SurfaceFrame {
2529
public:
26-
using SubmitCallback =
30+
using EncodeCallback =
2731
std::function<bool(SurfaceFrame& surface_frame, DlCanvas* canvas)>;
32+
using SubmitCallback = std::function<bool(SurfaceFrame& surface_frame)>;
2833

2934
// Information about the underlying framebuffer
3035
struct FramebufferInfo {
@@ -58,6 +63,7 @@ class SurfaceFrame {
5863

5964
SurfaceFrame(sk_sp<SkSurface> surface,
6065
FramebufferInfo framebuffer_info,
66+
const EncodeCallback& encode_callback,
6167
const SubmitCallback& submit_callback,
6268
SkISize frame_size,
6369
std::unique_ptr<GLContextResult> context_result = nullptr,
@@ -89,6 +95,8 @@ class SurfaceFrame {
8995
bool frame_boundary = true;
9096
};
9197

98+
bool Encode();
99+
92100
bool Submit();
93101

94102
bool IsSubmitted() const;
@@ -106,8 +114,17 @@ class SurfaceFrame {
106114

107115
sk_sp<DisplayList> BuildDisplayList();
108116

117+
void set_user_data(std::shared_ptr<impeller::Surface> data) {
118+
user_data_ = std::move(data);
119+
}
120+
121+
std::shared_ptr<impeller::Surface> take_user_data() {
122+
return std::move(user_data_);
123+
}
124+
109125
private:
110126
bool submitted_ = false;
127+
bool encoded_ = false;
111128

112129
#if !SLIMPELLER
113130
DlSkCanvasAdapter adapter_;
@@ -117,11 +134,15 @@ class SurfaceFrame {
117134
DlCanvas* canvas_ = nullptr;
118135
FramebufferInfo framebuffer_info_;
119136
SubmitInfo submit_info_;
137+
EncodeCallback encode_callback_;
120138
SubmitCallback submit_callback_;
139+
std::shared_ptr<impeller::Surface> user_data_;
121140
std::unique_ptr<GLContextResult> context_result_;
122141

123142
bool PerformSubmit();
124143

144+
bool PerformEncode();
145+
125146
FML_DISALLOW_COPY_AND_ASSIGN(SurfaceFrame);
126147
};
127148

flow/surface_frame_unittests.cc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ namespace flutter {
1111

1212
TEST(FlowTest, SurfaceFrameDoesNotSubmitInDtor) {
1313
SurfaceFrame::FramebufferInfo framebuffer_info;
14-
auto callback = [](const SurfaceFrame&, DlCanvas*) {
14+
auto callback = [](const SurfaceFrame&) {
1515
EXPECT_FALSE(true);
1616
return true;
1717
};
18+
auto encode_callback = [](const SurfaceFrame&, DlCanvas*) {
19+
EXPECT_FALSE(true);
20+
return true;
21+
};
22+
1823
auto surface_frame = std::make_unique<SurfaceFrame>(
1924
/*surface=*/nullptr,
2025
/*framebuffer_info=*/framebuffer_info,
26+
/*encode_callback=*/encode_callback,
2127
/*submit_callback=*/callback,
2228
/*frame_size=*/SkISize::Make(800, 600));
2329
surface_frame.reset();
@@ -26,10 +32,12 @@ TEST(FlowTest, SurfaceFrameDoesNotSubmitInDtor) {
2632
TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) {
2733
SurfaceFrame::FramebufferInfo framebuffer_info;
2834
auto callback = [](const SurfaceFrame&, DlCanvas*) { return true; };
35+
auto submit_callback = [](const SurfaceFrame&) { return true; };
2936
SurfaceFrame frame(
3037
/*surface=*/nullptr,
3138
/*framebuffer_info=*/framebuffer_info,
32-
/*submit_callback=*/callback,
39+
/*encode_callback=*/callback,
40+
/*submit_callback=*/submit_callback,
3341
/*frame_size=*/SkISize::Make(800, 600),
3442
/*context_result=*/nullptr,
3543
/*display_list_fallback=*/true);
@@ -41,10 +49,12 @@ TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) {
4149
TEST(FlowTest, SurfaceFrameDoesNotPrepareRtree) {
4250
SurfaceFrame::FramebufferInfo framebuffer_info;
4351
auto callback = [](const SurfaceFrame&, DlCanvas*) { return true; };
52+
auto submit_callback = [](const SurfaceFrame&) { return true; };
4453
auto surface_frame = std::make_unique<SurfaceFrame>(
4554
/*surface=*/nullptr,
4655
/*framebuffer_info=*/framebuffer_info,
47-
/*submit_callback=*/callback,
56+
/*encode_callback=*/callback,
57+
/*submit_callback=*/submit_callback,
4858
/*frame_size=*/SkISize::Make(800, 600),
4959
/*context_result=*/nullptr,
5060
/*display_list_fallback=*/true);

impeller/scene/README.md

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,35 +104,33 @@ auto renderer = impeller::Renderer(context);
104104
while(true) {
105105
std::unique_ptr<impeller::Surface> surface = /* Wrap the window surface */;
106106

107-
renderer->Render(surface, [&scene](RenderTarget& render_target) {
108-
/// Render a perspective view.
107+
const auto& render_target = surface->GetTargetRenderPassDescriptor();
109108

110-
auto camera =
111-
impeller::Camera::MakePerspective(
112-
/* fov */ kPiOver4,
113-
/* position */ {50, -30, 50})
114-
.LookAt(
115-
/* target */ impeller::Vector3::Zero,
116-
/* up */ {0, -1, 0});
109+
/// Render a perspective view.
117110

118-
scene.Render(render_target, camera);
111+
auto camera =
112+
impeller::Camera::MakePerspective(
113+
/* fov */ kPiOver4,
114+
/* position */ {50, -30, 50})
115+
.LookAt(
116+
/* target */ impeller::Vector3::Zero,
117+
/* up */ {0, -1, 0});
118+
119+
scene.Render(render_target, camera);
119120

120121
/// Render an overhead view on the bottom right corner of the screen.
121122

122-
auto size = render_target.GetRenderTargetSize();
123-
auto minimap_camera =
124-
impeller::Camera::MakeOrthographic(
125-
/* view */ Rect::MakeLTRB(-100, -100, 100, 100),
126-
/* position */ {0, -50, 0})
127-
.LookAt(
128-
/* target */ impeller::Vector3::Zero,
129-
/* up */ {0, 0, 1})
130-
.WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4,
131-
size.height / 5, size.height / 5));
132-
133-
scene.Render(render_target, minimap_camera);
134-
135-
return true;
136-
});
123+
auto size = render_target.GetRenderTargetSize();
124+
auto minimap_camera =
125+
impeller::Camera::MakeOrthographic(
126+
/* view */ Rect::MakeLTRB(-100, -100, 100, 100),
127+
/* position */ {0, -50, 0})
128+
.LookAt(
129+
/* target */ impeller::Vector3::Zero,
130+
/* up */ {0, 0, 1})
131+
.WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4,
132+
size.height / 5, size.height / 5));
133+
134+
scene.Render(render_target, minimap_camera);
137135
}
138136
```

shell/common/rasterizer_unittests.cc

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#define FML_USED_ON_EMBEDDER
66

7+
#include "flow/surface_frame.h"
78
#include "flutter/shell/common/rasterizer.h"
89

910
#include <memory>
@@ -209,7 +210,8 @@ TEST(RasterizerTest,
209210
auto surface_frame = std::make_unique<SurfaceFrame>(
210211
/*surface=*/
211212
nullptr, framebuffer_info,
212-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
213+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
214+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
213215
/*frame_size=*/SkISize::Make(800, 600));
214216
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
215217
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
@@ -287,7 +289,8 @@ TEST(
287289
auto surface_frame = std::make_unique<SurfaceFrame>(
288290
/*surface=*/
289291
nullptr, framebuffer_info,
290-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
292+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
293+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
291294
/*frame_size=*/SkISize::Make(800, 600));
292295
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
293296
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
@@ -365,7 +368,8 @@ TEST(
365368
auto surface_frame = std::make_unique<SurfaceFrame>(
366369
/*surface=*/
367370
nullptr, framebuffer_info,
368-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
371+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
372+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
369373
/*frame_size=*/SkISize::Make(800, 600));
370374
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
371375
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
@@ -440,12 +444,14 @@ TEST(RasterizerTest,
440444
auto surface_frame1 = std::make_unique<SurfaceFrame>(
441445
/*surface=*/
442446
nullptr, framebuffer_info,
443-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
447+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
448+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
444449
/*frame_size=*/SkISize::Make(800, 600));
445450
auto surface_frame2 = std::make_unique<SurfaceFrame>(
446451
/*surface=*/
447452
nullptr, framebuffer_info,
448-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
453+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
454+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
449455
/*frame_size=*/SkISize::Make(800, 600));
450456
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled())
451457
.WillRepeatedly(Return(true));
@@ -688,7 +694,8 @@ TEST(RasterizerTest, drawMultipleViewsWithExternalViewEmbedder) {
688694
return std::make_unique<SurfaceFrame>(
689695
/*surface=*/
690696
nullptr, framebuffer_info,
691-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
697+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
698+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
692699
/*frame_size=*/SkISize::Make(800, 600));
693700
});
694701
EXPECT_CALL(*surface, MakeRenderContextCurrent())
@@ -765,7 +772,8 @@ TEST(RasterizerTest,
765772
auto surface_frame = std::make_unique<SurfaceFrame>(
766773
/*surface=*/
767774
nullptr, /*framebuffer_info=*/framebuffer_info,
768-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
775+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
776+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
769777
/*frame_size=*/SkISize::Make(800, 600));
770778
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
771779
ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
@@ -826,7 +834,8 @@ TEST(
826834
auto surface_frame = std::make_unique<SurfaceFrame>(
827835
/*surface=*/
828836
nullptr, /*framebuffer_info=*/framebuffer_info,
829-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
837+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
838+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
830839
/*frame_size=*/SkISize::Make(800, 600));
831840
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
832841
ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
@@ -888,7 +897,8 @@ TEST(
888897
auto surface_frame = std::make_unique<SurfaceFrame>(
889898
/*surface=*/
890899
nullptr, /*framebuffer_info=*/framebuffer_info,
891-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
900+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
901+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
892902
/*frame_size=*/SkISize::Make(800, 600));
893903
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false));
894904
EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
@@ -949,7 +959,8 @@ TEST(
949959
auto surface_frame = std::make_unique<SurfaceFrame>(
950960
/*surface=*/
951961
nullptr, /*framebuffer_info=*/framebuffer_info,
952-
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
962+
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
963+
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
953964
/*frame_size=*/SkISize::Make(800, 600));
954965
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false));
955966
EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
@@ -1074,8 +1085,9 @@ TEST(RasterizerTest,
10741085
return std::make_unique<SurfaceFrame>(
10751086
/*surface=*/
10761087
nullptr, framebuffer_info,
1077-
/*submit_callback=*/
1078-
[](const SurfaceFrame& frame, DlCanvas*) { return true; },
1088+
/*encode_callback=*/
1089+
[](const SurfaceFrame&, DlCanvas*) { return true; },
1090+
/*submit_callback=*/[](const SurfaceFrame& frame) { return true; },
10791091
/*frame_size=*/SkISize::Make(800, 600));
10801092
}));
10811093
ON_CALL(*surface, MakeRenderContextCurrent())

shell/common/shell_test_platform_view_vulkan.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,21 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame(
203203
SkAlphaType::kOpaque_SkAlphaType);
204204
auto surface = SkSurfaces::RenderTarget(context_.get(), skgpu::Budgeted::kNo,
205205
image_info, 0, nullptr);
206-
SurfaceFrame::SubmitCallback callback = [](const SurfaceFrame&,
207-
DlCanvas* canvas) -> bool {
206+
207+
SurfaceFrame::EncodeCallback encode_callback = [](const SurfaceFrame&,
208+
DlCanvas* canvas) -> bool {
208209
canvas->Flush();
209210
return true;
210211
};
212+
SurfaceFrame::SubmitCallback submit_callback =
213+
[](const SurfaceFrame&) -> bool { return true; };
211214

212215
SurfaceFrame::FramebufferInfo framebuffer_info;
213216
framebuffer_info.supports_readback = true;
214217

215218
return std::make_unique<SurfaceFrame>(std::move(surface), framebuffer_info,
216-
std::move(callback),
219+
std::move(encode_callback),
220+
std::move(submit_callback),
217221
/*frame_size=*/SkISize::Make(800, 600));
218222
}
219223

0 commit comments

Comments
 (0)