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

[engine] Split encode and submit into two different surface frame callbacks. #54200

Merged
merged 8 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion flow/surface_frame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ namespace flutter {

SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
FramebufferInfo framebuffer_info,
const EncodeCallback& encode_callback,
const SubmitCallback& submit_callback,
SkISize frame_size,
std::unique_ptr<GLContextResult> context_result,
bool display_list_fallback)
: surface_(std::move(surface)),
framebuffer_info_(framebuffer_info),
encode_callback_(encode_callback),
submit_callback_(submit_callback),
context_result_(std::move(context_result)) {
FML_DCHECK(submit_callback_);
Expand All @@ -47,8 +49,23 @@ SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
}
}

bool SurfaceFrame::Encode() {
TRACE_EVENT0("flutter", "SurfaceFrame::Encode");
if (encoded_) {
return false;
}

encoded_ = PerformEncode();

return encoded_;
}

bool SurfaceFrame::Submit() {
TRACE_EVENT0("flutter", "SurfaceFrame::Submit");
if (!encoded_ && !Encode()) {
return false;
}

if (submitted_) {
return false;
}
Expand All @@ -70,12 +87,24 @@ sk_sp<SkSurface> SurfaceFrame::SkiaSurface() const {
return surface_;
}

bool SurfaceFrame::PerformEncode() {
if (encode_callback_ == nullptr) {
return false;
}

if (encode_callback_(*this, Canvas())) {
return true;
}

return false;
}

bool SurfaceFrame::PerformSubmit() {
if (submit_callback_ == nullptr) {
return false;
}

if (submit_callback_(*this, Canvas())) {
if (submit_callback_(*this)) {
return true;
}

Expand Down
23 changes: 22 additions & 1 deletion flow/surface_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace impeller {
class Surface;
}

namespace flutter {

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

// Information about the underlying framebuffer
struct FramebufferInfo {
Expand Down Expand Up @@ -58,6 +63,7 @@ class SurfaceFrame {

SurfaceFrame(sk_sp<SkSurface> surface,
FramebufferInfo framebuffer_info,
const EncodeCallback& encode_callback,
const SubmitCallback& submit_callback,
SkISize frame_size,
std::unique_ptr<GLContextResult> context_result = nullptr,
Expand Down Expand Up @@ -89,6 +95,8 @@ class SurfaceFrame {
bool frame_boundary = true;
};

bool Encode();

bool Submit();

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

sk_sp<DisplayList> BuildDisplayList();

void set_user_data(std::shared_ptr<impeller::Surface> data) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little wonky. For the impeller metal gpu surface, we construct the corresponding render target during the encode callback and not before - due to partial repaint - so we need a place to store the shared ptr for the present callback.

user_data_ = std::move(data);
}

std::shared_ptr<impeller::Surface> take_user_data() {
return std::move(user_data_);
}

private:
bool submitted_ = false;
bool encoded_ = false;

#if !SLIMPELLER
DlSkCanvasAdapter adapter_;
Expand All @@ -117,11 +134,15 @@ class SurfaceFrame {
DlCanvas* canvas_ = nullptr;
FramebufferInfo framebuffer_info_;
SubmitInfo submit_info_;
EncodeCallback encode_callback_;
SubmitCallback submit_callback_;
std::shared_ptr<impeller::Surface> user_data_;
std::unique_ptr<GLContextResult> context_result_;

bool PerformSubmit();

bool PerformEncode();

FML_DISALLOW_COPY_AND_ASSIGN(SurfaceFrame);
};

Expand Down
16 changes: 13 additions & 3 deletions flow/surface_frame_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ namespace flutter {

TEST(FlowTest, SurfaceFrameDoesNotSubmitInDtor) {
SurfaceFrame::FramebufferInfo framebuffer_info;
auto callback = [](const SurfaceFrame&, DlCanvas*) {
auto callback = [](const SurfaceFrame&) {
EXPECT_FALSE(true);
return true;
};
auto encode_callback = [](const SurfaceFrame&, DlCanvas*) {
EXPECT_FALSE(true);
return true;
};

auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/nullptr,
/*framebuffer_info=*/framebuffer_info,
/*encode_callback=*/encode_callback,
/*submit_callback=*/callback,
/*frame_size=*/SkISize::Make(800, 600));
surface_frame.reset();
Expand All @@ -26,10 +32,12 @@ TEST(FlowTest, SurfaceFrameDoesNotSubmitInDtor) {
TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) {
SurfaceFrame::FramebufferInfo framebuffer_info;
auto callback = [](const SurfaceFrame&, DlCanvas*) { return true; };
auto submit_callback = [](const SurfaceFrame&) { return true; };
SurfaceFrame frame(
/*surface=*/nullptr,
/*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/callback,
/*encode_callback=*/callback,
/*submit_callback=*/submit_callback,
/*frame_size=*/SkISize::Make(800, 600),
/*context_result=*/nullptr,
/*display_list_fallback=*/true);
Expand All @@ -41,10 +49,12 @@ TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) {
TEST(FlowTest, SurfaceFrameDoesNotPrepareRtree) {
SurfaceFrame::FramebufferInfo framebuffer_info;
auto callback = [](const SurfaceFrame&, DlCanvas*) { return true; };
auto submit_callback = [](const SurfaceFrame&) { return true; };
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/nullptr,
/*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/callback,
/*encode_callback=*/callback,
/*submit_callback=*/submit_callback,
/*frame_size=*/SkISize::Make(800, 600),
/*context_result=*/nullptr,
/*display_list_fallback=*/true);
Expand Down
48 changes: 23 additions & 25 deletions impeller/scene/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,35 +104,33 @@ auto renderer = impeller::Renderer(context);
while(true) {
std::unique_ptr<impeller::Surface> surface = /* Wrap the window surface */;

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

auto camera =
impeller::Camera::MakePerspective(
/* fov */ kPiOver4,
/* position */ {50, -30, 50})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, -1, 0});
/// Render a perspective view.

scene.Render(render_target, camera);
auto camera =
impeller::Camera::MakePerspective(
/* fov */ kPiOver4,
/* position */ {50, -30, 50})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, -1, 0});

scene.Render(render_target, camera);

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

auto size = render_target.GetRenderTargetSize();
auto minimap_camera =
impeller::Camera::MakeOrthographic(
/* view */ Rect::MakeLTRB(-100, -100, 100, 100),
/* position */ {0, -50, 0})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, 0, 1})
.WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4,
size.height / 5, size.height / 5));

scene.Render(render_target, minimap_camera);

return true;
});
auto size = render_target.GetRenderTargetSize();
auto minimap_camera =
impeller::Camera::MakeOrthographic(
/* view */ Rect::MakeLTRB(-100, -100, 100, 100),
/* position */ {0, -50, 0})
.LookAt(
/* target */ impeller::Vector3::Zero,
/* up */ {0, 0, 1})
.WithViewport(IRect::MakeXYWH(size.width / 4, size.height / 4,
size.height / 5, size.height / 5));

scene.Render(render_target, minimap_camera);
}
```
36 changes: 24 additions & 12 deletions shell/common/rasterizer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#define FML_USED_ON_EMBEDDER

#include "flow/surface_frame.h"
#include "flutter/shell/common/rasterizer.h"

#include <memory>
Expand Down Expand Up @@ -209,7 +210,8 @@ TEST(RasterizerTest,
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
Expand Down Expand Up @@ -287,7 +289,8 @@ TEST(
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
Expand Down Expand Up @@ -365,7 +368,8 @@ TEST(
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
Expand Down Expand Up @@ -440,12 +444,14 @@ TEST(RasterizerTest,
auto surface_frame1 = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
auto surface_frame2 = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled())
.WillRepeatedly(Return(true));
Expand Down Expand Up @@ -688,7 +694,8 @@ TEST(RasterizerTest, drawMultipleViewsWithExternalViewEmbedder) {
return std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
});
EXPECT_CALL(*surface, MakeRenderContextCurrent())
Expand Down Expand Up @@ -765,7 +772,8 @@ TEST(RasterizerTest,
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, /*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
Expand Down Expand Up @@ -826,7 +834,8 @@ TEST(
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, /*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true));
ON_CALL(delegate, GetIsGpuDisabledSyncSwitch())
Expand Down Expand Up @@ -888,7 +897,8 @@ TEST(
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, /*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false));
EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
Expand Down Expand Up @@ -949,7 +959,8 @@ TEST(
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, /*framebuffer_info=*/framebuffer_info,
/*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*encode_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame&) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false));
EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch())
Expand Down Expand Up @@ -1074,8 +1085,9 @@ TEST(RasterizerTest,
return std::make_unique<SurfaceFrame>(
/*surface=*/
nullptr, framebuffer_info,
/*submit_callback=*/
[](const SurfaceFrame& frame, DlCanvas*) { return true; },
/*encode_callback=*/
[](const SurfaceFrame&, DlCanvas*) { return true; },
/*submit_callback=*/[](const SurfaceFrame& frame) { return true; },
/*frame_size=*/SkISize::Make(800, 600));
}));
ON_CALL(*surface, MakeRenderContextCurrent())
Expand Down
10 changes: 7 additions & 3 deletions shell/common/shell_test_platform_view_vulkan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,21 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame(
SkAlphaType::kOpaque_SkAlphaType);
auto surface = SkSurfaces::RenderTarget(context_.get(), skgpu::Budgeted::kNo,
image_info, 0, nullptr);
SurfaceFrame::SubmitCallback callback = [](const SurfaceFrame&,
DlCanvas* canvas) -> bool {

SurfaceFrame::EncodeCallback encode_callback = [](const SurfaceFrame&,
DlCanvas* canvas) -> bool {
canvas->Flush();
return true;
};
SurfaceFrame::SubmitCallback submit_callback =
[](const SurfaceFrame&) -> bool { return true; };

SurfaceFrame::FramebufferInfo framebuffer_info;
framebuffer_info.supports_readback = true;

return std::make_unique<SurfaceFrame>(std::move(surface), framebuffer_info,
std::move(callback),
std::move(encode_callback),
std::move(submit_callback),
/*frame_size=*/SkISize::Make(800, 600));
}

Expand Down
Loading