blob: 2b76a747e328bae0808a30352548228586fa01d4 [file] [log] [blame] [edit]
// Copyright 2023 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_GRAPHICS_DISPLAY_TESTING_SOFTWARE_COMPOSITOR_SOFTWARE_COMPOSITOR_H_
#define SRC_GRAPHICS_DISPLAY_TESTING_SOFTWARE_COMPOSITOR_SOFTWARE_COMPOSITOR_H_
#include <cstdint>
#include <span>
#include "src/graphics/display/lib/api-types/cpp/alpha-mode.h"
#include "src/graphics/display/lib/api-types/cpp/color.h"
#include "src/graphics/display/lib/api-types/cpp/coordinate-transformation.h"
#include "src/graphics/display/lib/api-types/cpp/rectangle.h"
#include "src/graphics/display/testing/software-compositor/pixel.h"
namespace software_compositor {
struct Offset2D {
int x;
int y;
};
inline bool operator==(const Offset2D& lhs, const Offset2D& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
inline bool operator!=(const Offset2D& lhs, const Offset2D& rhs) { return !(lhs == rhs); }
struct ImageProperties {
int width;
int height;
int stride_bytes;
PixelFormat pixel_format;
};
struct OutputImage {
public:
inline PixelData At(const Offset2D& offset) const;
inline void SetPixelData(const Offset2D& offset, const PixelData& color) const;
std::span<uint8_t> buffer;
ImageProperties properties;
};
struct InputImage {
public:
inline PixelData At(const Offset2D& offset) const;
static const InputImage kNoInputImage;
// Empty iff the input has no image.
std::span<const uint8_t> buffer;
ImageProperties properties;
};
// static
constexpr InputImage InputImage::kNoInputImage = {
.buffer = {},
.properties = {},
};
// A compositor using software rendering to fill solid colors and draw images
// onto an output image (canvas).
class SoftwareCompositor {
public:
// Properties of composition of a layer onto the canvas.
struct CompositionProperties {
// Only the `image_source` part of the input image will be clipped and used.
//
// Equivalent to the `image_source` field in FIDL
// [`fuchsia.hardware.display.engine/Layer`] struct.
::display::Rectangle image_source;
// The destination (canvas) frame. The clipped input image will be scaled
// and painted onto the `canvas_destination` region of the canvas.
// `canvas_destination` will be cropped to the extent of the canvas.
//
// Equivalent to the `display_destination` field in FIDL
// [`fuchsia.hardware.display.engine/Layer`] struct.
::display::Rectangle canvas_destination;
// Indicates how image will be transformed (rotated / flipped).
//
// Equivalent to the `image_source_transformation` field in FIDL
// [`fuchsia.hardware.display.engine/Layer`] struct.
::display::CoordinateTransformation transform;
// Indicates whether alpha blending will be performed and the type of alpha
// blending.
//
// Equivalent to the `alpha_mode` field in FIDL
// [`fuchsia.hardware.display.engine/Layer`] struct.
::display::AlphaMode alpha_mode;
// The color to use if the layer has no image.
//
// Equivalent to the `fallback_color` field in FIDL
// [`fuchsia.hardware.display.engine/Layer`] struct.
::display::Color fallback_color;
};
// Represents a layer to be composited on the canvas.
struct LayerForComposition {
InputImage image;
CompositionProperties properties;
};
// The buffer backing `canvas` must outlive the newly created instance.
explicit SoftwareCompositor(const OutputImage& canvas);
// Clears the canvas by filling a solid `color` of format `pixel_format` on
// the whole canvas.
//
// This produces the same result as Vulkan command `vkCmdClearColorImage`.
void ClearCanvas(const PixelData& color, PixelFormat pixel_format) const;
// Composites all the layers in `image_layers` onto the the canvas using
// composition properties specified in each image layer.
//
// Canvas pixels not covered by any image layer in `image_layers` will not
// be modified.
//
// Image layers are sorted by z-index in ascending order, i.e. image layer
// in the front of the `image_layers` list will be composited first and on the
// bottom, the layer in the end will be composited the last and on the top.
//
// For each ImageLayerForComposition, its `composition_properties` must
// fulfill the following constraints:
// - `alpha_mode` must be kDisable.
// - `transform` must be kIdentity.
// - the source frame `source_frame` must start at (0, 0) and have the same
// size as `input_image`.
// - the destination frame `canvas_frame` must fall completely within the
// canvas and have the same size as `input_image`.
// TODO(https://fxbug.dev/42075534): Supports more composition properties.
// TODO(https://fxbug.dev/42080652): Instead of providing a separate ClearCanvas()
// command, we should integrate background filling into
// CompositeImageLayers().
void CompositeLayers(std::span<const LayerForComposition> image_layers) const;
private:
// Composites the `input_image` onto the top of the canvas using given
// `composition_properties`.
//
// For composition without alpha composition nor transformation, this produces
// the same result as the Vulkan command `vkCmdBlitImage`.
//
// Currently only the following `composition_properties` is supported:
// - `alpha_mode` must be kDisable.
// - `transform` must be kIdentity.
// - the source frame `source_frame` must start at (0, 0) and have the same
// size as `input_image`.
// - the destination frame `canvas_frame` must fall completely within the
// canvas and have the same size as `input_image`.
// TODO(https://fxbug.dev/42075534): Supports more composition properties.
void CompositeImage(const InputImage& input_image,
const CompositionProperties& composition_properties) const;
// Composites the `fallback_color` onto the top of the canvas using given
// `composition_properties`.
//
// Currently only the following `composition_properties` is supported:
// - `alpha_mode` must be kDisable.
// - `transform` must be kIdentity.
// - the destination frame `canvas_frame` must fall completely within the
// canvas and have the same size as `input_image`.
// TODO(https://fxbug.dev/42075534): Supports more composition properties.
void CompositeFallbackColor(const CompositionProperties& composition_properties) const;
const OutputImage canvas_;
};
} // namespace software_compositor
#endif // SRC_GRAPHICS_DISPLAY_TESTING_SOFTWARE_COMPOSITOR_SOFTWARE_COMPOSITOR_H_