// Copyright 2018 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.controller;

using fuchsia.hardware.i2cimpl;
using zx;

type ImageTilingType = strict enum : uint32 {
    /// The image is linear and VMO backed.
    LINEAR = 0;

    // Intentionally left some gap between LINEAR and CAPTURE.

    /// The image is used for capture
    CAPTURE = 10;
};

/// A structure containing information about an image.
type Image = struct {
    /// The width and height of the image in pixels.
    width uint32;
    height uint32;

    /// The type conveys information about what is providing the pixel data. If this is not
    /// IMAGE_TILING_TYPE_LINEAR, it is up to the driver and buffer producer to agree on the meaning
    /// of the value through some mechanism outside the scope of this API.
    tiling_type uint32;

    /// A driver-defined handle to the image. Each handle must be unique.
    handle uint64;
};

/// The intended usage for a sysmem BufferCollection holding image buffers.
///
/// Each buffer in the collection will store a single image, which is intended
/// to be used as described below.
type ImageBufferUsage = struct {
    /// Specifies how individual pixels are arranged in an image buffer.
    ///
    /// See [`fuchsia.hardware.display.types/ImageTilingTypeIdValue`].
    tiling_type uint32;
};

/// Describes how an image is stored in a buffer of a sysmem BufferCollection.
///
/// The buffer is dedicated to storing a single image. The properties below are
/// needed for decoding the image from the buffer.
// TODO(https://fxbug.dev/329163718): sysmem already has some of the information
// here. Prune this structure, replacing members with querying properties on the
// associated sysmem BufferCollection.
type ImageMetadata = struct {
    /// The width and height of the image in pixels.
    width uint32;
    height uint32;

    /// Specifies how individual pixels are arranged in an image buffer.
    ///
    /// See [`fuchsia.hardware.display.types/ImageTilingTypeIdValue`].
    tiling_type uint32;
};

const INVALID_DISPLAY_ID uint64 = 0;
const INVALID_ID uint64 = 0;

/// Indicates that a ConfigStamp is invalid.
const INVALID_CONFIG_STAMP_VALUE uint64 = 0;

/// A unique stamp representing a unique set of display configuration.
/// The value is always strictly increasing in chronological order.
type ConfigStamp = struct {
    /// For valid configurations, the value should not be equal to
    /// `INVALID_CONFIG_STAMP_VALUE`.
    value uint64;
};

/// The capabilities of a display panel.
type Panel = strict resource union {
    /// The i2c bus to use to read this display's EDID.
    1: i2c client_end:fuchsia.hardware.i2cimpl.I2cImpl;

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

type PanelCapabilitiesSource = strict enum {
    /// The panel uses Extended Display Identification Data (EDID) over the
    /// I2C bus to communicate its capabilities.
    EDID_I2C = 1;

    /// The panel provides a DisplayMode struct to express its capabilities.
    DISPLAY_MODE = 2;
};

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

    /// If `panel_capabilities_source` is `EDID_I2C`, `panel.i2c` must be a
    /// valid I2c client. The rest fields in `panel` are ignored.
    ///
    /// If `panel_capabilities_source` is `DISPLAY_MODE`, `panel.display_mode`
    /// must be valid. The rest fields in `panel` are ignored.
    panel_capabilities_source PanelCapabilitiesSource;
    panel Panel;

    /// A list of pixel formats supported by the display. The first entry is the
    /// preferred pixel format.
    pixel_format vector<FuchsiaImages2PixelFormatEnumValue>:MAX;
};

/// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
/// during these callbacks.
@transport("Banjo")
@banjo_layout("ddk-interface")
closed protocol DisplayControllerInterface {
    /// Emitted when a display is connected.
    ///
    /// Display Engine drivers must emit this event for all displays connected
    /// prior to initialization.
    strict 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.
    strict 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 call this function as close as possible to the start of
    /// every display's VSync period, even if the display has no images
    /// displayed.
    strict OnDisplayVsync(struct {
        display_id uint64;
        timestamp zx.Time;
        config_stamp box<ConfigStamp>;
    }) -> ();

    /// Called when the previous display capture triggered by
    /// [`DisplayControllerImpl.StartCapture`] is completed.
    ///
    /// Each `OnCaptureComplete` call must be paired with a previous successful
    /// call to [`DisplayControllerImpl.StartCapture`].
    strict OnCaptureComplete() -> ();
};

type Alpha = strict enum : uint8 {
    DISABLE = 0;
    PREMULTIPLIED = 1;
    HW_MULTIPLY = 2;
};

/// Rotations are applied counter-clockwise, and are applied before reflections.
type FrameTransform = strict enum : uint32 {
    IDENTITY = 0;
    REFLECT_X = 1;
    REFLECT_Y = 2;
    ROT_90 = 3;
    ROT_180 = 4;
    ROT_270 = 5;
    ROT_90_REFLECT_X = 6;
    ROT_90_REFLECT_Y = 7;
};

type Frame = struct {
    /// (|x_pos|, |y_pos|) specifies the position of the upper-left corner
    /// of the frame.
    x_pos uint32;
    y_pos uint32;
    width uint32;
    height uint32;
};

type PrimaryLayer = struct {
    /// The result of a successful ImportImage() call.
    image_handle uint64;

    /// Must match the ImportImage() argument for `image_handle`.
    image_metadata ImageMetadata;

    /// An ALPHA_* constant.
    ///
    /// If |alpha_mode| == `ALPHA_DISABLED`, the layer is opaque and alpha_layer_val is ignored.
    ///
    /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is NaN, the alpha
    /// used when blending is determined by the per-pixel alpha channel.
    ///
    /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is not NaN, the
    /// alpha used when blending is the product of alpha_layer_val and any per-pixel alpha.
    /// Additionally, if alpha_mode == PREMULTIPLIED, then the hardware must premultiply the color
    /// channel with alpha_layer_val before blending.
    ///
    /// If alpha_layer_val is not NaN, it will be in the range [0, 1].
    alpha_mode Alpha;
    alpha_layer_val float32;

    transform_mode FrameTransform;

    /// The source frame, where (0,0) is the top-left corner of the image. The
    /// client guarantees that src_frame lies entirely within the image.
    src_frame Frame;

    /// The destination frame, where (0,0) is the top-left corner of the
    /// composed output. The client guarantees that dest_frame lies entirely
    /// within the composed output.
    dest_frame Frame;
};

type ColorLayer = struct {
    /// The format of `color` bytes.
    format FuchsiaImages2PixelFormatEnumValue;

    /// The color to use for the layer. The color is little-endian, and is
    /// guaranteed to be of the exact size of one pixel in `format`.
    color vector<uint8>:MAX;
};

/// Types of layers.
type LayerType = strict enum : uint32 {
    PRIMARY = 0;
    COLOR = 1;
};

type LayerConfig = strict union {
    1: primary PrimaryLayer;
    2: color ColorLayer;
};

type Layer = struct {
    type LayerType;
    /// z_index of the layer. See |check_configuration| and |apply_configuration|.
    z_index uint32;
    cfg LayerConfig;
};

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

/// The video parameters which specify the display mode.
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;
    /// A bitmask of MODE_FLAG_* values
    flags uint32;
};

type ColorConversion = strict enum : 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;
};

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<Layer>:MAX;
};

type ConfigCheckResult = strict enum : uint32 {
    /// The display mode configuration is valid. Note that this is distinct from
    /// whether or not the layer configuration is valid.
    OK = 0;
    /// Error indicating that the hardware cannot simultaneously support the
    /// requested number of displays.
    TOO_MANY = 1;
    /// Error indicating that the hardware cannot simultaneously support the given
    /// set of display modes. To support a mode, the display must be able to display
    /// a single layer with width and height equal to the requested mode and the
    /// preferred pixel format.
    UNSUPPORTED_MODES = 2;
};

/// Contains client operations needed on a Layer to make it supported by
/// the display device. There may be multiple operations to be applied on a
/// single Layer.
///
/// Individual bit positions map to the values of the FIDL enum
/// [`fuchsia.hardware.display.types/ClientCompositionOpcode`].
type ClientCompositionOpcode = strict bits : uint32 {
    /// The client should convert the corresponding layer to a primary layer.
    USE_PRIMARY = 0x1;
    /// The client should compose all layers with MERGE_BASE and MERGE_SRC into a new,
    /// single primary layer at the MERGE_BASE layer's z-order. The driver must accept
    /// a fullscreen layer with the default pixel format, but may accept other layer
    /// parameters.
    ///
    /// MERGE_BASE should only be set on one layer per display. If it is set on multiple
    /// layers, the client will arbitrarily pick one and change the rest to MERGE_SRC.
    MERGE_BASE = 0x2;
    MERGE_SRC = 0x4;
    /// The client should pre-scale the image so that src_frame's dimensions are equal
    /// to dest_frame's dimensions.
    FRAME_SCALE = 0x8;
    /// The client should pre-clip the image so that src_frame's dimensions are equal to
    /// the image's dimensions.
    SRC_FRAME = 0x10;
    /// The client should pre-apply the transformation so TRANSFORM_IDENTITY can be used.
    TRANSFORM = 0x20;
    /// The client should apply the color conversion.
    COLOR_CONVERSION = 0x40;
    /// The client should apply the alpha transformation itself.
    ALPHA = 0x80;
};

/// The client guarantees that check_configuration and apply_configuration are always
/// made from a single thread. The client makes no other threading guarantees.
@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol DisplayControllerImpl {
    /// The function will only be called once, and it will be called before any other
    /// functions are called.
    strict SetDisplayControllerInterface(resource struct {
        intf client_end:DisplayControllerInterface;
    }) -> ();

    /// Resets the DisplayControllerInterface client (if set) and will not call
    /// DisplayControllerInterface callback methods anymore.
    strict ResetDisplayControllerInterface() -> ();

    /// Import a sysmem buffer collection token.
    ///
    /// Returns ZX_ERR_ALREADY_EXISTS if `collection_id` is in use.
    strict ImportBufferCollection(resource struct {
        collection_id uint64;
        // TODO(https://fxbug.dev/42171012): This is a client end channel of FIDL protocol
        // fuchsia.sysmem.BufferCollectionToken. The raw channel needs to be
        // replaced with FIDL client end once banjo to FIDL migration finishes.
        collection_token zx.Handle:CHANNEL;
    }) -> (struct {
        s zx.Status;
    });

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

    /// Imports an image from a imported BufferCollection into the driver.
    ///
    /// Returns ZX_OK and the imported image's handle, 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.
    strict 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 ImageMetadata;
        collection_id uint64;
        index uint32;
    }) -> (struct {
        s zx.Status;
        image_handle uint64;
    });

    /// 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. Returns out_capture_handle which maps to the allocated
    /// resource.
    ///
    /// If display capture is not supported, returns ZX_ERR_NOT_SUPPORTED and
    /// the value of `capture_handle` will be undefined.
    ///
    /// 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.
    strict ImportImageForCapture(struct {
        collection_id uint64;
        index uint32;
    }) -> (struct {
        s zx.Status;
        capture_handle uint64;
    });

    /// Releases any driver state associated with the given image. The client guarantees that
    /// any images passed to apply_config will not be released until a vsync occurs with a
    /// more recent image.
    strict ReleaseImage(struct {
        image_handle uint64;
    }) -> ();

    /// 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) ].
    ///
    /// The driver must not retain references to the configuration after this function returns.
    strict CheckConfiguration(struct {
        display_config vector<DisplayConfig>:MAX;
    }) -> (struct {
        config_check_result ConfigCheckResult;
        client_composition_opcodes vector<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 check_configuration, 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.
    ///
    /// The driver must not retain references to the configuration after this function returns.
    strict 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 ConfigStamp;
    }) -> ();

    /// Set ELD 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
    /// The driver must not retain references to the ELD after this function returns.
    strict SetEld(struct {
        display_id uint64;
        raw_eld vector<uint8>:MAX;
    }) -> ();

    /// Conveys the display hardware's limitations on image buffers to sysmem.
    ///
    /// The sysmem BufferCollection imported with `collection_id` will receive
    /// constraints representing the display hardware's limitations for image
    /// buffers that will be used according to `usage`. Once this succeeds,
    /// calls to ImportImage() or ImportImageForCapture() that are consistent
    /// with `usage` will not fail.
    ///
    /// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
    strict SetBufferCollectionConstraints(struct {
        usage ImageBufferUsage;
        collection_id uint64;
    }) -> (struct {
        s 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.
    strict SetDisplayPower(struct {
        display_id uint64;
        power_on bool;
    }) -> (struct {
        s zx.Status;
    });

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

    /// Starts capture into the resource mapped by capture_handle (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.
    strict StartCapture(struct {
        capture_handle uint64;
    }) -> (struct {
        s zx.Status;
    });

    /// Releases resources allocated by capture_handle.
    /// 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.
    strict ReleaseCapture(struct {
        capture_handle uint64;
    }) -> (struct {
        s zx.Status;
    });

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

    /// Set the minimum value of RGB channels.
    ///
    /// Returns ZX_ERR_NOT_SUPPORTED if RGB clamping is 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 API when migrating this
    // protocol to FIDL.
    strict SetMinimumRgb(struct {
        /// Must be >= 0 and <= 255.
        minimum_rgb uint8;
    }) -> (struct {
        s zx.Status;
    });
};
