// 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.images2;
using fuchsia.sysmem;
using zx;

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

/// 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 Coordinator {
    // 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(struct {
        added vector<Info>:MAX;
        removed vector<uint64>:MAX;
    });

    // 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. If the provided |image_id| is already in use, this
    // function will return |ZX_ERR_ALREADY_EXISTS|.
    @selector("ImportImage2")
    ImportImage(struct {
        image_config ImageConfig;
        collection_id uint64;
        image_id uint64;
        index uint32;
    }) -> (struct {
        res zx.Status;
    });


    // 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(struct {
        image_id uint64;
    });

    /// 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(resource struct {
        event zx.Handle:EVENT;
        id uint64;
    });

    /// 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(struct {
        id uint64;
    });

    // 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() -> (struct {
        res zx.Status;
        layer_id uint64;
    });

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

    // 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(struct {
        display_id DisplayId;
        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 acceptable 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 and to
    // validate their color correction input values.
    //
    // This a stateful call. Once color conversion values have been succesfully applied via a call
    // to ApplyConfig() they will remain in place until changed and another ApplyConfig() call is
    // successful. If SetDisplayColorConversion() is called and then the config is discarded, then
    // the last successfully applied state is restored.
    SetDisplayColorConversion(struct {
        display_id DisplayId;
        preoffsets array<float32, 3>;
        coefficients array<float32, 9>;
        postoffsets array<float32, 3>;
    });

    // 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(struct {
        display_id DisplayId;
        layer_ids vector<uint64>:MAX;
    });

    // 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(struct {
        layer_id uint64;
        image_config ImageConfig;
    });

    // 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(struct {
        layer_id uint64;
        transform Transform;
        src_frame Frame;
        dest_frame 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(struct {
        layer_id uint64;
        mode AlphaMode;
        val float32;
    });

    // 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(struct {
        layer_id uint64;
        image_config ImageConfig;
    });

    // 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(struct {
        layer_id uint64;
        x int32;
        y int32;
    });

    // Configures the layer as a color layer with the given color in
    // `pixel_format`.
    //
    // `color_bytes` vector is little-endian and of the exact size of one pixel
    // in `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(struct {
        layer_id uint64;
        pixel_format fuchsia.images2.PixelFormat;
        color_bytes vector<uint8>:MAX;
    });

    // 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 coordinator 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(struct {
        layer_id uint64;
        image_id uint64;
        wait_event_id uint64;
        signal_event_id uint64;
    });

    // 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(struct {
        discard bool;
    }) -> (struct {
        res ConfigResult;
        ops vector<ClientCompositionOp>:MAX;
    });

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

    // TODO(fxbug.dev/72588): This is a temporary solution to support old
    // ApplyConfig() with new OnVsync() events. Remove this once the migration
    // is done.
    //
    /// Gets the stamp provided with the latest configuration the client
    /// submitted (by calling ApplyConfig()) and the display core driver
    /// accepted; the display configuration may not have been rendered yet
    /// because of pending image availability or pending layer changes.
    /// If no configuration was applied before, returns `INVALID_CONFIG_STAMP_VALUE`.
    GetLatestAppliedConfigStamp() -> (struct {
        stamp ConfigStamp;
    });

    /// Applies any pending changes to the current configuration. This will
    /// not apply pending changes to layers which are not on any display.
    ///
    /// For each event in `signal_fences`, once the pending configuration is
    /// applied to and contents are displayed on all the displays connected to
    /// the Coordinator, it will be signaled immediately.
    ///
    /// Arguments
    ///
    ///   `signal_fences`:
    ///     Stores all fence events that will be signaled once the configuration
    ///     is applied.
    ///
    /// Error handling
    ///
    ///     If the input is invalid, for example:
    ///         - `signal_fences` contains invalid events
    ///     or the pending configuration cannot be applied, this call will
    ///     silently fail, so the client should ensure its configuration is
    ///     valid with CheckConfig().
    //
    // TODO(fxbug.dev/121265): The current ApplyConfig2() API could cause delay
    // when there are multiple displays with different refresh rates and vsync
    // phases. In order to better support multiple displays, we should support
    // fences to be signaled when configuration is applied to a subset of
    // displays.
    //
    // TODO(fxbug.dev/121340): `signal_fences` should be renamed. The field
    // should be named to better indicate the timing and semantics when it is
    // signaled by the display driver.
    @transitional
    ApplyConfig2(resource struct {
        signal_fences vector<zx.Handle:EVENT>:APPLY_CONFIG_MAX_SIGNAL_FENCES;
    });

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

    // 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(struct {
        cookie uint64;
    });

    /// Event sent for every vsync.
    ///
    /// Arguments
    ///
    /// - `display_id` identifies the display on which the vsync occurred.
    ///
    /// - `timestamp` indicates the time the vsync occurred.
    ///
    /// - `applied_config_stamp` is the stamp of the latest configuration that
    ///   is *fully* applied to the display. For example, if a configuration
    ///   contains images that are still waiting to be ready, the configuration
    ///   will be only partially applied (without the pending image), and thus
    ///   the stamp of this configuration will not appear in Vsync messages
    ///   unless that image becomes ready and display coordinator reapplies
    ///   the configuration fully with the pending image.
    ///
    ///   The `value` of the stamp MUST NOT be INVALID_CONFIG_STAMP_VALUE.
    ///
    /// - `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.
    //
    // TODO(fxbug.dev/72588): Remove "@transitional" tag after implementing
    // OnVsync on all display clients.
    //
    -> OnVsync(resource struct {
        display_id DisplayId;
        timestamp uint64;
        applied_config_stamp ConfigStamp;
        cookie uint64;
    });

    /// Sets the visibility behavior of the virtcon.
    ///
    /// This must only be called from the Virtcon client.
    SetVirtconMode(struct {
        mode VirtconMode;
    });

    // 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(struct {
        has_ownership bool;
    });

    // Import a sysmem buffer collection token. `collection_id` must not
    // already be in use.
    ImportBufferCollection(resource struct {
        collection_id uint64;
        collection_token client_end:fuchsia.sysmem.BufferCollectionToken;
    }) -> (struct {
        res zx.Status;
    });

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

    // Takes an imported buffer collection and sets the constraints
    // on it so that it can be imported with a specific config.
    // Dimensions, pixel format, and image type are ignored when
    // setting constraints if set to zero.
    // TODO(fxbug.dev/85320): Update this API to better support
    // optional fields.
    SetBufferCollectionConstraints(struct {
        collection_id uint64;
        config ImageConfig;
    }) -> (struct {
        res zx.Status;
    });

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

    /// Imports a buffer collection backed VMO into the display coordinator. The VMO
    /// will be used by display coordinator 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 coordinator does not support capture
    ImportImageForCapture(struct {
        image_config ImageConfig;
        collection_id uint64;
        index uint32;
    }) -> (struct {
        image_id uint64;
    }) 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 coordinator does not support capture
    StartCapture(struct {
        signal_event_id uint64;
        image_id uint64;
    }) -> () error zx.Status;

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

    /// Set the minimum value of rgb channels. Valid range [0 255] inclusive. Returns
    /// ZX_ERR_NOT_SUPPORTED when the display hardware does not support this feature.
    /// This API is meant to address backlight bleeding that may occur on some hardware
    /// that have a specific type of panel and hardware assembly. The evolution of this
    /// API is highly hardware and product dependant and therefore as products evolve, this
    /// API may change or support for this API may become non-existent. Therefore, this
    /// API should be used with caution.
    ///
    /// Unlike other calls in this API, SetMiniumRgb is applied immediately, and does not
    /// wait for ApplyConfig(). It is, however, still stateful.
    SetMinimumRgb(struct {
        minimum_rgb uint8;
    }) -> () error zx.Status;

    /// Power off/on the display panel.
    ///
    /// This function takes effect immediately. Clients don't need to call
    /// `ApplyConfig()` to commit this command.
    ///
    /// Once a display is turned off, it will not deliver vsync events, which
    /// may include the vsync event for the most recently applied config.
    ///
    /// Staged display control commands (e.g. SetDisplayLayer) will not be
    /// affected. They are still applied to the display device when client calls
    /// `ApplyConfig()`, but the contents will be shown on display panel only
    /// after client powers on the display again.
    ///
    /// Newly added displays are turned on by default.
    ///
    /// Returns ZX_ERR_NOT_FOUND if `display_id` is invalid when Coordinator
    /// handles this method.
    /// Returns ZX_ERR_NOT_SUPPORTED if the display driver IC doesn't support
    /// turning on/off displays.
    SetDisplayPower(struct {
        display_id DisplayId;
        power_on bool;
    }) -> () error zx.Status;
};
