{% set rfcid = “RFC-0162” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
{# Fuchsia RFCs use templates to display various fields from _rfcs.yaml. View the #} {# fully rendered RFCs at https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs #}
This RFC was previously submitted as an API design document and converted to an RFC afterwards when the API design doc template was deprecated.
This document proposes a 2D API for Fuchsia graphics clients. Flatland offers a display-controller-like functionality to clients where the resources are defined in a 2D world.
Scenic currently provides graphics clients with a 3D API under the fuchsia.ui.gfx
namespace (the “gfx api”). This 3D API provides clients with a scene model similar to video game engines or other 3D graphics programs. Drawing order is handled by Z depth and opacity is handled via alpha blending based on depth. Unfortunately the gfx API is no longer suitable for the demands being placed on Scenic, both from a product standpoint and a performance standpoint. Features like group opacity are impossible, because how to handle shadows for a group of translucent content is unclear.
From the product standpoint, our current customers are 2D products. There is no concept of depth and draw order. They are simply in the order that different batches of draw geometry are submitted in. Because there is no depth, transparency effects are also dictated by draw order. The “2D” clients (via Flutter, Chromium, and session framework) have to do extra work to resolve the mismatch between Scenic's 3D scene representation and the 2D representation experienced by the user.
From the performance standpoint, modern Video Display Controller (VDC) hardware provides acceleration features such as multiple display planes and hardware overlays that Scenic would like to leverage in the future to lower power consumption and GPU usage. The hardware operates in a strictly 2D paradigm however, and only understands rectangular layers that can be positioned in X/Y. Scenic‘s current 3D API allows and encourages clients to submit content that doesn’t fit into this paradigm and frustrates optimization attempts.
By exposing a true 2D API we intend to make our 2D clients life better:
Our suggestion is to write a 2D protocol from scratch that doesn't reuse parts of fuchsia.ui.gfx
.
The current state of the proposed 2D API is in the fuchsia.ui.scenic.internal.flatland
library being submitted as part of this review. Please take a look at and drop comments.
Here are explanations for some high level decisions made around Flatland API:
fuchsia.hardware.display/Controller
.fuchsia.ui.composition/Allocator
.Flatland design might evolve in some areas to better fit the clients needs.
Please take a look at out in-tree tests on flatland_unittest to find an extensive set of examples of Flatland API usage.
Below is a figure that explains how a connected graph that links multiple Flatland sessions would work. This is a more complex but common use case.
Figure 1 - Flatland
Flatland is currently defined as an internal API and testing is provided by in-tree unit tests. Since there is no other way to run Flatland code other than tests, we have been extensively covering every code with an automated test. We are planning to maintain this test coverage and quality.
We are planning to eventually convert every graphics example to Flatland. We do not have any clients that strictly need to live in a 3D world. We are currently working on having a Flatland presenter to be the basis for the addition and migration of in-tree integration tests fxbug.dev/76315. This will prepare us towards the future migration of some critical external clients, such as Flutter and Chromium.
Flatland is designed to allow running business logic without dependency on hardware capabilities, such as Vulkan and display. Vulkan can be swapped by the null renderer implementation, which skips compositing. Display can be swapped the existing fake display implementation.
Additional Flatland API integration tests will be provided under Compatibility Test Suite.
Flatland has been designed to allow many clients to operate at the same time without affecting each other’s work.
num_presents_returned
. The client may not call Present() more times than it is allowed by OnPresentProcessed(). Each client starts with one present allowance.Flatland users are isolated from each other. Each of them connect to Scenic through their own channels. Unique resource identifiers are defined only within the scope of their channel. They can only target the portion of the screen that is defined by their parent Flatland session.
Each error case causes Flatland channel closure. In these error states, it is not clear what should be drawn on the screen, so we don’t see any point to allow the client to keep presenting.
Flatland does not expose any device identifiers or privacy-sensitive information. The client does not interact with the hardware directly.
Flatland allows the client to set an identifiable debug string through SetDebugName(). This is used as a prefix when printing detailed system logs about errors to help the client distinguish what is theirs. The client has full control over what to set here, and if nothing is set, there is no prefix in system logs.
What we learned from the existing 3D api under fuchsia.ui.gfx
is the basis for the decision made for the 2D API of Flatland. We took into account all the user feedback, bugs and lessons when making design decisions.
fuchsia.ui.gfx
did. Currently, each Flatland command is mapped as a FIDL method. This decision was made because of the negatives observed with the existing command pattern in 3D API. We had to provide and maintain wrappers in different languages for the clients. However, there are some negatives about mapping each comment as a method. This design prevents batching until support for multiple messages in single write becomes available. However, we don’t expect the clients to manipulate the scene graph often and don’t consider this costly.There are some areas that we plan to work on for improving Flatland API: