// 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 zx; // Invalid id for displays, images, and events. const uint64 invalidId = 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 modeInterlaced = 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 identifierMaxLen = 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 modes; // zx_pixel_format_t constants supported by the attached display. The // first entry is the preferred mode. vector 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 cursor_configs; string:identifierMaxLen manufacturer_name; string:identifierMaxLen monitor_name; string:identifierMaxLen monitor_serial; }; struct ImagePlane { // Offset from the beginning of the mapped region. uint32 byte_offset; uint32 bytes_per_row; }; // 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 typeSimple, 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 = typeSimple; array:4 planes; }; const uint32 typeSimple = 0; // 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; }; // Interface for accessing the display hardware. // // The driver supports two simultaneous clients - a primary client and a virtcon // client. The primary client is obtained by directly opening the devfs device, // while the virtcon client is obtained by opening a 'virtcon' child of the // device. // // 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. interface 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. -> DisplaysChanged(vector added, vector removed); // Imports a VMO backed image. If tiling is not typeSimple, it is up to // the driver and client to agree on its meaning through some mechanism // outside the scope of this API. ImportVmoImage(ImageConfig image_config, handle vmo, int32 offset) -> (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 invalidId, 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). ImportEvent(handle 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. 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:3 preoffsets, array:9 coefficients, array: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 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 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 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); // 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 where were actively being displayed. -> Vsync(uint64 display_id, uint64 timestamp, vector images); // 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. -> ClientOwnershipChange(bool has_ownership); // Computes the stride (in pixels) necessary for a linear image with the // given width and pixel format. Returns 0 on error. ComputeLinearImageStride(uint32 width, uint32 pixel_format) -> (uint32 stride); // Allocates a VMO of the requested size which can be used for images. // TODO: move this into a separate video buffer management system. AllocateVmo(uint64 size) -> (zx.status res, handle? vmo); };