blob: bb90d0ade6950adc2617296db07cf29e00db16f2 [file] [log] [blame]
// Copyright 2020 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_UI_SCENIC_LIB_FLATLAND_RENDERER_RENDERER_H_
#define SRC_UI_SCENIC_LIB_FLATLAND_RENDERER_RENDERER_H_
#include <lib/zx/event.h>
#include <optional>
#include "src/ui/scenic/lib/flatland/renderer/buffer_collection_importer.h"
// clang-format off
#include "src/ui/lib/glm_workaround/glm_workaround.h"
// clang-format on
#include <glm/mat3x3.hpp>
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
#include "src/ui/lib/escher/geometry/types.h"
namespace flatland {
// Typedef to a flatland type.
using Rectangle2D = escher::Rectangle2D;
// Contains information regarding the constraints of a particular buffer collection. This
// should be used by the Flatland instance to check that images it wishes to create are
// valid. More information may be added to this struct over time.
struct BufferCollectionMetadata {
// The number of vmos available in the buffer collection.
uint32_t vmo_count;
// Various image constraint information, including max width/height and supported
// pixel formats. See |constraints.fidl| for more information.
fuchsia::sysmem::ImageFormatConstraints image_constraints;
};
// This is the main renderer interface used by the Flatland System. Since Flatland is
// agnostic to the implementation of the renderer, it is declared here as a virtual
// interface, whose concrete implementation is to be injected into Flatland.
class Renderer : public BufferCollectionImporter {
public:
// This function is for registering collections that contain render targets. In order for an image
// to be used as a render target in the Render() function below, the buffer collection it
// is associated with must have been registered with this function.
//
// This function is likewise threadsafe, although it is only meant to be called from the render
// loop, and not by any flatland instance directly.
virtual bool RegisterRenderTargetCollection(
sysmem_util::GlobalBufferCollectionId collection_id,
fuchsia::sysmem::Allocator_Sync* sysmem_allocator,
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token) = 0;
// Removes a buffer collection used for render targets from the renderer. Once done, the
// collection_id can be reused for another buffer collection.
virtual void DeregisterRenderTargetCollection(
sysmem_util::GlobalBufferCollectionId collection_id) = 0;
// This function validates if the buffer collection referenced by |collection_id| is ready to
// be used in rendering operations and must be called before that buffer collection is used
// in |Render|. Specifically, this function checks to make sure that the buffer collection is
// fully allocated (which can only happen after all token holders have set constraints and the
// client has requested for sysmem to allocate the buffer collection via a call to
// WaitForBuffersAllocated() or an equivalent function).
//
// If the collection has not yet been fully allocated, or if the collection has not been
// registered with the renderer via a call to RegisterBufferCollection(), this function will
// return std::nullopt. If the collection has been registered and has been fully allocated, then
// this function will return a BufferCollectionMetadata struct containing information pertaining
// to the number of vmos as well as image constraints, such as maximum width/height (see
// BufferCollectionMetadata at the top of this file for more information).
//
// The BufferCollectionMetadata can then be used by the Flatland instance to verify images it
// wishes to create with this buffer collection. Images map N:1 with buffer collections, since a
// collection can consist of multiple VMOs, and each VMO in turn can back multiple images. The
// intended usage then is for the Flatland instance to store the BufferCollectionMetadata it
// receives and use it to compare against any incoming images. For example, if a buffer collection
// only has 5 VMOs and an image is referencing vmo index 6, then that would be an error.
//
// This function needs to be separate from RegisterBufferCollection() since it is too early to
// return a |BufferCollectionMetadata| struct at registration time., as the client may have not
// yet set their constraints, or duplicated their token. Combining this function with the above
// registration function would require us to block on registration, which could go on forever.
//
// Lastly, this function needs to communicate with sysmem and may take some time. However, it does
// not block indefinitely. Additionally, it only needs to be called once per buffer collection if
// the call was successful. It is up to the Flatland instance how to proceed in the event of
// failure. Calling this function multiple times until it returns true is allowed.
virtual std::optional<BufferCollectionMetadata> Validate(
sysmem_util::GlobalBufferCollectionId collection_id) = 0;
// This function is responsible for rendering a single batch of Flatland rectangles into a
// render target. This function is designed to be called on the render thread, not on any
// Flatland instance thread. The specific behavior may differ depending on the specific subclass
// implementation, which may also be a null renderer.
//
// This function assumes that clients have already validated their input data by comparing it
// against the BufferCollectionMetadata received from calling |Validate| above. This function
// will abort if invalid data has been passed in or if |Validate| has never been called.
//
// The size of the arrays |rectangles| and |images| must match or else this function will CHECK.
// Entries in each array with the same index will be used together in rendering.
//
// The vector of release fences will be signaled once rendering has completed. Clients can use
// these fences to coordinate with other work that needs to wait until rendering is completed
// to be executed.
virtual void Render(const ImageMetadata& render_target,
const std::vector<Rectangle2D>& rectangles,
const std::vector<ImageMetadata>& images,
const std::vector<zx::event>& release_fences = {}) = 0;
virtual ~Renderer() = default;
};
} // namespace flatland
#endif // SRC_UI_SCENIC_LIB_FLATLAND_RENDERER_RENDERER_H_