blob: 5d922193a4c156197341e1b8258ac19ba642d713 [file] [log] [blame]
// 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 {
ROT_90 = 3;
ROT_180 = 4;
ROT_270 = 5;
enum AlphaMode : uint8 {
// Alpha is disabled for the plane (default).
// Plane alpha is premultiplied.
// Hardware should multiply the alpha and color channels when blending.
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.
// 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.
// 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.
// The client should provide a new image produced by clipping the source image
// to the region specified by src_frame.
// The client should provide a new image produced by applying the desired
// transformation, so that TRANSFORM_IDENTITY can be specified.
// The client should apply the color conversion itself.
// The client should apply the alpha itself.
// The client cannot control the display gamma, and must accept
// the uncalibrated output. Clients are expected to produce linear
// buffers, and as such they cannot perform software gamma
// correction.
enum ConfigResult : uint32 {
OK = 0;
// The requested layer configuration is invalid.
// The requested layer configuration cannot be supported by the hardware. See
// CheckConfig struct for mode details.
// The number of requested displays cannot be supported.
// The hardware cannot support the requested modes for the displays. The client
// should try a different set of displays or display modes.
struct ClientCompositionOp {
/// display_id and layer_id uniquely identify the subject of the
/// opcode.
uint64 display_id;
/// layer_id is 0 for whole-display issues like unsupported color
/// conversion and gamma tables.
uint64 layer_id;
ClientCompositionOpcode opcode;
/// Provider for display controllers.
/// The driver supports two simultaneous clients - a primary client and a virtcon
/// client. In some cases, the provider service may provide access to only one or
/// the other; if the client tries to open the other then `ZX_ERR_NOT_SUPPORTED` will
/// be returned.
[Discoverable, 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( 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( 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);
/// Import a gamma table for display calibration.
/// Each array is a quantized representation of the gamma curve for a single
/// color channel. An input luminance in [0.0, 1.0] is mapped to an index
/// between 0-255, and the value in the array is used as the output
/// luminance. Rounding behavior is hardware-specific, and most often it
/// will floor(input * 255.0), requiring an input luminance of 1.0 to get
/// the max output luminance.
/// It is an error to use output luminances outside of [0.0, 1.0]. Hardware
/// drivers may either clamp such values or disconnect a client that
/// provides invalid tables.
ImportGammaTable(uint64 gamma_table_id,
array<float32>:256 r,
array<float32>:256 g,
array<float32>:256 b);
/// Release an imported gamma table.
/// Subsequent calls to SetDisplayGammaTable cannot reference this
/// table. It is legal to re-use the gamma_table_id after making
/// this call. Releasing a table while it is set on a display is
/// safe, and will not modify the output of the display.
ReleaseGammaTable(uint64 gamma_table_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 and to
// validate their color correction input values.
SetDisplayColorConversion(uint64 display_id,
array<float32>:3 preoffsets,
array<float32>:9 coefficients,
array<float32>:3 postoffsets);
/// Set the gamma correction table for a display.
/// gamma_table_id must be a table registered with ImportGammaTable. It is
/// safe to release a gamma table after using it here, and will not modify
/// display output.
SetDisplayGammaTable(uint64 display_id, uint64 gamma_table_id);
// 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.
// 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;
/// 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.
SetMinimumRgb(uint8 minimum_rgb) -> () error zx.status;