// 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;
    /// Maximum number of vsync messages sent by driver before acknowledge is needed
    /// To acknowledge, client needs to use AcknowledgeVsync API and provide the cookie
    /// that was provided as part of the receive vsync message
    uint32 vsync_acknowledge_rate;
};

// 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.
[Layout = "Simple"]
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(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(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, 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(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.
    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
    // expected rate of acknowledgement is communicated as part of display info
    //(i.e vsync_acknowledge_rate)
    // The cookie sent should match the cookie received via vsync message (OnVsync).
    // Ideally clients should send the cookie from the most recent vsync event
    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. The cookie is used to acknowledge the receipt of vsync
    // event using AcknowledgeVsync API.
    // Not all the vsyncs need to be acknowledged. Clients only need to acknowledge one vsync
    // out of vsync_acknowledge_rate received vsyncs. Vsync events are delivered to clients that
    // acknowledge 1 vsync per vsync_acknowledge_rate regardless of whether they have applied
    // a (new) configuration or not (via ApplyConfig).
    // If a client fails to acknowledge vsyncs for a period longer than vsync_acknowledge_rate,
    // 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, 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;
};
