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

/// Maximum number of fences supported by
/// [`fuchsia.hardware.display/Coordinator.ApplyConfig2`].
const APPLY_CONFIG_MAX_SIGNAL_FENCES uint64 = 32;

/// 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.
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.
    strict -> OnDisplaysChanged(struct {
        added vector<Info>:MAX;
        removed vector<fuchsia.hardware.display.types.DisplayId>:MAX;
    });

    /// Imports a Buffer-Collection backed image.
    ///
    /// `image_metadata` must be compatible with the arguments passed to
    /// [`fuchsia.hardware.display/Coordinator.SetBufferCollectionConstraints`]
    /// on the `buffer_collection_id`.
    ///
    /// Returns `ZX_ERR_NOT_SUPPORTED` if the display hardware doesn't support
    /// `image_config`.
    /// Returns `ZX_ERR_ALREADY_EXISTS` if `image_id` was used in a successful
    /// `ImportImage()` without a corresponding `ReleaseImage()`.
    strict ImportImage(struct {
        image_metadata fuchsia.hardware.display.types.ImageMetadata;
        buffer_id BufferId;
        image_id ImageId;
    }) -> () error zx.Status;


    /// Releases an imported image.
    ///
    /// `image_id` must be already imported by
    /// [`fuchsia.hardware.display/Coordinator.ImportImage`].
    ///
    /// The image must not be the capture target of an ongoing capture specified
    /// in [`fuchsia.hardware.display/Coordinator.StartCapture`].
    ///
    /// 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.
    //
    // TODO(https://fxbug.dev/42080380): The precondition on capture image
    // exists because capture images have different constraints on image reuse
    // compared with non-capture images. We should have a unified design on
    // image reuse for both capture and non-capture images.
    strict ReleaseImage(struct {
        image_id ImageId;
    });

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

    /// 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.
    strict ReleaseEvent(struct {
        id EventId;
    });

    // 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.
    strict CreateLayer() -> (struct {
        layer_id LayerId;
    }) error zx.Status;

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

    // 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.
    strict SetDisplayMode(struct {
        display_id fuchsia.hardware.display.types.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.
    strict SetDisplayColorConversion(struct {
        display_id fuchsia.hardware.display.types.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.
    strict SetDisplayLayers(struct {
        display_id fuchsia.hardware.display.types.DisplayId;
        layer_ids vector<LayerId>: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.
    strict SetLayerPrimaryConfig(struct {
        layer_id LayerId;
        image_metadata fuchsia.hardware.display.types.ImageMetadata;
    });

    // 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.
    strict SetLayerPrimaryPosition(struct {
        layer_id LayerId;
        transform fuchsia.hardware.display.types.Transform;
        src_frame fuchsia.hardware.display.types.Frame;
        dest_frame fuchsia.hardware.display.types.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].
    strict SetLayerPrimaryAlpha(struct {
        layer_id LayerId;
        mode fuchsia.hardware.display.types.AlphaMode;
        val float32;
    });

    // 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.
    strict SetLayerColorConfig(struct {
        layer_id LayerId;
        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
    // resets 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.
    strict SetLayerImage(struct {
        layer_id LayerId;
        image_id ImageId;
        wait_event_id EventId;
        signal_event_id EventId;
    });

    // 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 operations require revalidating the configuration. The
    // following operations do not require revalidation.
    // * SetLayerImage()
    //
    // If discard is true, the pending changes will be discarded after validation.
    strict CheckConfig(struct {
        discard bool;
    }) -> (struct {
        res fuchsia.hardware.display.types.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.
    strict ApplyConfig();

    // TODO(https://fxbug.dev/42152065): 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`.
    strict GetLatestAppliedConfigStamp() -> (struct {
        stamp fuchsia.hardware.display.types.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(https://fxbug.dev/42072277): 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(https://fxbug.dev/42072361): `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.
    strict 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.
    strict 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.
    strict 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.
    strict -> OnVsync(resource struct {
        display_id fuchsia.hardware.display.types.DisplayId;
        timestamp uint64;
        applied_config_stamp fuchsia.hardware.display.types.ConfigStamp;
        cookie uint64;
    });

    /// Sets the visibility behavior of the virtcon.
    ///
    /// This must only be called from the Virtcon client.
    strict 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.
    strict -> OnClientOwnershipChange(struct {
        has_ownership bool;
    });

    // Import a sysmem buffer collection token. `buffer_collection_id` must not
    // already be in use.
    strict ImportBufferCollection(resource struct {
        buffer_collection_id BufferCollectionId;
        buffer_collection_token client_end:fuchsia.sysmem.BufferCollectionToken;
    }) -> () error zx.Status;

    // Release an imported buffer collection.
    strict ReleaseBufferCollection(struct {
        buffer_collection_id BufferCollectionId;
    });

    // Takes an imported buffer collection and sets the constraints
    // on it so that it can be imported with a specific config.
    // TODO(https://fxbug.dev/42166207): Update this API to better support
    // optional fields.
    strict SetBufferCollectionConstraints(struct {
        buffer_collection_id BufferCollectionId;
        buffer_usage fuchsia.hardware.display.types.ImageBufferUsage;
    }) -> () error zx.Status;

    /// Returns true if Capture is supported on the platform.
    strict IsCaptureSupported() -> (struct {
        supported bool;
    }) 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
    strict StartCapture(struct {
        signal_event_id EventId;
        image_id ImageId;
    }) -> () 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.
    strict 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.
    strict SetDisplayPower(struct {
        display_id fuchsia.hardware.display.types.DisplayId;
        power_on bool;
    }) -> () error zx.Status;
};
