Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,7 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_tzdata_unittest.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_unittest.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface_producer.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.cc
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.h
FILE: ../../../flutter/shell/platform/fuchsia/flutter/unique_fdio_ns.h
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/fuchsia/flutter/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ template("runner_sources") {
"runner.h",
"surface.cc",
"surface.h",
"surface_producer.h",
"task_runner_adapter.cc",
"task_runner_adapter.h",
"unique_fdio_ns.h",
Expand Down Expand Up @@ -465,6 +466,7 @@ executable("flutter_runner_unittests") {
"tests/engine_unittests.cc",
"tests/fake_session_unittests.cc",
"tests/flutter_runner_product_configuration_unittests.cc",
"tests/fuchsia_external_view_embedder_unittests.cc",
"tests/gfx_session_connection_unittests.cc",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ FlatlandExternalViewEmbedder::FlatlandExternalViewEmbedder(
fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
parent_viewport_watcher_request,
FlatlandConnection& flatland,
VulkanSurfaceProducer& surface_producer,
SurfaceProducer& surface_producer,
bool intercept_all_input)
: flatland_(flatland), surface_producer_(surface_producer) {
flatland_.flatland()->CreateView(std::move(view_creation_token),
Expand Down Expand Up @@ -309,7 +309,7 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
{
TRACE_EVENT0("flutter", "PresentSurfaces");

surface_producer_.OnSurfacesPresented(std::move(frame_surfaces));
surface_producer_.SubmitSurfaces(std::move(frame_surfaces));
}

// Submit the underlying render-backend-specific frame for processing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,8 @@
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"

#include "flatland_connection.h"
#include "vulkan_surface_producer.h"
#include "surface_producer.h"

namespace flutter_runner {

Expand All @@ -50,7 +47,7 @@ class FlatlandExternalViewEmbedder final
fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
parent_viewport_watcher_request,
FlatlandConnection& flatland,
VulkanSurfaceProducer& surface_producer,
SurfaceProducer& surface_producer,
bool intercept_all_input = false);
~FlatlandExternalViewEmbedder();

Expand Down Expand Up @@ -167,7 +164,7 @@ class FlatlandExternalViewEmbedder final
};

FlatlandConnection& flatland_;
VulkanSurfaceProducer& surface_producer_;
SurfaceProducer& surface_producer_;
fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher_;

fuchsia::ui::composition::TransformId root_transform_id_;
Expand Down
12 changes: 3 additions & 9 deletions shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@
namespace flutter_runner {
namespace {

// Layer separation is as infinitesimal as possible without introducing
// Z-fighting.
constexpr float kScenicZElevationBetweenLayers = 0.0001f;
constexpr float kScenicZElevationForPlatformView = 100.f;
constexpr float kScenicElevationForInputInterceptor = 500.f;

ViewMutators ParseMutatorStack(const flutter::MutatorsStack& mutators_stack) {
ViewMutators mutators;
SkMatrix total_transform = SkMatrix::I();
Expand Down Expand Up @@ -110,7 +104,7 @@ FuchsiaExternalViewEmbedder::FuchsiaExternalViewEmbedder(
fuchsia::ui::views::ViewToken view_token,
scenic::ViewRefPair view_ref_pair,
GfxSessionConnection& session,
VulkanSurfaceProducer& surface_producer,
SurfaceProducer& surface_producer,
bool intercept_all_input)
: session_(session),
surface_producer_(surface_producer),
Expand Down Expand Up @@ -491,7 +485,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
// This does not cause visual problems in practice, but probably has
// performance implications.
const SkAlpha layer_opacity =
first_layer ? SK_AlphaOPAQUE : SK_AlphaOPAQUE - 1;
first_layer ? kBackgroundLayerOpacity : kOverlayLayerOpacity;
const float layer_elevation =
kScenicZElevationBetweenLayers * scenic_layer_index +
embedded_views_height;
Expand Down Expand Up @@ -569,7 +563,7 @@ void FuchsiaExternalViewEmbedder::SubmitFrame(
{
TRACE_EVENT0("flutter", "PresentSurfaces");

surface_producer_.OnSurfacesPresented(std::move(frame_surfaces));
surface_producer_.SubmitSurfaces(std::move(frame_surfaces));
}

// Submit the underlying render-backend-specific frame for processing.
Expand Down
14 changes: 11 additions & 3 deletions shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include "third_party/skia/include/gpu/GrDirectContext.h"

#include "gfx_session_connection.h"
#include "vulkan_surface_producer.h"
#include "surface_producer.h"

namespace flutter_runner {

Expand Down Expand Up @@ -64,11 +64,19 @@ struct ViewMutators {
// correctly in a unified scene.
class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder {
public:
// Layer separation is as infinitesimal as possible without introducing
// Z-fighting.
constexpr static float kScenicZElevationBetweenLayers = 0.0001f;
constexpr static float kScenicZElevationForPlatformView = 100.f;
constexpr static float kScenicElevationForInputInterceptor = 500.f;
constexpr static SkAlpha kBackgroundLayerOpacity = SK_AlphaOPAQUE;
constexpr static SkAlpha kOverlayLayerOpacity = SK_AlphaOPAQUE - 1;

FuchsiaExternalViewEmbedder(std::string debug_label,
fuchsia::ui::views::ViewToken view_token,
scenic::ViewRefPair view_ref_pair,
GfxSessionConnection& session,
VulkanSurfaceProducer& surface_producer,
SurfaceProducer& surface_producer,
bool intercept_all_input = false);
~FuchsiaExternalViewEmbedder();

Expand Down Expand Up @@ -170,7 +178,7 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder {
};

GfxSessionConnection& session_;
VulkanSurfaceProducer& surface_producer_;
SurfaceProducer& surface_producer_;

scenic::View root_view_;
scenic::EntityNode metrics_node_;
Expand Down
58 changes: 23 additions & 35 deletions shell/platform/fuchsia/flutter/gfx_session_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,9 @@ GfxSessionConnection::GfxSessionConnection(
// Scenic retired a given number of frames, so mark them as completed.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, num_presents_handled,
now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
inspect_dispatcher_, [this, now = Now(), num_presents_handled]() {
presents_completed_.Add(num_presents_handled);
last_frame_completed_.Set(now);
last_frame_completed_.Set(now.ToEpochDelta().ToNanoseconds());
});

if (fire_callback_request_pending_) {
Expand Down Expand Up @@ -300,17 +298,15 @@ void GfxSessionConnection::Present() {
next_present_session_trace_id_);
++next_present_session_trace_id_;

auto now = fml::TimePoint::Now();
auto now = Now();
present_requested_time_ = now;

// Flutter is requesting a frame here, so mark it as such.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
presents_requested_.Add(1);
last_frame_requested_.Set(now);
});
async::PostTask(inspect_dispatcher_, [this, now]() {
presents_requested_.Add(1);
last_frame_requested_.Set(now.ToEpochDelta().ToNanoseconds());
});

// Throttle frame submission to Scenic if we already have the maximum amount
// of frames in flight. This allows the paint tasks for this frame to execute
Expand All @@ -333,12 +329,10 @@ void GfxSessionConnection::AwaitVsync(FireCallbackCallback callback) {

// Flutter is requesting a vsync here, so mark it as such.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
vsyncs_requested_.Add(1);
last_vsync_requested_.Set(now);
});
async::PostTask(inspect_dispatcher_, [this, now = Now()]() {
vsyncs_requested_.Add(1);
last_vsync_requested_.Set(now.ToEpochDelta().ToNanoseconds());
});

FireCallbackMaybe();
}
Expand All @@ -352,12 +346,10 @@ void GfxSessionConnection::AwaitVsyncForSecondaryCallback(

// Flutter is requesting a secondary vsync here, so mark it as such.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
secondary_vsyncs_completed_.Add(1);
last_secondary_vsync_completed_.Set(now);
});
async::PostTask(inspect_dispatcher_, [this, now = Now()]() {
secondary_vsyncs_completed_.Add(1);
last_secondary_vsync_completed_.Set(now.ToEpochDelta().ToNanoseconds());
});

FlutterFrameTimes times = GetTargetTimesHelper(/*secondary_callback=*/true);
fire_callback_(times.frame_start, times.frame_target);
Expand Down Expand Up @@ -391,12 +383,10 @@ void GfxSessionConnection::PresentSession() {

// Flutter is presenting a frame here, so mark it as such.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
presents_submitted_.Add(1);
last_frame_presented_.Set(now);
});
async::PostTask(inspect_dispatcher_, [this, now = Now()]() {
presents_submitted_.Add(1);
last_frame_presented_.Set(now.ToEpochDelta().ToNanoseconds());
});

session_wrapper_.Present2(
/*requested_presentation_time=*/next_latch_point.ToEpochDelta()
Expand Down Expand Up @@ -441,12 +431,10 @@ void GfxSessionConnection::FireCallbackMaybe() {

// Scenic completed a vsync here, so mark it as such.
// Inspect updates must run on the inspect dispatcher.
async::PostTask(
inspect_dispatcher_,
[this, now = fml::TimePoint::Now().ToEpochDelta().ToNanoseconds()]() {
vsyncs_completed_.Add(1);
last_vsync_completed_.Set(now);
});
async::PostTask(inspect_dispatcher_, [this, now = Now()]() {
vsyncs_completed_.Add(1);
last_vsync_completed_.Set(now.ToEpochDelta().ToNanoseconds());
});

fire_callback_(times.frame_start, times.frame_target);
} else {
Expand Down
78 changes: 78 additions & 0 deletions shell/platform/fuchsia/flutter/surface_producer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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_PLATFORM_FUCHSIA_FLUTTER_SURFACE_PRODUCER_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_SURFACE_PRODUCER_H_

#include <fuchsia/ui/composition/cpp/fidl.h>
#include <lib/zx/event.h>

#include <functional>
#include <memory>
#include <vector>

#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter_runner {

using ReleaseImageCallback = std::function<void()>;

// This represents an abstract notion of a "rendering surface", which is a
// destination for pixels drawn by some rendering engine. In this case, the
// rendering engine is Skia combined with one of its rendering backends.
//
// In addition to allowing Skia-based drawing via `GetSkiaSurface`, this
// rendering surface can be shared with Scenic via `SetImageId`,
// `GetBufferCollectionImportToken`, `GetAcquireFene`, and `GetReleaseFence`.
class SurfaceProducerSurface {
public:
virtual ~SurfaceProducerSurface() = default;

virtual bool IsValid() const = 0;

virtual SkISize GetSize() const = 0;

virtual void SetImageId(uint32_t image_id) = 0;

virtual uint32_t GetImageId() = 0;

virtual sk_sp<SkSurface> GetSkiaSurface() const = 0;

virtual fuchsia::ui::composition::BufferCollectionImportToken
GetBufferCollectionImportToken() = 0;

virtual zx::event GetAcquireFence() = 0;

virtual zx::event GetReleaseFence() = 0;

virtual void SetReleaseImageCallback(
ReleaseImageCallback release_image_callback) = 0;

virtual size_t AdvanceAndGetAge() = 0;

virtual bool FlushSessionAcquireAndReleaseEvents() = 0;

virtual void SignalWritesFinished(
const std::function<void(void)>& on_writes_committed) = 0;
};

// This represents an abstract notion of "surface producer", which serves as a
// source for `SurfaceProducerSurface`s. Produces surfaces should be returned
// to this `SurfaceProducer` via `SubmitSurfaces`, at which point they will be
// shared with Scenic.
class SurfaceProducer {
public:
virtual ~SurfaceProducer() = default;

virtual std::unique_ptr<SurfaceProducerSurface> ProduceSurface(
const SkISize& size) = 0;

virtual void SubmitSurfaces(
std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) = 0;
};

} // namespace flutter_runner

#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_SURFACE_PRODUCER_H_
Loading