// 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 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_khz uint32;
    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;
    /// A bitmask of MODE_FLAG_* values
    flags uint32;
};

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;
};

/// The capabilities of a display panel.
type Panel = flexible resource union {
    /// The I2C bus to use to read this display's EDID.
    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;
};

/// 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;
};

/// 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 ELD (EDID Like Data, audio info in EDID) for one display.
    ///
    /// This method is called independently from the CheckConfiguration and
    /// ApplyConfiguration methods. The display_id may be unconfigured at the
    /// time this method is called. raw_eld is the ELD raw data formatted
    /// according to the HDA specification version 1.0a section 7.3.3.34.1.
    /// https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf
    flexible SetEld(struct {
        display_id uint64;
        raw_eld vector<uint8>:MAX;
    }) -> ();

    /// 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;
};
