blob: becbbb392fabd20631b9110605e3e25a647959e5 [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.
// WARNING: This file is machine generated by fidlc.
#pragma once
#include <ddk/protocol/display-controller.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/device/audio.h>
#include <zircon/types.h>
#include "display-controller-internal.h"
// DDK display-controller-protocol support
//
// :: Proxies ::
//
// ddk::DisplayControllerProtocolProxy is a simple wrapper around
// display_controller_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
// ddk::DisplayControllerProtocol is a mixin class that simplifies writing DDK drivers
// that implement the display-controller protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_DISPLAY_CONTROLLER device.
// class DisplayControllerDevice {
// using DisplayControllerDeviceType = ddk::Device<DisplayControllerDevice, /* ddk mixins */>;
//
// class DisplayControllerDevice : public DisplayControllerDeviceType,
// public ddk::DisplayControllerProtocol<DisplayControllerDevice> {
// public:
// DisplayControllerDevice(zx_device_t* parent)
// : DisplayControllerDeviceType("my-display-controller-protocol-device", parent) {}
//
// void DisplayControllerSetDisplayControllerInterface(const display_controller_interface_t*
// intf);
//
// zx_status_t DisplayControllerImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset);
//
// void DisplayControllerReleaseImage(image_t* image);
//
// uint32_t DisplayControllerCheckConfiguration(const display_config_t** display_config_list,
// size_t display_config_count, uint32_t** out_layer_cfg_result_list, size_t*
// layer_cfg_result_count);
//
// void DisplayControllerApplyConfiguration(const display_config_t** display_config_list, size_t
// display_config_count);
//
// uint32_t DisplayControllerComputeLinearStride(uint32_t width, zx_pixel_format_t
// pixel_format);
//
// zx_status_t DisplayControllerAllocateVmo(uint64_t size, zx_handle_t* out_vmo);
//
// ...
// };
namespace ddk {
// The client will not make any `ZX_PROTOCOL_DISPLAY_CONTROLLER_IMPL` calls into the device
// during these callbacks.
template <typename D>
class DisplayControllerInterface : public internal::base_mixin {
public:
DisplayControllerInterface() {
internal::CheckDisplayControllerInterfaceSubclass<D>();
display_controller_interface_ops_.on_displays_changed =
DisplayControllerInterfaceOnDisplaysChanged;
display_controller_interface_ops_.on_display_vsync =
DisplayControllerInterfaceOnDisplayVsync;
display_controller_interface_ops_.get_audio_format =
DisplayControllerInterfaceGetAudioFormat;
}
protected:
display_controller_interface_ops_t display_controller_interface_ops_ = {};
private:
// Callbacks which are invoked when displays are added or removed. |added_display_list| and
// |removed_display_list| point to arrays of the display ids which were added and removed. If
// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
// The driver must be done accessing any images which were on the removed displays.
// The driver should call this function when the callback is registered if any displays
// are present.
static void DisplayControllerInterfaceOnDisplaysChanged(
void* ctx, const added_display_args_t* added_display_list, size_t added_display_count,
const uint64_t* removed_display_list, size_t removed_display_count,
added_display_info_t* out_display_info_list, size_t display_info_count,
size_t* out_display_info_actual) {
static_cast<D*>(ctx)->DisplayControllerInterfaceOnDisplaysChanged(
added_display_list, added_display_count, removed_display_list, removed_display_count,
out_display_info_list, display_info_count, out_display_info_actual);
}
// |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
// |handles| points to an array of image handles of each framebuffer being
// displayed, in increasing z-order.
static void DisplayControllerInterfaceOnDisplayVsync(void* ctx, uint64_t display_id,
int64_t timestamp,
const uint64_t* handle_list,
size_t handle_count) {
static_cast<D*>(ctx)->DisplayControllerInterfaceOnDisplayVsync(display_id, timestamp,
handle_list, handle_count);
}
static zx_status_t
DisplayControllerInterfaceGetAudioFormat(void* ctx, uint64_t display_id, uint32_t fmt_idx,
audio_stream_format_range_t* out_fmt) {
return static_cast<D*>(ctx)->DisplayControllerInterfaceGetAudioFormat(display_id, fmt_idx,
out_fmt);
}
};
class DisplayControllerInterfaceProxy {
public:
DisplayControllerInterfaceProxy() : ops_(nullptr), ctx_(nullptr) {}
DisplayControllerInterfaceProxy(const display_controller_interface_t* proto)
: ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(display_controller_interface_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
// Callbacks which are invoked when displays are added or removed. |added_display_list| and
// |removed_display_list| point to arrays of the display ids which were added and removed. If
// |added_display_count| or |removed_display_count| is 0, the corresponding array can be NULL.
// The driver must be done accessing any images which were on the removed displays.
// The driver should call this function when the callback is registered if any displays
// are present.
void OnDisplaysChanged(const added_display_args_t* added_display_list,
size_t added_display_count, const uint64_t* removed_display_list,
size_t removed_display_count,
added_display_info_t* out_display_info_list, size_t display_info_count,
size_t* out_display_info_actual) {
ops_->on_displays_changed(ctx_, added_display_list, added_display_count,
removed_display_list, removed_display_count,
out_display_info_list, display_info_count,
out_display_info_actual);
}
// |timestamp| is the ZX_CLOCK_MONOTONIC timestamp at which the vsync occurred.
// |handles| points to an array of image handles of each framebuffer being
// displayed, in increasing z-order.
void OnDisplayVsync(uint64_t display_id, int64_t timestamp, const uint64_t* handle_list,
size_t handle_count) {
ops_->on_display_vsync(ctx_, display_id, timestamp, handle_list, handle_count);
}
zx_status_t GetAudioFormat(uint64_t display_id, uint32_t fmt_idx,
audio_stream_format_range_t* out_fmt) {
return ops_->get_audio_format(ctx_, display_id, fmt_idx, out_fmt);
}
private:
display_controller_interface_ops_t* ops_;
void* ctx_;
};
// The client guarantees that check_configuration and apply_configuration are always
// made from a single thread. The client makes no other threading guarantees.
template <typename D>
class DisplayControllerProtocol : public internal::base_mixin {
public:
DisplayControllerProtocol() {
internal::CheckDisplayControllerProtocolSubclass<D>();
display_controller_protocol_ops_.set_display_controller_interface =
DisplayControllerSetDisplayControllerInterface;
display_controller_protocol_ops_.import_vmo_image = DisplayControllerImportVmoImage;
display_controller_protocol_ops_.release_image = DisplayControllerReleaseImage;
display_controller_protocol_ops_.check_configuration = DisplayControllerCheckConfiguration;
display_controller_protocol_ops_.apply_configuration = DisplayControllerApplyConfiguration;
display_controller_protocol_ops_.compute_linear_stride =
DisplayControllerComputeLinearStride;
display_controller_protocol_ops_.allocate_vmo = DisplayControllerAllocateVmo;
}
protected:
display_controller_protocol_ops_t display_controller_protocol_ops_ = {};
private:
// The function will only be called once, and it will be called before any other
// functions are called.
static void
DisplayControllerSetDisplayControllerInterface(void* ctx,
const display_controller_interface_t* intf) {
static_cast<D*>(ctx)->DisplayControllerSetDisplayControllerInterface(intf);
}
// Imports a VMO backed image into the driver. The driver should set image->handle. The
// driver does not own the vmo handle passed to this function.
static zx_status_t DisplayControllerImportVmoImage(void* ctx, image_t* image, zx_handle_t vmo,
size_t offset) {
return static_cast<D*>(ctx)->DisplayControllerImportVmoImage(image, vmo, offset);
}
// Releases any driver state associated with the given image. The client guarantees that
// any images passed to apply_config will not be released until a vsync occurs with a
// more recent image.
static void DisplayControllerReleaseImage(void* ctx, image_t* image) {
static_cast<D*>(ctx)->DisplayControllerReleaseImage(image);
}
// Validates the given configuration.
// The configuration may not include all displays. Omiteed displays should be treated as
// whichever of off or displaying a blank screen results in a more premissive 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. It also cannot depend on the
// cursor position, as that can be updated without another call to check_configuration.
// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
// display modes is not supported.
// layer_cfg_result points to an array of arrays. The primary length is display_count, the
// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
// flag in the corresponding layer_cfg_result entry.
// The driver must not retain references to the configuration after this function returns.
// TODO: Fix me...
static uint32_t DisplayControllerCheckConfiguration(
void* ctx, const display_config_t** display_config_list, size_t display_config_count,
uint32_t** out_layer_cfg_result_list, size_t* layer_cfg_result_count) {
return static_cast<D*>(ctx)->DisplayControllerCheckConfiguration(
display_config_list, display_config_count, out_layer_cfg_result_list,
layer_cfg_result_count);
}
// Applies the configuration.
// All configurations passed to this function will be derived from configurations which
// have been succesfully 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 check_configuration, 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 turn them off.
// In either case, the driver must drop all references to old images and invoke the vsync
// callback after doing so.
// The driver must not retain references to the configuration after this function returns.
static void DisplayControllerApplyConfiguration(void* ctx,
const display_config_t** display_config_list,
size_t display_config_count) {
static_cast<D*>(ctx)->DisplayControllerApplyConfiguration(display_config_list,
display_config_count);
}
// Computes the stride (in pixels) necessary for a linear image with the given width
// and pixel format. Returns 0 on error.
static uint32_t DisplayControllerComputeLinearStride(void* ctx, uint32_t width,
zx_pixel_format_t pixel_format) {
return static_cast<D*>(ctx)->DisplayControllerComputeLinearStride(width, pixel_format);
}
// Allocates a VMO of the requested size which can be used for images.
static zx_status_t DisplayControllerAllocateVmo(void* ctx, uint64_t size,
zx_handle_t* out_vmo) {
return static_cast<D*>(ctx)->DisplayControllerAllocateVmo(size, out_vmo);
}
};
class DisplayControllerProtocolProxy {
public:
DisplayControllerProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
DisplayControllerProtocolProxy(const display_controller_protocol_t* proto)
: ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(display_controller_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
// The function will only be called once, and it will be called before any other
// functions are called.
void SetDisplayControllerInterface(const display_controller_interface_t* intf) {
ops_->set_display_controller_interface(ctx_, intf);
}
// Imports a VMO backed image into the driver. The driver should set image->handle. The
// driver does not own the vmo handle passed to this function.
zx_status_t ImportVmoImage(image_t* image, zx_handle_t vmo, size_t offset) {
return ops_->import_vmo_image(ctx_, image, vmo, offset);
}
// Releases any driver state associated with the given image. The client guarantees that
// any images passed to apply_config will not be released until a vsync occurs with a
// more recent image.
void ReleaseImage(image_t* image) { ops_->release_image(ctx_, image); }
// Validates the given configuration.
// The configuration may not include all displays. Omiteed displays should be treated as
// whichever of off or displaying a blank screen results in a more premissive 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. It also cannot depend on the
// cursor position, as that can be updated without another call to check_configuration.
// display_cfg_result should be set to a CONFIG_DISPLAY_* error if the combination of
// display modes is not supported.
// layer_cfg_result points to an array of arrays. The primary length is display_count, the
// secondary lengths are the corresponding display_cfg's layer_count. If display_cfg_result
// is CONFIG_DISPLAY_OK, any errors in layer configuration should be returned as a CLIENT*
// flag in the corresponding layer_cfg_result entry.
// The driver must not retain references to the configuration after this function returns.
// TODO: Fix me...
uint32_t CheckConfiguration(const display_config_t** display_config_list,
size_t display_config_count, uint32_t** out_layer_cfg_result_list,
size_t* layer_cfg_result_count) {
return ops_->check_configuration(ctx_, display_config_list, display_config_count,
out_layer_cfg_result_list, layer_cfg_result_count);
}
// Applies the configuration.
// All configurations passed to this function will be derived from configurations which
// have been succesfully 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 check_configuration, 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 turn them off.
// In either case, the driver must drop all references to old images and invoke the vsync
// callback after doing so.
// The driver must not retain references to the configuration after this function returns.
void ApplyConfiguration(const display_config_t** display_config_list,
size_t display_config_count) {
ops_->apply_configuration(ctx_, display_config_list, display_config_count);
}
// Computes the stride (in pixels) necessary for a linear image with the given width
// and pixel format. Returns 0 on error.
uint32_t ComputeLinearStride(uint32_t width, zx_pixel_format_t pixel_format) {
return ops_->compute_linear_stride(ctx_, width, pixel_format);
}
// Allocates a VMO of the requested size which can be used for images.
zx_status_t AllocateVmo(uint64_t size, zx_handle_t* out_vmo) {
return ops_->allocate_vmo(ctx_, size, out_vmo);
}
private:
display_controller_protocol_ops_t* ops_;
void* ctx_;
};
} // namespace ddk