blob: 5623f5e9aeeb7f0220ed3cf12caef4f80daf7855 [file] [log] [blame]
// Copyright 2022 The Fuchsia 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 SRC_EMBEDDER_FLATLAND_CONNECTION_H_
#define SRC_EMBEDDER_FLATLAND_CONNECTION_H_
#include <fuchsia/scenic/scheduling/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <cstdint>
#include <mutex>
#include <string>
namespace embedder {
using OnFramePresentedCallback =
std::function<void(fuchsia::scenic::scheduling::FramePresentedInfo)>;
/// The object residing on the raster thread that is responsible for
/// maintaining the Flatland instance connection and presenting updates.
///
/// Flatland is Fuchsia's 2D composition API, which lets us construct
/// a scene graph and submit that graph to be rendered.
///
/// See https://fuchsia.dev/fuchsia-src/concepts/ui/scenic/flatland?hl=en.
class FlatlandConnection final {
public:
/// Connects to the Flatland server via |flatland|.
///
/// - |debug_name| will be printed by the Flatland server in debugging
/// logs (`ffx inspect show core/ui/scenic`).
/// - |error_callback| will be fired when an error occurs in the Flatland
/// server.
/// - |on_frame_presented_callback| will be fired when a |Present()|
/// call actually presents the frame.
FlatlandConnection(std::string debug_name, fuchsia::ui::composition::FlatlandHandle flatland,
std::function<void()> on_error_callback,
OnFramePresentedCallback on_frame_presented_callback);
~FlatlandConnection();
FlatlandConnection(const FlatlandConnection&) = delete;
FlatlandConnection& operator=(const FlatlandConnection&) = delete;
/// Present immediately if we have a present credit,
/// otherwise queue to present once we've been given a present credit.
///
/// RASTER THREAD ONLY
void Present();
/// Get the Flatland client.
fuchsia::ui::composition::Flatland* flatland() { return flatland_.get(); }
/// Get a new ID for a Flatland transform.
fuchsia::ui::composition::TransformId NextTransformId() { return {++next_transform_id_}; }
/// Get a new ID for Flatland content (for example, an image).
fuchsia::ui::composition::ContentId NextContentId() { return {++next_content_id_}; }
/// Block |Present| until |fence| has been signalled.
///
/// Flatland will not be able to |Present| until all queued acquire
/// fences have been signalled.
///
/// RASTER THREAD ONLY
void EnqueueAcquireFence(zx::event fence);
/// Adds a |fence| that will be signalled when Flatland
/// has finished using resources and shared buffers from the |Present| call.
///
/// RASTER THREAD ONLY
void EnqueueReleaseFence(zx::event fence);
// TODO(akbiggs): Either implement vsyncing logic from
// https://github.com/flutter/engine/blob/d05d681a841e5d65db2a2fbf6ca0d1187e29c3a2/shell/platform/fuchsia/flutter/flatland_connection.h#L47
// or move it elsewhere.
private:
/// See fuchsia.ui.composition.Flatland.OnError:
/// https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.composition/flatland.fidl;l=435;drc=a4c898b7f54ae07986a3f6f3c246d80953b2cbf8
void OnError(fuchsia::ui::composition::FlatlandError error);
/// See fuchsia.ui.composition.Flatland.OnNextFrameBegin:
/// https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.composition/flatland.fidl;l=410;drc=a4c898b7f54ae07986a3f6f3c246d80953b2cbf8
///
/// RASTER THREAD ONLY
void OnNextFrameBegin(fuchsia::ui::composition::OnNextFrameBeginValues values);
/// See fuchsia.ui.composition.Flatland.OnFramePresented:
/// https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.composition/flatland.fidl;l=425;drc=a4c898b7f54ae07986a3f6f3c246d80953b2cbf8
///
/// RASTER THREAD ONLY
void OnFramePresented(fuchsia::scenic::scheduling::FramePresentedInfo info);
/// Present immediately without any queuing.
///
/// RASTER THREAD ONLY
void DoPresent();
/// Our connection to the Flatland server.
fuchsia::ui::composition::FlatlandPtr flatland_;
/// Called when the Flatland server reports an error to the client.
std::function<void()> on_error_callback_;
/// Called when the Flatland server finishes presenting a frame.
OnFramePresentedCallback on_frame_presented_callback_;
uint64_t next_transform_id_ = 0;
uint64_t next_content_id_ = 0;
/// If true, we have a queued |Present| call.
bool present_pending_ = false;
/// The Flatland server gives a "present credit" to the Flatland client
/// at the start of each frame to allow the client to present. This field
/// tracks how many credits we have been given by the server.
///
/// We start with one present credit per
/// https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.composition/flatland.fidl;l=384;drc=a4c898b7f54ae07986a3f6f3c246d80953b2cbf8.
uint32_t present_credits_ = 1;
/// Events that need to be signalled to unblock |Present|.
std::vector<zx::event> acquire_fences_;
/// Events that will be signalled when the current |Present| call
/// is finished with all resources and shared buffers.
std::vector<zx::event> current_present_release_fences_;
/// Events that will be signalled when the previous |Present| call
/// is finished with all resources and shared buffers.
std::vector<zx::event> previous_present_release_fences_;
};
} // namespace embedder
#endif // SRC_EMBEDDER_FLATLAND_CONNECTION_H_