| // 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_ |