// 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.audiotypes;
using zx;

alias ZxPixelFormat = uint32;

alias ZxUnownedHandle = uint32;

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

    // Intentionally left some gap between SIMPLE 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 pixel format of the image.
    pixel_format ZxPixelFormat;

    /// The type conveys information about what is providing the pixel data. If this is not
    /// IMAGE_TYPE_SIMPLE, 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.
    type uint32;

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

const INVALID_DISPLAY_ID uint32 = 0;
const INVALID_ID uint32 = 0;
const INVALID_CONFIG_STAMP_VALUE uint64 = 0;

/// A unique stamp representing a unique set of display configuration
/// in ApplyConfiguration().
type ConfigStamp = struct {
    /// For valid configurations, the value should not be equal to
    /// `INVALID_CONFIG_STAMP_VALUE`.
    value uint64;
};

/// A fallback structure to convey display information without an edid.
type DisplayParams = struct {
    width uint32;
    height uint32;
    refresh_rate_e2 uint32;
};

/// Info about valid cursor configurations.
type CursorInfo = struct {
    /// The width and height of the cursor configuration, in pixels.
    width uint32;
    height uint32;
    format ZxPixelFormat;
};

type Panel = strict union {
    /// The bus_id to use to read this display's edid from the device's i2c protocol.
    1: i2c_bus_id uint32;
    /// The display's parameters if an edid is not present.
    2: params DisplayParams;
};

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

    /// A flag indicating whether or not the display has a valid edid.
    ///
    /// If true, the device should expose an ZX_PROTOCOL_I2C_IMPL device through get_protocol, in
    /// addition to the ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL protocol. Note that the i2c device
    /// will be called from the on_displays_changed callback, so care should be taken to avoid
    /// deadlocks or double-locking.
    ///
    /// If no edid is present, then the meaning of display_config's mode structure is
    /// undefined, and drivers should ignore it in check_configuration and apply_configuration.
    edid_present bool;
    panel Panel;

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

    /// A list of cursor configurations most likely to be accepted by the driver. Can
    /// be null if cursor_count is 0.
    ///
    /// The driver may reject some of these configurations in some circumstances, and
    /// it may accept other configurations, but at least one of these configurations
    /// should be valid at most times.
    cursor_info vector<CursorInfo>:MAX;
};

/// Out parameters will be populated before on_displays_changed returns.
type AddedDisplayInfo = struct {
    is_hdmi_out bool;
    is_standard_srgb_out bool;

    audio_format_count uint32;

    /// All strings are null-terminated. |manufacturer_id| is guaranteed to have
    /// length 3, all other strings may be empty.
    manufacturer_id string:4;
    /// non-null
    manufacturer_name string:MAX;
    /// null-terminated
    monitor_name string:14;
    /// null-terminated
    monitor_serial string:14;

    // physical horizontal size in millimeters
    horizontal_size_mm uint32;
    // physical vertical size in millimeters
    vertical_size_mm uint32;
};

/// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
/// during these callbacks.
@transport("Banjo")
@banjo_layout("ddk-interface")
protocol DisplayControllerInterface {
    /// Callbacks which are invoked when displays are added or removed. |added_display_list| and
    /// |removed_display_list| point to arrays of the display ids which were added and removed. If
    /// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
    ///
    /// The driver must be done accessing any images which were on the removed displays.
    ///
    /// The driver should call this function when the callback is registered if any displays
    /// are present.
    OnDisplaysChanged(struct {
        added_display vector<AddedDisplayArgs>:MAX;
        removed_display vector<uint64>:MAX;
    }) -> (struct {
        display_info vector<AddedDisplayInfo>:MAX;
    });

    /// 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 for all vsync events, even if the
    /// display has no images displayed.
    OnDisplayVsync(struct {
        display_id uint64;
        timestamp zx.time;
        config_stamp ConfigStamp:optional;
    }) -> ();

    GetAudioFormat(struct {
        display_id uint64;
        fmt_idx uint32;
    }) -> (struct {
        s zx.status;
        fmt fuchsia.hardware.audiotypes.AudioTypesAudioStreamFormatRange;
    });
};

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 {
    image Image;

    /// 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 CursorLayer = struct {
    image Image;

    /// The position of the top-left corner of the cursor's image. When being
    /// applied to a display, the cursor is guaranteed to have at least one
    /// pixel of overlap with the display.
    x_pos int32;
    y_pos int32;
};

type ColorLayer = struct {
    format ZxPixelFormat;
    /// The color to use for the layer. The color is little-endian, and is
    /// guaranteed to be of the appropriate size.
    color vector<uint8>:MAX;
};

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

type LayerConfig = strict union {
    1: primary PrimaryLayer;
    2: cursor CursorLayer;
    3: 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_10khz 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 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 COLOR_CONVERSION_* flags
    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>;

    @mutable
    @out_of_line_contents
    layer vector<Layer>:MAX;

    /// Flag to indicate valid gamma table
    gamma_table_present bool;
    /// Flag to indicate whether display driver should re-apply gamma correction table to hardware
    apply_gamma_table bool;
    /// Gamma Table (Red, Green and Blue)
    @mutable
    gamma_red vector<float32>:MAX;
    @mutable
    gamma_green vector<float32>:MAX;
    @mutable
    gamma_blue vector<float32>:MAX;
};

type ConfigDisplay = 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;
};

type Client = strict enum : 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 cannot control the display gamma, and must accept
    /// the uncalibrated output. Clients are expected to produce linear
    /// buffers, and as such they cannot perform software gamma
    /// correction.
    GAMMA = 0x100;
};

/// 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")
protocol DisplayControllerImpl {
    /// The function will only be called once, and it will be called before any other
    /// functions are called.
    SetDisplayControllerInterface(resource struct {
        intf client_end:DisplayControllerInterface;
    }) -> ();

    /// Imports an image from a buffer collection into the driver. The driver should set
    /// image->handle.
    ImportImage(struct {
        @in_out
        image Image;
        collection ZxUnownedHandle;
        index uint32;
    }) -> (struct {
        s zx.status;
    });

    /// 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.
    ReleaseImage(struct {
        @in_out
        image Image;
    }) -> ();

    /// 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. It also cannot depend on the
    /// cursor position, as that can be updated without another call to check_configuration.
    ///
    /// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
    /// display modes is not supported.
    ///
    /// layer_cfg_result points to an array of arrays. The primary length is display_count, the
    /// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
    /// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
    /// flag in the corresponding layer_cfg_result entry.
    ///
    /// The driver must not retain references to the configuration after this function returns.
    /// TODO: Fix me...
    CheckConfiguration(struct {
        @inner_pointer
        display_config vector<DisplayConfig>:MAX;
    }) -> (struct {
        display_cfg_result uint32;
        @callee_allocated
        layer_cfg_result vector<uint32>:MAX;
    });

    /// Applies the configuration.
    ///
    /// All configurations passed to this function will 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 turn them off.
    /// In either case, the driver must drop all references to old images and invoke the vsync
    /// callback after doing so.
    ///
    /// `config_stamp` is a non-zero unique stamp to identify each configuration.
    /// Callers must guarantee that `config_stamp` is unique for each `ApplyConfiguration()`
    /// call.
    ///
    /// The driver must not retain references to the configuration after this function returns.
    ApplyConfiguration(struct {
        @inner_pointer
        display_config vector<DisplayConfig>:MAX;
        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.
    SetEld(struct {
        display_id uint64;
        raw_eld vector<uint8>:MAX;
    }) -> ();

    // Connects the handle to the sysmem service.
    GetSysmemConnection(resource struct {
        sysmem_handle zx.handle:CHANNEL;
    }) -> (struct {
        s zx.status;
    });

    // Set sysmem buffer collection contraints needed to ensure an image can be imported with config
    // |config| on the fuchsia.sysmem.BufferCollection handle |collection|.
    SetBufferCollectionConstraints(struct {
        config Image;
        collection ZxUnownedHandle;
    }) -> (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.
    SetDisplayPower(struct {
        display_id uint64;
        power_on bool;
    }) -> (struct {
        s zx.status;
    });
};
