// 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.
library fuchsia.hardware.display.engine;

using fuchsia.hardware.display.types;
using fuchsia.hardware.i2cimpl;
using fuchsia.images2;
using fuchsia.sysmem;
using fuchsia.sysmem2;
using zx;

type ColorConversion = strict bits : uint32 {
    /// If set, use the 0 vector for the color conversion preoffset
    PREOFFSET = 0x1;
    /// If set, use the identity matrix for the color conversion coefficients
    COEFFICIENTS = 0x2;
    /// If set, use the 0 vector for the color conversion postoffset
    POSTOFFSET = 0x4;
};

/// Constants for display_config's mode_flags field
type ModeFlag = strict bits : uint32 {
    VSYNC_POSITIVE = 0x1;
    HSYNC_POSITIVE = 0x2;
    INTERLACED = 0x4;
    ALTERNATING_VBLANK = 0x8;
    DOUBLE_CLOCKED = 0x10;
};

/// The video parameters which specify the display mode.
/// TODO(https://fxbug.dev/42085013): Replace this type with something more similar
/// to //src/graphics/display/lib/api-types-cpp/display-timing.h.
type DisplayMode = struct {
    pixel_clock_hz int64;
    h_addressable uint32;
    h_front_porch uint32;
    h_sync_pulse uint32;
    h_blanking uint32;
    v_addressable uint32;
    v_front_porch uint32;
    v_sync_pulse uint32;
    v_blanking uint32;
    flags ModeFlag;
};

type DisplayConfig = struct {
    /// the display id to which the configuration applies
    display_id uint64;

    mode DisplayMode;

    /// Bitmask of flags defined in the ColorConversion enum.
    cc_flags uint32;
    /// Color conversion is applied to each pixel according to the formula:
    ///
    /// (cc_coefficients * (pixel + cc_preoffsets)) + cc_postoffsets
    ///
    /// where pixel is a column vector consisting of the pixel's 3 components.
    cc_preoffsets array<float32, 3>;
    cc_coefficients array<array<float32, 3>, 3>;
    cc_postoffsets array<float32, 3>;

    layer vector<fuchsia.hardware.display.types.Layer>:MAX;
};

// An E-EDID can contain up to 256 data blocks, each of which contains 128
// bytes. So it can contain up to 256 * 128 = 32768 bytes of data.
const MAX_COUNT_EDID_BYTES uint32 = 32768;

/// The capabilities of a display panel.
type Panel = flexible resource union {
    /// Connection to the display's implementation of the E-DDC standard.
    ///
    /// E-DDC (Enhanced Display Data Channel) is a VESA standard that describes
    /// exposing display information over an I2C bus. The information is encoded
    /// using the VESA E-EDID or DisplayID standards.
    1: i2c client_end:fuchsia.hardware.i2cimpl.Device;

    /// Hard-coded display configuration.
    ///
    /// Can be used when the device does not implement EDID,
    /// or when the driver needs to override the EDID contents.
    2: mode DisplayMode;

    /// Display capabilities encoded using the E-EDID standard.
    ///
    /// E-EDID (Enhanced Extended Display Identification Data) is a VESA
    /// standard that describes display capabilities as a series of 128-byte
    /// data blocks.
    3: edid_bytes vector<uint8>:MAX_COUNT_EDID_BYTES;
};

const MAX_COUNT_DISPLAY_PIXEL_FORMATS uint32 = fuchsia.sysmem2.MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS;

/// A structure containing information a connected display.
type AddedDisplayArgs = resource struct {
    display_id uint64;

    panel Panel;

    /// A list of pixel formats supported by the display. The first entry is the
    /// preferred pixel format.
    pixel_formats vector<fuchsia.images2.PixelFormat>:MAX_COUNT_DISPLAY_PIXEL_FORMATS;
};

/// This protocol is `open` while under development.
/// TODO(b/316631158): We should make it `closed` once the API is stabilized.
@discoverable
@transport("Driver")
open protocol Engine {
    /// Import a sysmem buffer collection token.
    ///
    /// Returns ZX_ERR_ALREADY_EXISTS if `collection_id` is in use.
    flexible ImportBufferCollection(resource struct {
        buffer_collection_id BufferCollectionId;

        collection_token client_end:fuchsia.sysmem.BufferCollectionToken;
    }) -> () error zx.Status;

    /// Release an imported buffer collection.
    ///
    /// Returns ZX_ERR_NOT_FOUND if `collection_id` isn't successfully imported.
    flexible ReleaseBufferCollection(struct {
        collection_id uint64;
    }) -> () error zx.Status;

    /// Imports an image from a imported BufferCollection into the driver and
    /// returns its unique ID.
    ///
    /// Returns ZX_OK if the image is imported succesfully.
    /// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
    /// Returns ZX_ERR_SHOULD_WAIT if the buffer collection is not already
    /// allocated.
    flexible ImportImage(struct {
        // TODO(https://fxbug.dev/329163718): Some of the information in
        // `image_metadata` was negotiated by sysmem. The display coordinator or
        // engine drivers should read that information directly from sysmem.
        image_metadata fuchsia.hardware.display.types.ImageMetadata;
        buffer_id BufferId;
    }) -> (struct {
        image_id ImageId;
    }) error zx.Status;

    /// Import BufferCollection backed VMO pointed to by `index`.
    /// Importing the VMO usually involves pinning the VMO and updating display
    /// controller hardware registers with the physical address of the VMO to be
    /// used for capture.
    ///
    /// If display capture is not supported, returns ZX_ERR_NOT_SUPPORTED.
    ///
    /// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
    /// Returns ZX_ERR_SHOULD_WAIT if the buffer collection is not already
    /// allocated.
    flexible ImportImageForCapture(struct {
        buffer_id BufferId;
    }) -> (struct {
        capture_image_id ImageId;
    }) error zx.Status;

    /// Releases any driver state associated with the given image. The client
    /// is expected to not release any images passed to `apply_config`
    /// until a vsync occurs with a more recent image.
    flexible ReleaseImage(struct {
        image_id ImageId;
    }) -> ();

    /// Validates the given configuration.
    ///
    /// The configuration may not include all displays. Omitted displays should
    /// be treated as whichever of off or displaying a blank screen results in
    /// a more permissive validation.
    ///
    /// All displays in a configuration will have at least one layer. The
    /// layers will be arranged in increasing z-order, and their z_index fields
    /// will be set consecutively.
    ///
    /// Whether or not the driver can accept the configuration cannot depend on
    /// the particular image handles, as it must always be possible to present
    /// a new image in place of another image with a matching configuration.
    ///
    /// `config_check_result` should be set to a CONFIG_DISPLAY_* error if the
    /// combination of display modes is not supported.
    ///
    /// `client_composition_opcodes` are per-layer client operations
    /// to make the layer configuration supported by the display hardware. If
    /// the `config_check_result` is not `CONFIG_CHECK_RESULT_OK`, the values of
    /// `client_composition_opcodes` are undefined and should be ignored by the
    /// client.
    ///
    /// `client_composition_opcodes` is an array with one element for each
    /// layer in
    /// each display_config element. The elements map to layers following a
    /// DFS traversal of a tree where the first-level children are the
    /// `display_config` elements, and the second-level children are each
    /// `DisplayConfig`'s layers.
    ///
    /// The element ordering matches flattening the array obtained by mapping
    /// each display_config element to its `DisplayConfig.layers` value:
    ///   [ display 0 layer 0, display 0 layer 1, ...,
    ///     display 1 layer 0, display 1 layer 1, ...,
    ///     display (N-1) layer 0, ..., display (N-1) layer (M-1) ].
    flexible CheckConfiguration(struct {
        display_config vector<DisplayConfig>:MAX;
    }) -> (struct {
        config_check_result fuchsia.hardware.display.types.ConfigResult;
        client_composition_opcodes
                vector<fuchsia.hardware.display.types.ClientCompositionOpcode>:MAX;
    });

    /// Applies the configuration.
    ///
    /// All configurations passed to this function must be derived from
    /// configurations which have been successfully validated, with the only
    /// differences either being omitted layers or different image handles. To
    /// account for any layers which are not present, the driver must use the
    /// z_index values of the present layers to configure them as if the whole
    /// configuration was present.
    ///
    /// Unlike with `CheckConfiguration`, displays included in the configuration
    /// are not guaranteed to include any layers. Both omitted displays and
    /// displays with no layers can either be turned off or set to display a
    /// blank screen, but for displays with no layers there is a strong
    /// preference to display a blank screen instead of turning them off. In
    /// either case, the driver must drop all references to old images and
    /// invoke the vsync callback after doing so.
    flexible ApplyConfiguration(struct {
        display_config vector<DisplayConfig>:MAX;

        /// Identifies the configuration to be applied. Must be a valid value.
        /// Must be strictly increasing across calls.
        config_stamp fuchsia.hardware.display.types.ConfigStamp;
    }) -> ();

    /// Set sysmem buffer collection contraints needed to ensure an image can be
    /// imported with `config` on the imported BufferCollecition with
    /// `collection_id`.
    ///
    /// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
    flexible SetBufferCollectionConstraints(struct {
        usage fuchsia.hardware.display.types.ImageBufferUsage;
        buffer_collection_id BufferCollectionId;
    }) -> () error zx.Status;

    /// Power off/on the display panel. Newly added displays are turned on by
    /// default.
    ///
    /// Displays that are turned off will not deliver VSync events.
    /// This may include the vsync event for the most recently applied
    /// config.
    flexible SetDisplayPower(struct {
        display_id uint64;
        power_on bool;
    }) -> () error zx.Status;

    /// Set the minimum value of RGB channels.
    ///
    /// Returns ZX_ERR_NOT_SUPPORTED if RGB clamping is not supported.
    ///
    /// This method is provisional and is only for some display engines.
    /// Most display drivers willreturn ZX_ERR_NOT_SUPPORTED.
    //
    // TODO(https://fxbug.dev/328903017): This is a provisional method meant
    // to address a hardware issue where RGB channels need to get clamped in
    // order to reduce backlight bleeding. Revise this method when stabilizing
    // the Engine protocol API.
    flexible SetMinimumRgb(struct {
        /// Must be >= 0 and <= 255.
        minimum_rgb uint8;
    }) -> () error zx.Status;

    /// Returns true iff the display Engine supports capturing the pixels
    /// on the display device.
    flexible IsCaptureSupported() -> (struct {
        is_supported bool;
    });

    /// Starts capture into the resource mapped by `capture_image_id `(non-blocking)
    /// Only one active capture is allowed at a time.
    /// A valid image must be displayed during capture. Otherwise unexpected
    /// hardware behavior might occur.
    ///
    /// Drivers should not leave display hardware in this unexpected state.
    /// Drivers are expected to stop and/or abort capture if no valid image is
    /// being displayed.
    ///
    /// Returns ZX_ERR_NOT_SUPPORTED if display capture feature is not
    /// supported.
    flexible StartCapture(struct {
        capture_image_id ImageId;
    }) -> () error zx.Status;

    /// Releases resources allocated by `capture_image_id`.
    /// Releasing resources from an active capture is not allowed and will cause
    /// unexpected behavior.
    ///
    /// Returns ZX_ERR_NOT_SUPPORTED if display capture feature is not
    /// supported.
    flexible ReleaseCapture(struct {
        capture_image_id ImageId;
    }) -> () error zx.Status;

    /// Returns true if display capture is supported and the previous capture is
    /// completed. False otherwise.
    flexible IsCaptureCompleted() -> (struct {
        is_capture_completed bool;
    });

    /// Triggered when a previous display capture triggered by [`StartCapture`]
    /// is completed.
    ///
    /// The display Engine emits an [`OnCaptureComplete`] event only if
    /// [`IsCaptureSupported`] returns `true`.
    flexible -> OnCaptureComplete();

    /// Emitted when a display is connected.
    ///
    /// Display Engine drivers must emit this event for all displays connected
    /// prior to initialization.
    flexible -> OnDisplayAdded(resource struct {
        added_display AddedDisplayArgs;
    });

    /// Emitted when a display is removed.
    ///
    /// `display_id` must be a valid display ID that occurred in a previous
    /// `OnDisplayAdded()` event.
    ///
    /// Display Engine drivers must have finished accessing all images which
    /// were on the removed display before emitting the `OnDisplayRemoved()`
    /// event.
    flexible -> OnDisplayRemoved(struct {
        display_id uint64;
    });

    /// Events which are invoked when display vsync occurs.
    ///
    /// Arguments
    /// - `timestamp`
    ///      The ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
    /// - `config_stamp`
    ///      The config stamp of the latest configuration that is currently
    ///      fully applied to all the layers of the display with `display_id`.
    ///        If none of the configurations are currently fully applied to
    ///      this display, a null value will be passed to the driver.
    ///        Note that an `ApplyConfiguration()` call may contain multiple
    ///      configurations with a certain `config_stamp`; Only the application
    ///      status of the configuration with ID `display_id` is related.
    ///
    /// The driver must emit this event as close as possible to the start of
    /// every display's VSync period, even if the display has no images
    /// displayed.
    flexible -> OnDisplayVsync(struct {
        display_id uint64;
        timestamp zx.Time;
        config_stamp box<fuchsia.hardware.display.types.ConfigStamp>;
    });

    // A noop method with a response from the server that should be used
    // by clients who optionally use this library to determine availability.
    flexible IsAvailable() -> ();
};

service Service {
    engine client_end:Engine;
};
