Skip to content

Commit

Permalink
Pass SurfaceFrame to SubmitFrame (flutter#18709)
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmanuel Garcia authored Jun 3, 2020
1 parent 33a1f1a commit 243bb59
Show file tree
Hide file tree
Showing 21 changed files with 175 additions and 155 deletions.
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ FILE: ../../../flutter/shell/common/skia_event_tracer_impl.cc
FILE: ../../../flutter/shell/common/skia_event_tracer_impl.h
FILE: ../../../flutter/shell/common/surface.cc
FILE: ../../../flutter/shell/common/surface.h
FILE: ../../../flutter/shell/common/surface_frame.cc
FILE: ../../../flutter/shell/common/surface_frame.h
FILE: ../../../flutter/shell/common/switches.cc
FILE: ../../../flutter/shell/common/switches.h
FILE: ../../../flutter/shell/common/thread_host.cc
Expand Down
1 change: 1 addition & 0 deletions flow/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ source_set("flow") {
deps = [
"//flutter/common",
"//flutter/fml",
"//flutter/shell/common:surface_frame",
"//third_party/skia",
]

Expand Down
6 changes: 2 additions & 4 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
namespace flutter {

bool ExternalViewEmbedder::SubmitFrame(GrContext* context,
SkCanvas* background_canvas) {
return false;
std::unique_ptr<SurfaceFrame> frame) {
return frame->Submit();
};

void ExternalViewEmbedder::FinishFrame(){};

void MutatorsStack::PushClipRect(const SkRect& rect) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rect);
vector_.push_back(element);
Expand Down
12 changes: 8 additions & 4 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "flutter/fml/memory/ref_counted.h"
#include "flutter/fml/raster_thread_merger.h"
#include "flutter/shell/common/surface_frame.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
Expand Down Expand Up @@ -248,10 +249,13 @@ class ExternalViewEmbedder {
// Must be called on the UI thread.
virtual SkCanvas* CompositeEmbeddedView(int view_id) = 0;

virtual bool SubmitFrame(GrContext* context, SkCanvas* background_canvas);

// This is called after submitting the embedder frame and the surface frame.
virtual void FinishFrame();
// Implementers must submit the frame by calling frame.Submit().
//
// This method can mutate the root Skia canvas before submitting the frame.
//
// It can also allocate frames for overlay surfaces to compose hybrid views.
virtual bool SubmitFrame(GrContext* context,
std::unique_ptr<SurfaceFrame> frame);

// This should only be called after |SubmitFrame|.
// This method provides the embedder a way to do additional tasks after
Expand Down
13 changes: 13 additions & 0 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ source_set("common") {
]

deps = [
":surface_frame",
"//flutter/assets",
"//flutter/common",
"//flutter/flow",
Expand All @@ -141,6 +142,18 @@ source_set("common") {
public_configs = [ "//flutter:config" ]
}

source_set("surface_frame") {
sources = [
"surface_frame.cc",
"surface_frame.h",
]

deps = [
"//flutter/fml",
"//third_party/skia",
]
}

template("shell_host_executable") {
executable(target_name) {
testonly = true
Expand Down
9 changes: 2 additions & 7 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,14 +421,9 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
return raster_status;
}
if (external_view_embedder != nullptr) {
FML_DCHECK(!frame->IsSubmitted());
external_view_embedder->SubmitFrame(surface_->GetContext(),
root_surface_canvas);
// The external view embedder may mutate the root surface canvas while
// submitting the frame.
// Therefore, submit the final frame after asking the external view
// embedder to submit the frame.
frame->Submit();
external_view_embedder->FinishFrame();
std::move(frame));
} else {
frame->Submit();
}
Expand Down
10 changes: 4 additions & 6 deletions shell/common/shell_test_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,12 @@ SkCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView(int view_id) {
}

// |ExternalViewEmbedder|
bool ShellTestExternalViewEmbedder::SubmitFrame(GrContext* context,
SkCanvas* background_canvas) {
return true;
bool ShellTestExternalViewEmbedder::SubmitFrame(
GrContext* context,
std::unique_ptr<SurfaceFrame> frame) {
return frame->Submit();
}

// |ExternalViewEmbedder|
void ShellTestExternalViewEmbedder::FinishFrame() {}

// |ExternalViewEmbedder|
void ShellTestExternalViewEmbedder::EndFrame(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
Expand Down
6 changes: 2 additions & 4 deletions shell/common/shell_test_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
SkCanvas* CompositeEmbeddedView(int view_id) override;

// |ExternalViewEmbedder|
bool SubmitFrame(GrContext* context, SkCanvas* background_canvas) override;

// |ExternalViewEmbedder|
void FinishFrame() override;
bool SubmitFrame(GrContext* context,
std::unique_ptr<SurfaceFrame> frame) override;

// |ExternalViewEmbedder|
void EndFrame(
Expand Down
50 changes: 0 additions & 50 deletions shell/common/surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,8 @@

#include "flutter/shell/common/surface.h"

#include "flutter/fml/logging.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter {

SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
bool supports_readback,
const SubmitCallback& submit_callback)
: submitted_(false),
surface_(surface),
supports_readback_(supports_readback),
submit_callback_(submit_callback) {
FML_DCHECK(submit_callback_);
}

SurfaceFrame::~SurfaceFrame() {
if (submit_callback_ && !submitted_) {
// Dropping without a Submit.
submit_callback_(*this, nullptr);
}
}

bool SurfaceFrame::Submit() {
if (submitted_) {
return false;
}

submitted_ = PerformSubmit();

return submitted_;
}

SkCanvas* SurfaceFrame::SkiaCanvas() {
return surface_ != nullptr ? surface_->getCanvas() : nullptr;
}

sk_sp<SkSurface> SurfaceFrame::SkiaSurface() const {
return surface_;
}

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

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

return false;
}

Surface::Surface() = default;

Surface::~Surface() = default;
Expand Down
34 changes: 1 addition & 33 deletions shell/common/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,10 @@
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "flutter/shell/common/surface_frame.h"

namespace flutter {

/// 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 =
std::function<bool(const SurfaceFrame& surface_frame, SkCanvas* canvas)>;

SurfaceFrame(sk_sp<SkSurface> surface,
bool supports_readback,
const SubmitCallback& submit_callback);

~SurfaceFrame();

bool Submit();

SkCanvas* SkiaCanvas();

sk_sp<SkSurface> SkiaSurface() const;

bool supports_readback() { return supports_readback_; }

private:
bool submitted_;
sk_sp<SkSurface> surface_;
bool supports_readback_;
SubmitCallback submit_callback_;

bool PerformSubmit();

FML_DISALLOW_COPY_AND_ASSIGN(SurfaceFrame);
};

/// Abstract Base Class that represents where we will be rendering content.
class Surface {
public:
Expand Down
61 changes: 61 additions & 0 deletions shell/common/surface_frame.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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/common/surface_frame.h"

#include "flutter/fml/logging.h"

namespace flutter {

SurfaceFrame::SurfaceFrame(sk_sp<SkSurface> surface,
bool supports_readback,
const SubmitCallback& submit_callback)
: surface_(surface),
supports_readback_(supports_readback),
submit_callback_(submit_callback) {
FML_DCHECK(submit_callback_);
}

SurfaceFrame::~SurfaceFrame() {
if (submit_callback_ && !submitted_) {
// Dropping without a Submit.
submit_callback_(*this, nullptr);
}
}

bool SurfaceFrame::Submit() {
if (submitted_) {
return false;
}

submitted_ = PerformSubmit();

return submitted_;
}

bool SurfaceFrame::IsSubmitted() const {
return submitted_;
}

SkCanvas* SurfaceFrame::SkiaCanvas() {
return surface_ != nullptr ? surface_->getCanvas() : nullptr;
}

sk_sp<SkSurface> SurfaceFrame::SkiaSurface() const {
return surface_;
}

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

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

return false;
}

} // namespace flutter
52 changes: 52 additions & 0 deletions shell/common/surface_frame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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_COMMON_SURFACE_FRAME_H_
#define FLUTTER_SHELL_COMMON_SURFACE_FRAME_H_

#include <memory>

#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter {

/// 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 =
std::function<bool(const SurfaceFrame& surface_frame, SkCanvas* canvas)>;

SurfaceFrame(sk_sp<SkSurface> surface,
bool supports_readback,
const SubmitCallback& submit_callback);

~SurfaceFrame();

bool Submit();

bool IsSubmitted() const;

SkCanvas* SkiaCanvas();

sk_sp<SkSurface> SkiaSurface() const;

bool supports_readback() { return supports_readback_; }

private:
bool submitted_ = false;
sk_sp<SkSurface> surface_;
bool supports_readback_;
SubmitCallback submit_callback_;

bool PerformSubmit();

FML_DISALLOW_COPY_AND_ASSIGN(SurfaceFrame);
};

} // namespace flutter

#endif // FLUTTER_SHELL_COMMON_SURFACE_FRAME_H_
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,18 @@ std::vector<SkCanvas*> AndroidExternalViewEmbedder::GetCurrentCanvases() {
}

// |ExternalViewEmbedder|
bool AndroidExternalViewEmbedder::SubmitFrame(GrContext* context,
SkCanvas* background_canvas) {
bool AndroidExternalViewEmbedder::SubmitFrame(
GrContext* context,
std::unique_ptr<SurfaceFrame> frame) {
// TODO(egarciad): Implement hybrid composition.
// https://github.com/flutter/flutter/issues/55270
TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame");
for (size_t i = 0; i < composition_order_.size(); i++) {
int64_t view_id = composition_order_[i];
background_canvas->drawPicture(
frame->SkiaCanvas()->drawPicture(
picture_recorders_[view_id]->finishRecordingAsPicture());
}
return true;
return frame->Submit();
}

// |ExternalViewEmbedder|
Expand Down Expand Up @@ -83,11 +84,6 @@ void AndroidExternalViewEmbedder::CancelFrame() {
ClearFrame();
}

// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::FinishFrame() {
ClearFrame();
}

// |ExternalViewEmbedder|
void AndroidExternalViewEmbedder::EndFrame(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {}
Expand Down
Loading

0 comments on commit 243bb59

Please sign in to comment.