blob: 1b03cef903451e91c6865a1280f9eafb3f8ea1cc [file] [log] [blame]
// Copyright 2023 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.engine;
using fuchsia.hardware.display.types;
using fuchsia.hardware.i2cimpl;
using fuchsia.images2;
using fuchsia.sysmem;
using zx;
type ColorConversion = strict bits : uint32 {
/// If set, use the 0 vector for the color conversion preoffset
PREOFFSET = 0x1;
/// If set, use the identity matrix for the color conversion coefficients
COEFFICIENTS = 0x2;
/// If set, use the 0 vector for the color conversion postoffset
POSTOFFSET = 0x4;
};
/// Constants for display_config's mode_flags field
type ModeFlag = strict bits : uint32 {
VSYNC_POSITIVE = 0x1;
HSYNC_POSITIVE = 0x2;
INTERLACED = 0x4;
ALTERNATING_VBLANK = 0x8;
DOUBLE_CLOCKED = 0x10;
};
/// The video parameters which specify the display mode.
/// TODO(https://fxbug.dev/42085013): Replace this type with something more similar
/// to //src/graphics/display/lib/api-types-cpp/display-timing.h.
type DisplayMode = struct {
pixel_clock_khz uint32;
h_addressable uint32;
h_front_porch uint32;
h_sync_pulse uint32;
h_blanking uint32;
v_addressable uint32;
v_front_porch uint32;
v_sync_pulse uint32;
v_blanking uint32;
/// A bitmask of MODE_FLAG_* values
flags uint32;
};
type DisplayConfig = struct {
/// the display id to which the configuration applies
display_id uint64;
mode DisplayMode;
/// Bitmask of flags defined in the ColorConversion enum.
cc_flags uint32;
/// Color conversion is applied to each pixel according to the formula:
///
/// (cc_coefficients * (pixel + cc_preoffsets)) + cc_postoffsets
///
/// where pixel is a column vector consisting of the pixel's 3 components.
cc_preoffsets array<float32, 3>;
cc_coefficients array<array<float32, 3>, 3>;
cc_postoffsets array<float32, 3>;
layer vector<fuchsia.hardware.display.types.Layer>:MAX;
};
/// The capabilities of a display panel.
type Panel = flexible resource union {
/// The I2C bus to use to read this display's EDID.
1: i2c client_end:fuchsia.hardware.i2cimpl.Device;
/// Hard-coded display configuration.
///
/// Can be used when the device does not implement EDID,
/// or when the driver needs to override the EDID contents.
2: mode DisplayMode;
};
/// A structure containing information a connected display.
type AddedDisplayArgs = resource struct {
display_id uint64;
panel Panel;
/// A list of pixel formats supported by the display. The first entry is the
/// preferred pixel format.
pixel_formats vector<fuchsia.images2.PixelFormat>:MAX;
};
/// This protocol is `open` while under development.
/// TODO(b/316631158): We should make it `closed` once the API is stabilized.
@discoverable
@transport("Driver")
open protocol Engine {
/// Import a sysmem buffer collection token.
///
/// Returns ZX_ERR_ALREADY_EXISTS if `collection_id` is in use.
flexible ImportBufferCollection(resource struct {
buffer_collection_id BufferCollectionId;
collection_token client_end:fuchsia.sysmem.BufferCollectionToken;
}) -> () error zx.Status;
/// Release an imported buffer collection.
///
/// Returns ZX_ERR_NOT_FOUND if `collection_id` isn't successfully imported.
flexible ReleaseBufferCollection(struct {
collection_id uint64;
}) -> () error zx.Status;
/// Imports an image from a imported BufferCollection into the driver and
/// returns its unique ID.
///
/// Returns ZX_OK if the image is imported succesfully.
/// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
/// Returns ZX_ERR_SHOULD_WAIT if the buffer collection is not already
/// allocated.
flexible ImportImage(struct {
// TODO(https://fxbug.dev/329163718): Some of the information in
// `image_metadata` was negotiated by sysmem. The display coordinator or
// engine drivers should read that information directly from sysmem.
image_metadata fuchsia.hardware.display.types.ImageMetadata;
buffer_id BufferId;
}) -> (struct {
image_id ImageId;
}) error zx.Status;
/// Import BufferCollection backed VMO pointed to by `index`.
/// Importing the VMO usually involves pinning the VMO and updating display
/// controller hardware registers with the physical address of the VMO to be
/// used for capture.
///
/// If display capture is not supported, returns ZX_ERR_NOT_SUPPORTED.
///
/// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
/// Returns ZX_ERR_SHOULD_WAIT if the buffer collection is not already
/// allocated.
flexible ImportImageForCapture(struct {
buffer_id BufferId;
}) -> (struct {
capture_image_id ImageId;
}) error zx.Status;
/// Releases any driver state associated with the given image. The client
/// is expected to not release any images passed to `apply_config`
/// until a vsync occurs with a more recent image.
flexible ReleaseImage(struct {
image_id ImageId;
}) -> ();
/// Validates the given configuration.
///
/// The configuration may not include all displays. Omitted displays should
/// be treated as whichever of off or displaying a blank screen results in
/// a more permissive validation.
///
/// All displays in a configuration will have at least one layer. The
/// layers will be arranged in increasing z-order, and their z_index fields
/// will be set consecutively.
///
/// Whether or not the driver can accept the configuration cannot depend on
/// the particular image handles, as it must always be possible to present
/// a new image in place of another image with a matching configuration.
///
/// `config_check_result` should be set to a CONFIG_DISPLAY_* error if the
/// combination of display modes is not supported.
///
/// `client_composition_opcodes` are per-layer client operations
/// to make the layer configuration supported by the display hardware. If
/// the `config_check_result` is not `CONFIG_CHECK_RESULT_OK`, the values of
/// `client_composition_opcodes` are undefined and should be ignored by the
/// client.
///
/// `client_composition_opcodes` is an array with one element for each
/// layer in
/// each display_config element. The elements map to layers following a
/// DFS traversal of a tree where the first-level children are the
/// `display_config` elements, and the second-level children are each
/// `DisplayConfig`'s layers.
///
/// The element ordering matches flattening the array obtained by mapping
/// each display_config element to its `DisplayConfig.layers` value:
/// [ display 0 layer 0, display 0 layer 1, ...,
/// display 1 layer 0, display 1 layer 1, ...,
/// display (N-1) layer 0, ..., display (N-1) layer (M-1) ].
flexible CheckConfiguration(struct {
display_config vector<DisplayConfig>:MAX;
}) -> (struct {
config_check_result fuchsia.hardware.display.types.ConfigResult;
client_composition_opcodes
vector<fuchsia.hardware.display.types.ClientCompositionOpcode>:MAX;
});
/// Applies the configuration.
///
/// All configurations passed to this function must be derived from
/// configurations which have been successfully validated, with the only
/// differences either being omitted layers or different image handles. To
/// account for any layers which are not present, the driver must use the
/// z_index values of the present layers to configure them as if the whole
/// configuration was present.
///
/// Unlike with `CheckConfiguration`, displays included in the configuration
/// are not guaranteed to include any layers. Both omitted displays and
/// displays with no layers can either be turned off or set to display a
/// blank screen, but for displays with no layers there is a strong
/// preference to display a blank screen instead of turning them off. In
/// either case, the driver must drop all references to old images and
/// invoke the vsync callback after doing so.
flexible ApplyConfiguration(struct {
display_config vector<DisplayConfig>:MAX;
/// Identifies the configuration to be applied. Must be a valid value.
/// Must be strictly increasing across calls.
config_stamp fuchsia.hardware.display.types.ConfigStamp;
}) -> ();
/// Set ELD (EDID Like Data, audio info in EDID) for one display.
///
/// This method is called independently from the CheckConfiguration and
/// ApplyConfiguration methods. The display_id may be unconfigured at the
/// time this method is called. raw_eld is the ELD raw data formatted
/// according to the HDA specification version 1.0a section 7.3.3.34.1.
/// https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf
flexible SetEld(struct {
display_id uint64;
raw_eld vector<uint8>:MAX;
}) -> ();
/// Set sysmem buffer collection contraints needed to ensure an image can be
/// imported with `config` on the imported BufferCollecition with
/// `collection_id`.
///
/// Returns ZX_ERR_NOT_FOUND if `collection_id` is not imported yet.
flexible SetBufferCollectionConstraints(struct {
usage fuchsia.hardware.display.types.ImageBufferUsage;
buffer_collection_id BufferCollectionId;
}) -> () error zx.Status;
/// Power off/on the display panel. Newly added displays are turned on by
/// default.
///
/// Displays that are turned off will not deliver VSync events.
/// This may include the vsync event for the most recently applied
/// config.
flexible SetDisplayPower(struct {
display_id uint64;
power_on bool;
}) -> () error zx.Status;
/// Set the minimum value of RGB channels.
///
/// Returns ZX_ERR_NOT_SUPPORTED if RGB clamping is not supported.
///
/// This method is provisional and is only for some display engines.
/// Most display drivers willreturn ZX_ERR_NOT_SUPPORTED.
//
// TODO(https://fxbug.dev/328903017): This is a provisional method meant
// to address a hardware issue where RGB channels need to get clamped in
// order to reduce backlight bleeding. Revise this method when stabilizing
// the Engine protocol API.
flexible SetMinimumRgb(struct {
/// Must be >= 0 and <= 255.
minimum_rgb uint8;
}) -> () error zx.Status;
/// Returns true iff the display Engine supports capturing the pixels
/// on the display device.
flexible IsCaptureSupported() -> (struct {
is_supported bool;
});
/// Starts capture into the resource mapped by `capture_image_id `(non-blocking)
/// Only one active capture is allowed at a time.
/// A valid image must be displayed during capture. Otherwise unexpected
/// hardware behavior might occur.
///
/// Drivers should not leave display hardware in this unexpected state.
/// Drivers are expected to stop and/or abort capture if no valid image is
/// being displayed.
///
/// Returns ZX_ERR_NOT_SUPPORTED if display capture feature is not
/// supported.
flexible StartCapture(struct {
capture_image_id ImageId;
}) -> () error zx.Status;
/// Releases resources allocated by `capture_image_id`.
/// Releasing resources from an active capture is not allowed and will cause
/// unexpected behavior.
///
/// Returns ZX_ERR_NOT_SUPPORTED if display capture feature is not
/// supported.
flexible ReleaseCapture(struct {
capture_image_id ImageId;
}) -> () error zx.Status;
/// Returns true if display capture is supported and the previous capture is
/// completed. False otherwise.
flexible IsCaptureCompleted() -> (struct {
is_capture_completed bool;
});
/// Triggered when a previous display capture triggered by [`StartCapture`]
/// is completed.
///
/// The display Engine emits an [`OnCaptureComplete`] event only if
/// [`IsCaptureSupported`] returns `true`.
flexible -> OnCaptureComplete();
/// Called when displays are added or removed.
///
/// The driver must be done accessing any images which were on the removed
/// displays.
///
/// The driver should emit this event if any displays are present.
flexible -> OnDisplaysChanged(resource struct {
added_displays vector<AddedDisplayArgs>:MAX;
removed_display_ids vector<uint64>:MAX;
});
/// Events which are invoked when display vsync occurs.
///
/// Arguments
/// - `timestamp`
/// The ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
/// - `config_stamp`
/// The config stamp of the latest configuration that is currently
/// fully applied to all the layers of the display with `display_id`.
/// If none of the configurations are currently fully applied to
/// this display, a null value will be passed to the driver.
/// Note that an `ApplyConfiguration()` call may contain multiple
/// configurations with a certain `config_stamp`; Only the application
/// status of the configuration with ID `display_id` is related.
///
/// The driver must emit this event as close as possible to the start of
/// every display's VSync period, even if the display has no images
/// displayed.
flexible -> OnDisplayVsync(struct {
display_id uint64;
timestamp zx.Time;
config_stamp box<fuchsia.hardware.display.types.ConfigStamp>;
});
// A noop method with a response from the server that should be used
// by clients who optionally use this library to determine availability.
flexible IsAvailable() -> ();
};
service Service {
engine client_end:Engine;
};