1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5library ddk.protocol.display.controller; 6 7using zircon.device.audio; 8using zx; 9 10//using ZxPixelFormat = uint32; 11enum ZxPixelFormat : uint32 { 12}; 13 14/// The image is linear and VMO backed. 15const uint32 IMAGE_TYPE_SIMPLE = 0; 16 17/// A structure containing information about each plane of an image. 18struct ImagePlane { 19 uint32 byte_offset; 20 uint32 bytes_per_row; 21}; 22 23/// A structure containing information about an image. 24struct Image { 25 /// The width and height of the image in pixels. 26 uint32 width; 27 uint32 height; 28 29 /// The pixel format of the image. 30 ZxPixelFormat pixel_format; 31 32 /// The type conveys information about what is providing the pixel data. If this is not 33 /// IMAGE_FORMAT_SIMPLE, it is up to the driver and buffer producer to agree on the meaning 34 /// of the value through some mechanism outside the scope of this API. 35 uint32 type; 36 37 array<ImagePlane>:4 planes; 38 39 /// A driver-defined handle to the image. Each handle must be unique. 40 uint64 @handle; 41}; 42 43const uint32 INVALID_DISPLAY_ID = 0; 44 45/// A fallback structure to convey display information without an edid. 46struct DisplayParams { 47 uint32 width; 48 uint32 height; 49 uint32 refresh_rate_e2; 50}; 51 52/// Info about valid cursor configurations. 53struct CursorInfo { 54 /// The width and height of the cursor configuration, in pixels. 55 uint32 width; 56 uint32 height; 57 ZxPixelFormat format; 58}; 59 60union Panel { 61 /// The bus_id to use to read this display's edid from the device's i2c protocol. 62 uint32 i2c_bus_id; 63 /// The display's parameters if an edid is not present. 64 DisplayParams params; 65}; 66 67/// A structure containing information a connected display. 68struct AddedDisplayArgs { 69 uint64 display_id; 70 71 /// A flag indicating whether or not the display has a valid edid. 72 /// 73 /// If true, the device should expose an ZX_PROTOCOL_I2C_IMPL device through get_protocol, in 74 /// addition to the ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL protocol. Note that the i2c device 75 /// will be called from the on_displays_changed callback, so care should be taken to avoid 76 /// deadlocks or double-locking. 77 /// 78 /// If no edid is present, then the meaning of display_config's mode structure is 79 /// undefined, and drivers should ignore it in check_configuration and apply_configuration. 80 bool edid_present; 81 Panel panel; 82 83 /// A list of pixel formats supported by the display. The first entry is the 84 /// preferred pixel format. 85 vector<ZxPixelFormat> pixel_format; 86 87 /// A list of cursor configurations most likely to be accepted by the driver. Can 88 /// be null if cursor_count is 0. 89 /// 90 /// The driver may reject some of these configurations in some circumstances, and 91 /// it may accept other configurations, but at least one of these configurations 92 /// should be valid at most times. 93 vector<CursorInfo> cursor_info; 94}; 95 96/// Out parameters will be populated before on_displays_changed returns. 97struct AddedDisplayInfo { 98 bool is_hdmi_out; 99 bool is_standard_srgb_out; 100 101 uint32 audio_format_count; 102 103 /// All strings are null-terminated. |manufacturer_id| is guaranteed to have 104 /// length 3, all other strings may be empty. 105 string:4 manufacturer_id; 106 /// non-null 107 string manufacturer_name; 108 /// null-terminated 109 string:14 monitor_name; 110 /// null-terminated 111 string:14 monitor_serial; 112}; 113 114/// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device 115/// during these callbacks. 116[Layout = "ddk-interface"] 117interface DisplayControllerInterface { 118 /// Callbacks which are invoked when displays are added or removed. |added_display_list| and 119 /// |removed_display_list| point to arrays of the display ids which were added and removed. If 120 /// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL. 121 /// 122 /// The driver must be done accessing any images which were on the removed displays. 123 /// 124 /// The driver should call this function when the callback is registered if any displays 125 /// are present. 126 OnDisplaysChanged(vector<AddedDisplayArgs> added_display, 127 vector<uint64> removed_display) -> (vector<AddedDisplayInfo> display_info); 128 129 /// |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred. 130 /// |handles| points to an array of image handles of each framebuffer being 131 /// displayed, in increasing z-order. 132 OnDisplayVsync(uint64 display_id, zx.time timestamp, vector<uint64> @handle) -> (); 133 134 GetAudioFormat(uint64 display_id, uint32 fmt_idx) 135 -> (zx.status s, zircon.device.audio.AudioStreamFormatRange fmt); 136}; 137 138enum Alpha : uint8 { 139 DISABLE = 0; 140 PREMULTIPLIED = 1; 141 HW_MULTIPLY = 2; 142}; 143 144/// Rotations are applied counter-clockwise, and are applied before reflections. 145enum FrameTransform : uint32 { 146 IDENTITY = 0; 147 REFLECT_X = 1; 148 REFLECT_Y = 2; 149 ROT_90 = 3; 150 ROT_180 = 4; 151 ROT_270 = 5; 152 ROT_90_REFLECT_X = 6; 153 ROT_90_REFLECT_Y = 7; 154}; 155 156struct Frame { 157 /// (|x_pos|, |y_pos|) specifies the position of the upper-left corner 158 /// of the frame. 159 uint32 x_pos; 160 uint32 y_pos; 161 uint32 width; 162 uint32 height; 163}; 164 165struct PrimaryLayer { 166 Image image; 167 168 /// An ALPHA_* constant. 169 /// 170 /// If |alpha_mode| == `ALPHA_DISABLED`, the layer is opaque and alpha_layer_val is ignored. 171 /// 172 /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is NaN, the alpha 173 /// used when blending is determined by the per-pixel alpha channel. 174 /// 175 /// If |alpha_mode| == `PREMULTIPLIED` or `HW_MULTIPLY` and |alpha_layer_val| is not NaN, the 176 /// alpha used when blending is the product of alpha_layer_val and any per-pixel alpha. 177 /// Additionally, if alpha_mode == PREMULTIPLIED, then the hardware must premultiply the color 178 /// channel with alpha_layer_val before blending. 179 /// 180 /// If alpha_layer_val is not NaN, it will be in the range [0, 1]. 181 Alpha alpha_mode; 182 float32 alpha_layer_val; 183 184 FrameTransform transform_mode; 185 186 /// The source frame, where (0,0) is the top-left corner of the image. The 187 /// client guarantees that src_frame lies entirely within the image. 188 Frame src_frame; 189 190 /// The destination frame, where (0,0) is the top-left corner of the 191 /// composed output. The client guarantees that dest_frame lies entirely 192 /// within the composed output. 193 Frame dest_frame; 194}; 195 196struct CursorLayer { 197 Image image; 198 199 /// The position of the top-left corner of the cursor's image. When being 200 /// applied to a display, the cursor is guaranteed to have at least one 201 /// pixel of overlap with the display. 202 int32 x_pos; 203 int32 y_pos; 204}; 205 206struct ColorLayer { 207 ZxPixelFormat format; 208 /// The color to use for the layer. The color is little-endian, and is 209 /// guaranteed to be of the appropriate size. 210 vector<uint8> color; 211}; 212 213/// Types of layers. 214enum LayerType : uint32 { 215 PRIMARY = 0; 216 CURSOR = 1; 217 COLOR = 2; 218}; 219 220union LayerConfig { 221 PrimaryLayer primary; 222 CursorLayer cursor; 223 ColorLayer color; 224}; 225 226struct Layer { 227 LayerType type; 228 /// z_index of the layer. See |check_configuration| and |apply_configuration|. 229 uint32 z_index; 230 LayerConfig cfg; 231}; 232 233/// constants for display_config's mode_flags field 234enum ModeFlag : uint32 { 235 VSYNC_POSITIVE = 0x1; 236 HSYNC_POSITIVE = 0x2; 237 INTERLACED = 0x4; 238 ALTERNATING_VBLANK = 0x8; 239 DOUBLE_CLOCKED = 0x10; 240}; 241 242/// The video parameters which specify the display mode. 243struct DisplayMode { 244 uint32 pixel_clock_10khz; 245 uint32 h_addressable; 246 uint32 h_front_porch; 247 uint32 h_sync_pulse; 248 uint32 h_blanking; 249 uint32 v_addressable; 250 uint32 v_front_porch; 251 uint32 v_sync_pulse; 252 uint32 v_blanking; 253 /// A bitmask of MODE_FLAG_* values 254 uint32 flags; 255}; 256 257enum ColorConversion : uint32 { 258 /// If set, use the 0 vector for the color conversion preoffset 259 PREOFFSET = 0x1; 260 /// If set, use the identity matrix for the color conversion coefficients 261 COEFFICIENTS = 0x2; 262 /// If set, use the 0 vector for the color conversion postoffset 263 POSTOFFSET = 0x4; 264}; 265 266struct DisplayConfig { 267 /// the display id to which the configuration applies 268 uint64 display_id; 269 270 DisplayMode mode; 271 272 /// Bitmask of COLOR_CONVERSION_* flags 273 uint32 cc_flags; 274 /// Color conversion is applied to each pixel according to the formula: 275 /// 276 /// (cc_coefficients * (pixel + cc_preoffsets)) + cc_postoffsets 277 /// 278 /// where pixel is a column vector consisting of the pixel's 3 components. 279 array<float32>:3 cc_preoffsets; 280 array<array<float32>:3>:3 cc_coefficients; 281 array<float32>:3 cc_postoffsets; 282 283 vector<Layer?>? layer; 284}; 285 286enum ConfigDisplay : uint32 { 287 /// The display mode configuration is valid. Note that this is distinct from 288 /// whether or not the layer configuration is valid. 289 OK = 0; 290 /// Error indicating that the hardware cannot simultaneously support the 291 /// requested number of displays. 292 TOO_MANY = 1; 293 /// Error indicating that the hardware cannot simultaneously support the given 294 /// set of display modes. To support a mode, the display must be able to display 295 /// a single layer with width and height equal to the requested mode and the 296 /// preferred pixel format. 297 UNSUPPORTED_MODES = 2; 298}; 299 300enum Client : uint32 { 301 /// The client should convert the corresponding layer to a primary layer. 302 USE_PRIMARY = 0x1; 303 /// The client should compose all layers with MERGE_BASE and MERGE_SRC into a new, 304 /// single primary layer at the MERGE_BASE layer's z-order. The driver must accept 305 /// a fullscreen layer with the default pixel format, but may accept other layer 306 /// parameters. 307 /// 308 /// MERGE_BASE should only be set on one layer per display. If it is set on multiple 309 /// layers, the client will arbitrarily pick one and change the rest to MERGE_SRC. 310 MERGE_BASE = 0x2; 311 MERGE_SRC = 0x4; 312 /// The client should pre-scale the image so that src_frame's dimensions are equal 313 /// to dest_frame's dimensions. 314 FRAME_SCALE = 0x8; 315 /// The client should pre-clip the image so that src_frame's dimensions are equal to 316 /// the image's dimensions. 317 SRC_FRAME = 0x10; 318 /// The client should pre-apply the transformation so TRANSFORM_IDENTITY can be used. 319 TRANSFORM = 0x20; 320 /// The client should apply the color conversion. 321 COLOR_CONVERSION = 0x40; 322 /// The client should apply the alpha transformation itself. 323 ALPHA = 0x80; 324}; 325 326/// The client guarantees that check_configuration and apply_configuration are always 327/// made from a single thread. The client makes no other threading guarantees. 328[Layout = "ddk-protocol", HandleWrappers] 329interface DisplayControllerImpl { 330 /// The function will only be called once, and it will be called before any other 331 /// functions are called. 332 SetDisplayControllerInterface(DisplayControllerInterface intf) -> (); 333 334 /// Imports a VMO backed image into the driver. The driver should set image->handle. The 335 /// driver does not own the vmo handle passed to this function. 336 ImportVmoImage(Image? image, handle<vmo> vmo, usize offset) -> (zx.status s); 337 338 /// Releases any driver state associated with the given image. The client guarantees that 339 /// any images passed to apply_config will not be released until a vsync occurs with a 340 /// more recent image. 341 ReleaseImage(Image? image) -> (); 342 343 /// Validates the given configuration. 344 /// 345 /// The configuration may not include all displays. Omitted displays should be treated as 346 /// whichever of off or displaying a blank screen results in a more permissive validation. 347 /// 348 /// All displays in a configuration will have at least one layer. The layers will be 349 /// arranged in increasing z-order, and their z_index fields will be set consecutively. 350 /// 351 /// Whether or not the driver can accept the configuration cannot depend on the 352 /// particular image handles, as it must always be possible to present a new image in 353 /// place of another image with a matching configuration. It also cannot depend on the 354 /// cursor position, as that can be updated without another call to check_configuration. 355 /// 356 /// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of 357 /// display modes is not supported. 358 /// 359 /// layer_cfg_result points to an array of arrays. The primary length is display_count, the 360 /// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result 361 /// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT* 362 /// flag in the corresponding layer_cfg_result entry. 363 /// 364 /// The driver must not retain references to the configuration after this function returns. 365 /// TODO: Fix me... 366 CheckConfiguration(vector<DisplayConfig?> display_config) 367 -> (uint32 display_cfg_result, vector<uint32>? layer_cfg_result); 368 369 /// Applies the configuration. 370 /// 371 /// All configurations passed to this function will be derived from configurations which 372 /// have been successfully validated, with the only differences either being omitted layers 373 /// or different image handles. To account for any layers which are not present, the driver 374 /// must use the z_index values of the present layers to configure them as if the whole 375 /// configuration was present. 376 /// 377 /// Unlike with check_configuration, displays included in the configuration are not 378 /// guaranteed to include any layers. Both omitted displays and displays with no layers 379 /// can either be turned off or set to display a blank screen, but for displays with no 380 /// layers there is a strong preference to display a blank screen instead of turn them off. 381 /// In either case, the driver must drop all references to old images and invoke the vsync 382 /// callback after doing so. 383 /// 384 /// The driver must not retain references to the configuration after this function returns. 385 ApplyConfiguration(vector<DisplayConfig?> display_config) -> (); 386 387 /// Computes the stride (in pixels) necessary for a linear image with the given width 388 /// and pixel format. Returns 0 on error. 389 ComputeLinearStride(uint32 width, ZxPixelFormat pixel_format) -> (uint32 s); 390 391 /// Allocates a VMO of the requested size which can be used for images. 392 // TODO: move this functionality into a seperate video buffer management system. 393 AllocateVmo(uint64 size) -> (zx.status s, handle<vmo> vmo); 394}; 395