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

using fuchsia.sysmem;
using zx;

// Invalid id for displays, images, and events.
const uint64 INVALID_DISP_ID = 0;

enum VirtconMode : uint8 {
    INACTIVE = 0; // the virtcon is never visible.
    FALLBACK = 1; // the virtcon is visible if there is no primary client.
    FORCED = 2; // the virtcon is visible even if there is a primary client.
};

// A display mode configuration.
struct Mode {
    // Resolution in pixels.
    uint32 horizontal_resolution;
    uint32 vertical_resolution;
    // Vertical refresh rate in units of (Hz / 100).
    uint32 refresh_rate_e2;

    // Bitfield of flags defined below which further specify the mode.
    uint32 flags;
};

// === Mode flags ===

// Flag for interlaced display modes.
const int32 MODE_INTERLACED = 0x1;

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

    uint32 pixel_format;
};

const uint32 IDENTIFIER_MAX_LEN = 128;

// Info contains the information about a particular attached display.
struct Info {
    uint64 id;

    // Modes supported by the attached display. The first entry is the
    // preferred mode.
    vector<Mode>:MAX modes;
    // zx_pixel_format_t constants supported by the attached display. The
    // first entry is the preferred mode.
    vector<uint32>:MAX pixel_format;

    // A list of cursor configurations most likely to be accepted by the
    // driver. Maybe be empty if there is no hardware support for cursors.
    //
    // 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.
    vector<CursorInfo>:MAX cursor_configs;

    string:IDENTIFIER_MAX_LEN manufacturer_name;
    string:IDENTIFIER_MAX_LEN monitor_name;
    string:IDENTIFIER_MAX_LEN monitor_serial;

    /// Physical horizontal size in millimeters.
    /// If this value is not available, set to a best guess value and set the flag
    uint32 horizontal_size_mm;
    /// Physical vertical size in millimeters
    /// If this value is not available, set to a best guess value and set the flag
    uint32 vertical_size_mm;
    /// This flag is set if fallback horizontal and vertical sizes were used as opposed
    /// to actual values reported by the display.
    bool using_fallback_size;
};

// An ImageConfig accompanies image data and defines how to interpret that data.
struct ImageConfig {
    // The width and height of the image in pixels.
    uint32 width;
    uint32 height;

    // A zx_pixel_format_t constant that defines the pixel format of the data.
    uint32 pixel_format;

    // Type conveys information about what is providing the pixel data. If this
    // is not TYPE_SIMPLE, it is up to the driver and image producer to
    // agree on the meaning of the value through some mechanism outside the scope
    // of this API.
    uint32 type = TYPE_SIMPLE;
};
const uint32 TYPE_SIMPLE = 0;
// Intentionally left some gap between Simple and Capture types.
const uint32 TYPE_CAPTURE = 10; //The image is used for capture

// Rotations are applied counter-clockwise, and are applied before reflections.
enum Transform : uint8 {
    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;
};

enum AlphaMode : uint8 {
    // Alpha is disabled for the plane (default).
    DISABLE = 0;
    // Plane alpha is premultiplied.
    PREMULTIPLIED = 1;
    // Hardware should multiply the alpha and color channels when blending.
    HW_MULTIPLY = 2;
};

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

enum ClientCompositionOpcode : uint8 {
    // The client should convert the corresponding layer to a primary layer.
    CLIENT_USE_PRIMARY = 0;
    // The client should compose all layers with CLIENT_MERGE_BASE and CLIENT_MERGE_SRC
    // into a new, single primary layer at the CLIENT_MERGE_BASE layer's z-order. The
    // driver must accept a fullscreen layer with the default pixel format, but may
    // accept other layer parameters.
    //
    // CLIENT_MERGE_BASE will only be set on one layer per display.
    CLIENT_MERGE_BASE = 1;
    // See CLIENT_MERGE_BASE.
    CLIENT_MERGE_SRC = 2;
    // The client should provide a new image produced by scaling the source image
    // such that the dimensions of the new image's src_frame and dest_frame are
    // equal to the dimensions of the current image's dest_frame.
    CLIENT_FRAME_SCALE = 3;
    // The client should provide a new image produced by clipping the source image
    // to the region specified by src_frame.
    CLIENT_SRC_FRAME = 4;
    // The client should provide a new image produced by applying the desired
    // transformation, so that TRANSFORM_IDENTITY can be specified.
    CLIENT_TRANSFORM = 5;
    // The client should apply the color conversion itself.
    CLIENT_COLOR_CONVERSION = 6;
    // The client should apply the alpha itself.
    CLIENT_ALPHA = 7;
};

enum ConfigResult : uint32 {
    OK = 0;
    // The requested layer configuration is invalid.
    INVALID_CONFIG = 1;
    // The requested layer configuration cannot be supported by the hardware. See
    // CheckConfig struct for mode details.
    UNSUPPORTED_CONFIG = 2;
    // The number of requested displays cannot be supported.
    TOO_MANY_DISPLAYS = 3;
    // The hardware cannot support the requested modes for the displays. The client
    // should try a different set of displays or display modes.
    UNSUPPORTED_DISPLAY_MODES = 4;
};

struct ClientCompositionOp {
    uint64 display_id;
    uint64 layer_id;
    ClientCompositionOpcode opcode;
};

/// Provider for display controllers.
///
/// The driver supports two simultaneous clients - a primary client and a virtcon
/// client.
[ForDeprecatedCBindings]
protocol Provider {
    /// Open a virtcon client. `device` should be a handle to one endpoint of a
    /// channel that (on success) will become an open connection to a new
    /// instance of a display client device. A protocol request `controller`
    /// provides an interface to the Controller for the new device. Closing the
    /// connection to `device` will also close the `controller` interface. If
    /// the display device already has a virtcon controller then this method
    /// will return `ZX_ERR_ALREADY_BOUND`.
    // TODO(ZX-3889): Once llcpp is supported in Zircon, unify `device` and
    // `controller`.
    OpenVirtconController(zx.handle:CHANNEL device, request<Controller> controller) -> (zx.status s);

    /// Open a primary client. `device` should be a handle to one endpoint of a
    /// channel that (on success) will become an open connection to a new
    /// instance of a display client device. A protocol request `controller`
    /// provides an interface to the Controller for the new device. Closing the
    /// connection to `device` will also close the `controller` interface. If
    /// the display device already has a primary controller then this method
    /// will return `ZX_ERR_ALREADY_BOUND`.
    // TODO(ZX-3889): Once llcpp is supported in Zircon, unify `device` and
    // `controller`.
    OpenController(zx.handle:CHANNEL device, request<Controller> controller) -> (zx.status s);
};

/// Interface for accessing the display hardware.
///
/// A display configuration can be separated into two parts: the layer layout and
/// the layer contents. The layout includes all parts of a configuration other
/// than the image handles. The active configuration is composed of the most
/// recently applied layout and an active image from each layer - see
/// SetLayerImage for details on how the active image is defined. Note the
/// requirement that each layer has an active image. Whenever a new active
/// configuration is available, it is immediately given to the hardware. This
/// allows the layout and each layer's contents to advance independently when
/// possible.
///
/// Performing illegal actions on the interface will result in the interface
/// being closed.
protocol Controller {
    // Event fired when displays are added or removed. This event will be fired
    // when the callback is registered if there are any connected displays.
    //
    // A display change always invalidates the current configuration. When a
    // client receives this event, they must either apply a new configuration
    // or revalidate and reapply their current configuration.
    -> OnDisplaysChanged(vector<Info>:MAX added, vector<uint64>:MAX removed);

    // Imports a VMO backed image. If tiling is not TYPE_SIMPLE, it is up to
    // the driver and client to agree on its meaning through some mechanism
    // outside the scope of this API.
    //
    // DEPRECATED: This should not be used with buffer collections - ImportImage
    // should be used instead.
    ImportVmoImage(ImageConfig image_config, zx.handle:VMO vmo, int32 offset) -> (zx.status res, uint64 image_id);

    // Imports a Buffer-Collection backed image. If tiling is not TYPE_SIMPLE,
    // it is up to the driver and client to agree on its meaning through some
    // mechanism outside the scope of this API. The ImageConfig must be
    // compatible with that passed through SetBufferCollectionConstraints on
    // the collection id.
    ImportImage(ImageConfig image_config, uint64 collection_id, uint32 index)
        -> (zx.status res, uint64 image_id);

    // Releases an image.
    //
    // It is safe to call this at any time. When an image is released, it
    // is immediately removed from any pending or active configurations,
    // and any fences associated with the image are dropped. The resources
    // associated with the image will be released as soon as the image is
    // no longer in use.
    ReleaseImage(uint64 image_id);

    /// Imports an event into the driver and associates it with the given id.
    ///
    /// It is illegal for id to be equal to INVALID_DISP_ID, and it is undefined to
    /// import one event with two different ids or to import two different events
    /// with the same id (note that ids map well to koids).
    ///
    /// If a client is reusing events, they must clear the signal
    /// before referencing the id again.
    ImportEvent(zx.handle:EVENT event, uint64 id);

    /// Releases the event imported with the given id.
    ///
    /// If any images are currently using the given event, the event
    /// will still be waited up or signaled as appropriate before its
    /// resources are released. It is an error to reuse an ID while the
    /// active config has references to it.
    ReleaseEvent(uint64 id);

    // Creates a new layer.
    //
    // Layers are not associated with a particular display, but they can only be
    // shown on at most one display at any given time.  A layer is considered in
    // use from the time it is passed to SetDisplayLayers until a subsequent
    // configuration is applied which does not include the layer or until its
    // display is removed.
    CreateLayer() -> (zx.status res, uint64 layer_id);

    // Destroys the given layer.
    //
    // It is illegal to destroy a layer which does not exist or which is in use.
    DestroyLayer(uint64 layer_id);

    // Sets the display mode for the given display.
    //
    // It is illegal to pass a display mode which was not part of the display's Info.
    SetDisplayMode(uint64 display_id, Mode mode);

    // Set the color conversion applied to the display. The conversion is applied to
    // to each pixel according to the formula:
    //
    // (coefficients * (pixel + preoffsets)) + postoffsets
    //
    // where pixel is a column vector consisting of the pixel's 3 components.
    //
    // `coefficients` is passed in row-major order. If the first entry of an array is NaN, the
    // array is treated as the identity element for the relevant operation.
    // Hardware that support color correction generally accept a limited range of coefficient
    // values. Coefficients in the range of [-2, 2] inclusive will be accepted by most
    // hardware. The hardware driver will clamp values that are outside its accetable range.
    //
    // `preoffsets`, `postoffsets`: Clients are encourged to produce color correction values that
    // do not depend on pre and post offsets since some hardware do not have support for that.
    // For cases where pre and post offset values need to be used, the range should be limited to
    // (-1, 1) exclusive as confirmed by CheckConfig API. Values outside this range will be
    // rejected.
    //
    // Clients are encouraged to use the CheckConfig API to confirm support for correction
    // corection and to validate their color correction input values.
    //
    SetDisplayColorConversion(uint64 display_id,
                              array<float32>:3 preoffsets,
                              array<float32>:9 coefficients,
                              array<float32>:3 postoffsets);

    // Sets which layers are on a display. The list is in increasing z-order.
    //
    // It is illegal to use a layer on multiple displays concurrently. If a layer
    // needs to be moved between displays, it must be removed from the first display's
    // pending config before being added to the second display's pending config. It
    // is also illegal to pass an invalid layer id.
    SetDisplayLayers(uint64 display_id, vector<uint64>:MAX layer_ids);

    // Configures the layer as a primary layer with no image and the default
    // config (no src_frame cropping, the identity transform, positioned in the
    // top-left corner of the composed output, and no scaling).
    //
    // See the documentation on SetLayerImage for details on how this method
    // affects the layer's contents.
    //
    // It is illegal to pass an invalid layer id.
    SetLayerPrimaryConfig(uint64 layer_id, ImageConfig image_config);

    // Sets the layer transform, scaling, and positioning.
    //
    // `src_frame` must be non-empty and must fit entirely within the source
    // image. `dest_frame` must be non-empty and must fit entirely within the
    // composed output. CheckConfig will return INVALID_CONFIG if any of these
    // conditions is violated.
    //
    // Calling this on a non-primary layer or passing an invalid transform
    // is illegal.
    SetLayerPrimaryPosition(uint64 layer_id, Transform transform, Frame src_frame, Frame dest_frame);

    // Sets the alpha mode of the plane.
    //
    // If `mode` == DISABLED, the layer is opaque and `val` is ignored.
    //
    // If `mode` == PREMULTIPLIED or HW_MULTIPLY and `val` is NaN, the alpha
    // used when blending is determined by the per-pixel alpha channel.
    //
    // If `mode` == PREMULTIPLIED or HW_MULTIPLY and `val` is not NaN, the
    // alpha used when blending is the product of `val` and any per-pixel
    // alpha. Additionally, if `mode` == PREMULTIPLIED, then the hardware
    // premultiplies the color channel with `val` before blending.
    //
    // It is illegal to call this on a non-primary layer, to pass an
    // invalid mode, or to pass a value of `val` which is not NaN or
    // in the range [0, 1].
    SetLayerPrimaryAlpha(uint64 layer_id, AlphaMode mode, float32 val);

    // Configures the layer as a cursor layer with the given config. The
    // default position is (0, 0).
    //
    // See the documentation on SetLayerImage for details on how this method
    // affects the layer's contents.
    //
    // It is illegal to call this on an invalid layer.
    SetLayerCursorConfig(uint64 layer_id, ImageConfig image_config);

    // Updates the cursor position.
    //
    // The driver will clamp x to [-cursor_width + 1, display_width - 1] and
    // will clamp y to [-cursor_height + 1, display_height - 1].
    //
    // It is illegal to call this on a non-cursor layer.
    SetLayerCursorPosition(uint64 layer_id, int32 x, int32 y);

    // Configures the layer as a color layer with the given color. The
    // color_bytes vector is little-endian and must have length appropriate
    // for the pixel format.
    //
    // It is illegal to call this on an invalid layer or for the length of
    // color_bytes to mismatch the size of the supplied format.
    SetLayerColorConfig(uint64 layer_id, uint32 pixel_format, vector<uint8>:MAX color_bytes);

    // Sets the image for the layer.
    //
    // If wait_event_id corresponds to an imported event, the driver will
    // wait for ZX_EVENT_SIGNALED on the object before presenting the image.
    //
    // If signal_event_id is valid, then the driver will signal the event with
    // ZX_EVENT_SIGNALED when the image is no longer being presented.
    //
    // A layer's active image is the most recently applied image which either has
    // no wait event or whose wait event has been signaled. Whenever a new image
    // becomes active, any older images which never became active are dropped, and
    // their signal events will be fired as soon as their wait events are
    // signaled. The driver also does not have any concept like 'target vsync',
    // meaning that if multiple images become active within one vsync period, then
    // only the last image will actually be displayed.
    //
    // By default, the driver retains an active image until a new image becomes
    // active. However, setting a layer's ImageConfig with SetLayerPrimaryConfig
    // or SetLayerCursorConfig reset the layer's active and pending images, even
    // if the new ImageConfig matches the old ImageConfig.
    //
    // An image cannot be used for multiple layers simultaneously, nor can an
    // image be given back to the display controller while it is still in use.
    // An image is considered in use when it is part of a pending configuration
    // or from when its configuration is applied until its signal_event_id is
    // signaled.
    //
    // It is illegal to call this with an invalid layer or image id, to
    // call it on a color layer, or to call it with an image and layer whose
    // ImageConfigs do not match. It is illegal to apply a configuration
    // with an image layer that has no image (note that is is not illegal to
    // validate such a configuration). It is illegal to reuse a wait event which
    // another layer that has not been presented is waiting on.
    SetLayerImage(uint64 layer_id, uint64 image_id, uint64 wait_event_id, uint64 signal_event_id);

    // Attempts to validate the current configuration.
    //
    // When CheckConfig is called, the driver will validate the pending
    // configuration. If res is UNSUPPORTED_CONFIG, then ops will be
    // non-empty.
    //
    // Most SetX operation require re-validating the configuration. The exception
    // are SetLayerCursorPosition and SetLayerImage - these operations do not
    // modify the configuration in a way which requires revalidation.
    //
    // If discard is true, the pending changes will be discarded after validation.
    CheckConfig(bool discard) -> (ConfigResult res, vector<ClientCompositionOp>:MAX ops);

    // Applies any pending changes to the current configuration. This will
    // not apply pending changes to layers which are not on any display.
    //
    // If the pending configuration cannot be applied, this call will silently
    // fail, so the client should ensure its configuration is valid with
    // CheckConfig.
    ApplyConfig();

    // Sets whether or not vsync events will be given to this client. Defaults
    // to false.
    EnableVsync(bool enable);

    // This API is used by the client to acknowledge receipt of vsync messages.
    // The cookie sent should match the cookie received via vsync message (OnVsync).
    // A cookie can only be acknowledged once. Using invalid cookies, or previously
    // acknowledged cookies will not be accepted by the driver.
    AcknowledgeVsync(uint64 cookie);

    // Event sent for every vsync.
    //
    // display_id is the identifies the display on which the vsync occurred, and
    // timestamp indicates the time the vsync occurred. images is a (possibly
    // empty) vector of all images that were actively being displayed. cookie is a unique
    // number returned by the driver.
    // Cookie is used to acknowledge the receipt of vsync events using AcknowledgeVsync API.
    // When cookie has a value of zero, no acknowledgement is required by the client. A non-zero
    // valued cookie requires immediate acknowledgement by client. Failure to acknowledge
    // vsync events will result in driver suspending vsync event notification. All vsync
    // messages containing a non-zero cookie require acknowledgement regardless of whether
    // client has applied a (new) configuration or not (via ApplyConfig).
    // If a client fails to acknowledge vsync messages, the driver will store incoming
    // hardware-generated vsyncs in a circular buffer and send them
    // to the client once it resumes acknowledgement. Due to limited size of buffer, only the most
    // recently received vsyncs will be stored and older ones will be dropped.
    -> OnVsync(uint64 display_id, uint64 timestamp, vector<uint64>:MAX images, uint64 cookie);

    // Sets the visibility behavior of the virtcon. It is illegal to call this
    // from the primary client.
    SetVirtconMode(uint8 mode);

    // Event fired when the client gains or loses ownership of the displays.
    //
    // New clients should assume they do not have ownership of the display
    // until this event informs them otherwise.
    -> OnClientOwnershipChange(bool has_ownership);

    // Import a sysmem buffer collection token. `collection_id` must not
    // already be in use.
    ImportBufferCollection(uint64 collection_id,
                           fuchsia.sysmem.BufferCollectionToken collection_token)
        -> (zx.status res);

    // Release an imported buffer collection.
    ReleaseBufferCollection(uint64 collection_id);

    // Takes an imported buffer collection and sets the constraints
    // on it so that it can be imported with a specific config.
    SetBufferCollectionConstraints(uint64 collection_id, ImageConfig config) -> (zx.status res);

    // If the system only supports single-buffered mode with a single framebuffer, then this returns
    // that buffer and its stride. Otherwise it can return ZX_ERR_NOT_SUPPORTED.
    GetSingleBufferFramebuffer() -> (zx.status res, zx.handle:VMO? vmo, uint32 stride);

    /// Returns true if Capture is supported on the platform.
    IsCaptureSupported() -> (bool supported) error zx.status;

    /// Imports a buffer collection backed VMO into the display controller. The VMO
    /// will be used by display controller to capture the image being displayed.
    /// Returns ZX_OK along with an image_id.
    /// image_id must be used by the client to start capture and/or release
    /// resources allocated for capture.
    /// Returns ZX_ERR_NOT_SUPPORTED if controller does not support capture
    ImportImageForCapture(ImageConfig image_config, uint64 collection_id,
                          uint32 index) -> (uint64 image_id) error zx.status;

    /// Starts capture. Client must provide a valid signal_event_id and
    /// image_id. signal_event_id must have been imported into the driver
    /// using ImportEvent FIDL API. Image_id is the id from ImportImageForCapture.
    /// The client will get notified once capture is complete via signal_event_id.
    /// Returns ZX_ERR_NOT_SUPPORTED if controller does not support capture
    StartCapture(uint64 signal_event_id, uint64 image_id) -> () error zx.status;

    /// Releases resources allocated for capture.
    /// Returns ZX_ERR_NOT_SUPPORTED if controller does not support capture
    ReleaseCapture(uint64 image_id) -> () error zx.status;
};
