Merge "libadf: support ADF_{POST,SIMPLE_POST}_CONFIG_V2 ioctls" am: 64fc7442db
am: e36bede288
Change-Id: I6415b33d8a9b3319a3feb9736f18ead9c9eee859
This commit is contained in:
commit
cced4446db
6 changed files with 324 additions and 61 deletions
|
|
@ -180,6 +180,37 @@ int adf_device_post(struct adf_device *dev,
|
||||||
return (int)data.complete_fence;
|
return (int)data.complete_fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int adf_device_post_v2(struct adf_device *dev,
|
||||||
|
adf_id_t *interfaces, __u32 n_interfaces,
|
||||||
|
struct adf_buffer_config *bufs, __u32 n_bufs,
|
||||||
|
void *custom_data, __u64 custom_data_size,
|
||||||
|
enum adf_complete_fence_type complete_fence_type,
|
||||||
|
int *complete_fence)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct adf_post_config_v2 data;
|
||||||
|
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
data.interfaces = (uintptr_t)interfaces;
|
||||||
|
data.n_interfaces = n_interfaces;
|
||||||
|
data.bufs = (uintptr_t)bufs;
|
||||||
|
data.n_bufs = n_bufs;
|
||||||
|
data.custom_data = (uintptr_t)custom_data;
|
||||||
|
data.custom_data_size = custom_data_size;
|
||||||
|
data.complete_fence_type = complete_fence_type;
|
||||||
|
|
||||||
|
err = ioctl(dev->fd, ADF_POST_CONFIG_V2, &data);
|
||||||
|
if (err < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (complete_fence)
|
||||||
|
*complete_fence = data.complete_fence;
|
||||||
|
else if (data.complete_fence >= 0)
|
||||||
|
close(data.complete_fence);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int adf_device_attachment(struct adf_device *dev,
|
static int adf_device_attachment(struct adf_device *dev,
|
||||||
adf_id_t overlay_engine, adf_id_t interface, bool attach)
|
adf_id_t overlay_engine, adf_id_t interface, bool attach)
|
||||||
{
|
{
|
||||||
|
|
@ -421,6 +452,21 @@ int adf_interface_simple_buffer_alloc(int fd, __u32 w, __u32 h,
|
||||||
return (int)data.fd;
|
return (int)data.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void adf_interface_simple_post_config_buf(struct adf_buffer_config *buf,
|
||||||
|
__u32 overlay_engine, __u32 w, __u32 h, __u32 format, int buf_fd,
|
||||||
|
__u32 offset, __u32 pitch, int acquire_fence)
|
||||||
|
{
|
||||||
|
buf->overlay_engine = overlay_engine;
|
||||||
|
buf->w = w;
|
||||||
|
buf->h = h;
|
||||||
|
buf->format = format;
|
||||||
|
buf->fd[0] = buf_fd;
|
||||||
|
buf->offset[0] = offset;
|
||||||
|
buf->pitch[0] = pitch;
|
||||||
|
buf->n_planes = 1;
|
||||||
|
buf->acquire_fence = acquire_fence;
|
||||||
|
}
|
||||||
|
|
||||||
int adf_interface_simple_post(int fd, __u32 overlay_engine,
|
int adf_interface_simple_post(int fd, __u32 overlay_engine,
|
||||||
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
||||||
__u32 pitch, int acquire_fence)
|
__u32 pitch, int acquire_fence)
|
||||||
|
|
@ -429,16 +475,8 @@ int adf_interface_simple_post(int fd, __u32 overlay_engine,
|
||||||
struct adf_simple_post_config data;
|
struct adf_simple_post_config data;
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.buf.overlay_engine = overlay_engine;
|
adf_interface_simple_post_config_buf(&data.buf, overlay_engine, w, h, format,
|
||||||
data.buf.w = w;
|
buf_fd, offset, pitch, acquire_fence);
|
||||||
data.buf.h = h;
|
|
||||||
data.buf.format = format;
|
|
||||||
data.buf.fd[0] = buf_fd;
|
|
||||||
data.buf.offset[0] = offset;
|
|
||||||
data.buf.pitch[0] = pitch;
|
|
||||||
data.buf.n_planes = 1;
|
|
||||||
data.buf.acquire_fence = acquire_fence;
|
|
||||||
|
|
||||||
ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG, &data);
|
ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG, &data);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -446,6 +484,32 @@ int adf_interface_simple_post(int fd, __u32 overlay_engine,
|
||||||
return (int)data.complete_fence;
|
return (int)data.complete_fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int adf_interface_simple_post_v2(int fd, adf_id_t overlay_engine,
|
||||||
|
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
||||||
|
__u32 pitch, int acquire_fence,
|
||||||
|
enum adf_complete_fence_type complete_fence_type,
|
||||||
|
int *complete_fence)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct adf_simple_post_config_v2 data;
|
||||||
|
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
adf_interface_simple_post_config_buf(&data.buf, overlay_engine, w, h, format,
|
||||||
|
buf_fd, offset, pitch, acquire_fence);
|
||||||
|
data.complete_fence_type = complete_fence_type;
|
||||||
|
|
||||||
|
ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG_V2, &data);
|
||||||
|
if (ret < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (complete_fence)
|
||||||
|
*complete_fence = data.complete_fence;
|
||||||
|
else if (data.complete_fence >= 0)
|
||||||
|
close(data.complete_fence);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t adf_overlay_engines(struct adf_device *dev, adf_id_t **overlay_engines)
|
ssize_t adf_overlay_engines(struct adf_device *dev, adf_id_t **overlay_engines)
|
||||||
{
|
{
|
||||||
char pattern[64];
|
char pattern[64];
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,29 @@ int adf_device_post(struct adf_device *dev,
|
||||||
adf_id_t *interfaces, size_t n_interfaces,
|
adf_id_t *interfaces, size_t n_interfaces,
|
||||||
struct adf_buffer_config *bufs, size_t n_bufs,
|
struct adf_buffer_config *bufs, size_t n_bufs,
|
||||||
void *custom_data, size_t custom_data_size);
|
void *custom_data, size_t custom_data_size);
|
||||||
|
/**
|
||||||
|
* Atomically posts a new display configuration to the specified interfaces.
|
||||||
|
*
|
||||||
|
* Compared to adf_device_post(), adf_device_post_v2():
|
||||||
|
*
|
||||||
|
* (*) allows the client to choose the kind of sync fence returned
|
||||||
|
* (through complete_fence_type)
|
||||||
|
*
|
||||||
|
* (*) stores the returned sync fence fd in a provided buffer, so the client
|
||||||
|
* can distinguish between a permission error (ret = -1) and a successful
|
||||||
|
* call that returns no fence (*complete_fence = -1)
|
||||||
|
*
|
||||||
|
* On error, returns -errno.
|
||||||
|
*
|
||||||
|
* On devices without the corresponding kernel support, returns -ENOTTY.
|
||||||
|
*/
|
||||||
|
int adf_device_post_v2(struct adf_device *dev,
|
||||||
|
adf_id_t *interfaces, __u32 n_interfaces,
|
||||||
|
struct adf_buffer_config *bufs, __u32 n_bufs,
|
||||||
|
void *custom_data, __u64 custom_data_size,
|
||||||
|
enum adf_complete_fence_type complete_fence_type,
|
||||||
|
int *complete_fence);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches the specified interface and overlay engine.
|
* Attaches the specified interface and overlay engine.
|
||||||
*/
|
*/
|
||||||
|
|
@ -163,6 +186,28 @@ int adf_interface_simple_buffer_alloc(int fd, __u32 w, __u32 h,
|
||||||
int adf_interface_simple_post(int fd, adf_id_t overlay_engine,
|
int adf_interface_simple_post(int fd, adf_id_t overlay_engine,
|
||||||
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
||||||
__u32 pitch, int acquire_fence);
|
__u32 pitch, int acquire_fence);
|
||||||
|
/**
|
||||||
|
* Posts a single-plane RGB buffer to the display using the specified
|
||||||
|
* overlay engine.
|
||||||
|
*
|
||||||
|
* Compared to adf_interface_simple_post(), adf_interface_simple_post_v2():
|
||||||
|
*
|
||||||
|
* (*) allows the client to choose the kind of sync fence returned
|
||||||
|
* (through complete_fence_type)
|
||||||
|
*
|
||||||
|
* (*) stores the returned sync fence fd in a provided buffer, so the client
|
||||||
|
* can distinguish between a permission error (ret = -1) and a successful
|
||||||
|
* call that returns no fence (*complete_fence = -1)
|
||||||
|
*
|
||||||
|
* On error, returns -errno.
|
||||||
|
*
|
||||||
|
* On devices without the corresponding kernel support, returns -ENOTTY.
|
||||||
|
*/
|
||||||
|
int adf_interface_simple_post_v2(int fd, adf_id_t overlay_engine,
|
||||||
|
__u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
|
||||||
|
__u32 pitch, int acquire_fence,
|
||||||
|
enum adf_complete_fence_type complete_fence_type,
|
||||||
|
int *complete_fence);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumerates all overlay engines belonging to an ADF device.
|
* Enumerates all overlay engines belonging to an ADF device.
|
||||||
|
|
|
||||||
|
|
@ -49,69 +49,94 @@ enum adf_event_type {
|
||||||
ADF_EVENT_DEVICE_CUSTOM = 128,
|
ADF_EVENT_DEVICE_CUSTOM = 128,
|
||||||
ADF_EVENT_TYPE_MAX = 255,
|
ADF_EVENT_TYPE_MAX = 255,
|
||||||
};
|
};
|
||||||
struct adf_set_event {
|
enum adf_complete_fence_type {
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
ADF_COMPLETE_FENCE_NONE = 0,
|
||||||
|
ADF_COMPLETE_FENCE_PRESENT = 1,
|
||||||
|
ADF_COMPLETE_FENCE_RELEASE = 2,
|
||||||
|
};
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
struct adf_set_event {
|
||||||
__u8 type;
|
__u8 type;
|
||||||
__u8 enabled;
|
__u8 enabled;
|
||||||
};
|
};
|
||||||
struct adf_event {
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
struct adf_event {
|
||||||
__u8 type;
|
__u8 type;
|
||||||
__u32 length;
|
__u32 length;
|
||||||
};
|
};
|
||||||
struct adf_vsync_event {
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
struct adf_vsync_event {
|
||||||
struct adf_event base;
|
struct adf_event base;
|
||||||
__aligned_u64 timestamp;
|
__aligned_u64 timestamp;
|
||||||
};
|
};
|
||||||
struct adf_hotplug_event {
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
struct adf_hotplug_event {
|
||||||
struct adf_event base;
|
struct adf_event base;
|
||||||
__u8 connected;
|
__u8 connected;
|
||||||
};
|
};
|
||||||
#define ADF_MAX_PLANES 4
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
#define ADF_MAX_PLANES 4
|
||||||
struct adf_buffer_config {
|
struct adf_buffer_config {
|
||||||
__u32 overlay_engine;
|
__u32 overlay_engine;
|
||||||
__u32 w;
|
__u32 w;
|
||||||
__u32 h;
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__u32 h;
|
||||||
__u32 format;
|
__u32 format;
|
||||||
__s32 fd[ADF_MAX_PLANES];
|
__s32 fd[ADF_MAX_PLANES];
|
||||||
__u32 offset[ADF_MAX_PLANES];
|
__u32 offset[ADF_MAX_PLANES];
|
||||||
__u32 pitch[ADF_MAX_PLANES];
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__u32 pitch[ADF_MAX_PLANES];
|
||||||
__u8 n_planes;
|
__u8 n_planes;
|
||||||
__s32 acquire_fence;
|
__s32 acquire_fence;
|
||||||
};
|
};
|
||||||
#define ADF_MAX_BUFFERS (4096 / sizeof(struct adf_buffer_config))
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
#define ADF_MAX_BUFFERS (4096 / sizeof(struct adf_buffer_config))
|
||||||
struct adf_post_config {
|
struct adf_post_config {
|
||||||
size_t n_interfaces;
|
size_t n_interfaces;
|
||||||
__u32 __user * interfaces;
|
__u32 __user * interfaces;
|
||||||
size_t n_bufs;
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
size_t n_bufs;
|
||||||
struct adf_buffer_config __user * bufs;
|
struct adf_buffer_config __user * bufs;
|
||||||
size_t custom_data_size;
|
size_t custom_data_size;
|
||||||
void __user * custom_data;
|
void __user * custom_data;
|
||||||
__s32 complete_fence;
|
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__s32 complete_fence;
|
||||||
};
|
};
|
||||||
|
struct adf_post_config_v2 {
|
||||||
|
__u32 n_interfaces;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__u64 interfaces;
|
||||||
|
__u32 n_bufs;
|
||||||
|
__u64 bufs;
|
||||||
|
__u64 custom_data_size;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__u64 custom_data;
|
||||||
|
__s32 complete_fence;
|
||||||
|
__u8 complete_fence_type;
|
||||||
|
};
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
#define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
|
#define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
|
||||||
struct adf_simple_buffer_alloc {
|
struct adf_simple_buffer_alloc {
|
||||||
__u16 w;
|
__u16 w;
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
|
||||||
__u16 h;
|
__u16 h;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
__u32 format;
|
__u32 format;
|
||||||
__s32 fd;
|
__s32 fd;
|
||||||
__u32 offset;
|
__u32 offset;
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
|
||||||
__u32 pitch;
|
__u32 pitch;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
};
|
};
|
||||||
struct adf_simple_post_config {
|
struct adf_simple_post_config {
|
||||||
struct adf_buffer_config buf;
|
struct adf_buffer_config buf;
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
|
||||||
__s32 complete_fence;
|
__s32 complete_fence;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
};
|
||||||
|
struct adf_simple_post_config_v2 {
|
||||||
|
struct adf_buffer_config buf;
|
||||||
|
__s32 complete_fence;
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
__u8 complete_fence_type;
|
||||||
};
|
};
|
||||||
struct adf_attachment_config {
|
struct adf_attachment_config {
|
||||||
__u32 overlay_engine;
|
__u32 overlay_engine;
|
||||||
|
|
@ -177,4 +202,8 @@ struct adf_overlay_engine_data {
|
||||||
#define ADF_ATTACH _IOW(ADF_IOCTL_TYPE, 9, struct adf_attachment_config)
|
#define ADF_ATTACH _IOW(ADF_IOCTL_TYPE, 9, struct adf_attachment_config)
|
||||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
#define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, struct adf_attachment_config)
|
#define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, struct adf_attachment_config)
|
||||||
|
#define ADF_POST_CONFIG_V2 _IOW(ADF_IOCTL_TYPE, 11, struct adf_post_config_v2)
|
||||||
|
#define ADF_SIMPLE_POST_CONFIG_V2 _IOW(ADF_IOCTL_TYPE, 12, struct adf_simple_post_config_v2)
|
||||||
#endif
|
#endif
|
||||||
|
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,15 @@ enum adf_event_type {
|
||||||
ADF_EVENT_TYPE_MAX = 255,
|
ADF_EVENT_TYPE_MAX = 255,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum adf_complete_fence_type {
|
||||||
|
/* no fence */
|
||||||
|
ADF_COMPLETE_FENCE_NONE = 0,
|
||||||
|
/* fence fires when the configuration appears on the screen */
|
||||||
|
ADF_COMPLETE_FENCE_PRESENT = 1,
|
||||||
|
/* fence fires when the configuration leaves the screen */
|
||||||
|
ADF_COMPLETE_FENCE_RELEASE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct adf_set_event - start or stop subscribing to ADF events
|
* struct adf_set_event - start or stop subscribing to ADF events
|
||||||
*
|
*
|
||||||
|
|
@ -131,6 +140,9 @@ struct adf_buffer_config {
|
||||||
/**
|
/**
|
||||||
* struct adf_post_config - request to flip to a new set of buffers
|
* struct adf_post_config - request to flip to a new set of buffers
|
||||||
*
|
*
|
||||||
|
* This request is equivalent to &struct adf_post_config_v2 with
|
||||||
|
* @complete_fence_type = %ADF_COMPLETE_FENCE_RELEASE.
|
||||||
|
*
|
||||||
* @n_interfaces: number of interfaces targeted by the flip (input)
|
* @n_interfaces: number of interfaces targeted by the flip (input)
|
||||||
* @interfaces: ids of interfaces targeted by the flip (input)
|
* @interfaces: ids of interfaces targeted by the flip (input)
|
||||||
* @n_bufs: number of buffers displayed (input)
|
* @n_bufs: number of buffers displayed (input)
|
||||||
|
|
@ -152,6 +164,34 @@ struct adf_post_config {
|
||||||
|
|
||||||
__s32 complete_fence;
|
__s32 complete_fence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct adf_post_config_v2 - request to flip to a new set of buffers
|
||||||
|
*
|
||||||
|
* @n_interfaces: number of interfaces targeted by the flip (input)
|
||||||
|
* @interfaces: ids of interfaces targeted by the flip (input)
|
||||||
|
* @n_bufs: number of buffers displayed (input)
|
||||||
|
* @bufs: description of buffers displayed (input)
|
||||||
|
* @custom_data_size: size of driver-private data (input)
|
||||||
|
* @custom_data: driver-private data (input)
|
||||||
|
* @complete_fence_type: one of &enum adf_complete_fence_type describing what
|
||||||
|
* fence to return (input)
|
||||||
|
* @complete_fence: sync_fence fd which will fire at the time
|
||||||
|
* requested by @complete_fence_type (output)
|
||||||
|
*/
|
||||||
|
struct adf_post_config_v2 {
|
||||||
|
__u32 n_interfaces;
|
||||||
|
__u64 interfaces; /* __u32 * packed into __u64 */
|
||||||
|
|
||||||
|
__u32 n_bufs;
|
||||||
|
__u64 bufs; /* struct adf_buffer_config * packed into __u64 */
|
||||||
|
|
||||||
|
__u64 custom_data_size;
|
||||||
|
__u64 custom_data; /* void * packed into __u64 */
|
||||||
|
|
||||||
|
__s32 complete_fence;
|
||||||
|
__u8 complete_fence_type;
|
||||||
|
};
|
||||||
#define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
|
#define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -189,6 +229,9 @@ struct adf_simple_buffer_alloc {
|
||||||
* struct adf_simple_post_config - request to flip to a single buffer without
|
* struct adf_simple_post_config - request to flip to a single buffer without
|
||||||
* driver-private data
|
* driver-private data
|
||||||
*
|
*
|
||||||
|
* This request is equivalent to &struct adf_simple_post_config_v2 with
|
||||||
|
* @complete_fence_type = %ADF_COMPLETE_FENCE_RELEASE.
|
||||||
|
*
|
||||||
* @buf: description of buffer displayed (input)
|
* @buf: description of buffer displayed (input)
|
||||||
* @complete_fence: sync_fence fd which will clear when this buffer has left the
|
* @complete_fence: sync_fence fd which will clear when this buffer has left the
|
||||||
* screen (output)
|
* screen (output)
|
||||||
|
|
@ -198,6 +241,22 @@ struct adf_simple_post_config {
|
||||||
__s32 complete_fence;
|
__s32 complete_fence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct adf_simple_post_config_v2 - request to flip to a single buffer without
|
||||||
|
* driver-private data
|
||||||
|
*
|
||||||
|
* @buf: description of buffer displayed (input)
|
||||||
|
* @complete_fence_type: one of &enum adf_complete_fence_type describing what
|
||||||
|
* fence to return (input)
|
||||||
|
* @complete_fence: sync_fence fd which will fire at the time
|
||||||
|
* requested by @complete_fence_type (output)
|
||||||
|
*/
|
||||||
|
struct adf_simple_post_config_v2 {
|
||||||
|
struct adf_buffer_config buf;
|
||||||
|
__s32 complete_fence;
|
||||||
|
__u8 complete_fence_type;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct adf_attachment_config - description of attachment between an overlay
|
* struct adf_attachment_config - description of attachment between an overlay
|
||||||
* engine and an interface
|
* engine and an interface
|
||||||
|
|
@ -318,4 +377,10 @@ struct adf_overlay_engine_data {
|
||||||
#define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, \
|
#define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, \
|
||||||
struct adf_attachment_config)
|
struct adf_attachment_config)
|
||||||
|
|
||||||
|
#define ADF_POST_CONFIG_V2 _IOW(ADF_IOCTL_TYPE, 11, \
|
||||||
|
struct adf_post_config_v2)
|
||||||
|
#define ADF_SIMPLE_POST_CONFIG_V2 \
|
||||||
|
_IOW(ADF_IOCTL_TYPE, 12, \
|
||||||
|
struct adf_simple_post_config_v2)
|
||||||
|
|
||||||
#endif /* _UAPI_VIDEO_ADF_H_ */
|
#endif /* _UAPI_VIDEO_ADF_H_ */
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
cc_test {
|
cc_test {
|
||||||
name: "adf-unit-tests",
|
name: "adf-unit-tests",
|
||||||
srcs: ["adf_test.cpp"],
|
srcs: ["adf_test.cpp"],
|
||||||
|
shared_libs: ["libsync"],
|
||||||
static_libs: ["libadf"],
|
static_libs: ["libadf"],
|
||||||
cflags: ["-Werror"],
|
cflags: ["-Werror"],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include <adf/adf.h>
|
#include <adf/adf.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sync/sync.h>
|
||||||
|
|
||||||
class AdfTest : public testing::Test {
|
class AdfTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
|
|
@ -73,24 +74,6 @@ public:
|
||||||
FAIL(); /* this should never happen */
|
FAIL(); /* this should never happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCheckerboard(void *buf, uint32_t w, uint32_t h, uint32_t pitch) {
|
|
||||||
uint8_t *buf8 = reinterpret_cast<uint8_t *>(buf);
|
|
||||||
for (uint32_t y = 0; y < h / 2; y++) {
|
|
||||||
uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
|
|
||||||
for (uint32_t x = 0; x < w / 2; x++)
|
|
||||||
scanline[x] = 0xFF0000FF;
|
|
||||||
for (uint32_t x = w / 2; x < w; x++)
|
|
||||||
scanline[x] = 0xFF00FFFF;
|
|
||||||
}
|
|
||||||
for (uint32_t y = h / 2; y < h; y++) {
|
|
||||||
uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
|
|
||||||
for (uint32_t x = 0; x < w / 2; x++)
|
|
||||||
scanline[x] = 0xFFFF00FF;
|
|
||||||
for (uint32_t x = w / 2; x < w; x++)
|
|
||||||
scanline[x] = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* various helpers to call ADF and die on failure */
|
/* various helpers to call ADF and die on failure */
|
||||||
|
|
||||||
void getInterfaceData(adf_interface_data &data) {
|
void getInterfaceData(adf_interface_data &data) {
|
||||||
|
|
@ -141,6 +124,42 @@ public:
|
||||||
free(event);
|
free(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawCheckerboard(uint32_t &w, uint32_t &h, uint32_t &format,
|
||||||
|
char format_str[ADF_FORMAT_STR_SIZE], int &buf_fd, uint32_t &offset,
|
||||||
|
uint32_t &pitch) {
|
||||||
|
ASSERT_NO_FATAL_FAILURE(getCurrentMode(w, h));
|
||||||
|
ASSERT_NO_FATAL_FAILURE(get8888Format(format, format_str));
|
||||||
|
|
||||||
|
buf_fd = adf_interface_simple_buffer_alloc(intf, w, h, format, &offset,
|
||||||
|
&pitch);
|
||||||
|
ASSERT_GE(buf_fd, 0) << "allocating " << w << "x" << h << " " <<
|
||||||
|
format_str << " buffer failed: " << strerror(-buf_fd);
|
||||||
|
EXPECT_GE(pitch, w * 4);
|
||||||
|
|
||||||
|
void *mapped = mmap(NULL, pitch * h, PROT_WRITE, MAP_SHARED, buf_fd,
|
||||||
|
offset);
|
||||||
|
ASSERT_NE(mapped, MAP_FAILED) << "mapping " << w << "x" << h << " " <<
|
||||||
|
format_str << " buffer failed: " << strerror(-errno);
|
||||||
|
|
||||||
|
uint8_t *buf8 = static_cast<uint8_t *>(mapped);
|
||||||
|
for (uint32_t y = 0; y < h / 2; y++) {
|
||||||
|
uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
|
||||||
|
for (uint32_t x = 0; x < w / 2; x++)
|
||||||
|
scanline[x] = 0xFF0000FF;
|
||||||
|
for (uint32_t x = w / 2; x < w; x++)
|
||||||
|
scanline[x] = 0xFF00FFFF;
|
||||||
|
}
|
||||||
|
for (uint32_t y = h / 2; y < h; y++) {
|
||||||
|
uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
|
||||||
|
for (uint32_t x = 0; x < w / 2; x++)
|
||||||
|
scanline[x] = 0xFFFF00FF;
|
||||||
|
for (uint32_t x = w / 2; x < w; x++)
|
||||||
|
scanline[x] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(mapped, pitch * h);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
adf_device dev;
|
adf_device dev;
|
||||||
adf_id_t intf_id;
|
adf_id_t intf_id;
|
||||||
|
|
@ -310,27 +329,11 @@ TEST_F(AdfTest, simple_buffer_alloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AdfTest, simple_buffer) {
|
TEST_F(AdfTest, simple_buffer) {
|
||||||
uint32_t w = 0, h = 0;
|
int buf_fd;
|
||||||
ASSERT_NO_FATAL_FAILURE(getCurrentMode(w, h));
|
uint32_t w, h, format, offset, pitch;
|
||||||
|
|
||||||
uint32_t format = 0;
|
|
||||||
char format_str[ADF_FORMAT_STR_SIZE];
|
char format_str[ADF_FORMAT_STR_SIZE];
|
||||||
ASSERT_NO_FATAL_FAILURE(get8888Format(format, format_str));
|
ASSERT_NO_FATAL_FAILURE(drawCheckerboard(w, h, format, format_str,
|
||||||
|
buf_fd, offset, pitch));
|
||||||
uint32_t offset;
|
|
||||||
uint32_t pitch;
|
|
||||||
int buf_fd = adf_interface_simple_buffer_alloc(intf, w, h, format, &offset,
|
|
||||||
&pitch);
|
|
||||||
ASSERT_GE(buf_fd, 0) << "allocating " << w << "x" << h << " " <<
|
|
||||||
format_str << " buffer failed: " << strerror(-buf_fd);
|
|
||||||
EXPECT_GE(pitch, w * 4);
|
|
||||||
|
|
||||||
void *mapped = mmap(NULL, pitch * h, PROT_WRITE, MAP_SHARED, buf_fd,
|
|
||||||
offset);
|
|
||||||
ASSERT_NE(mapped, MAP_FAILED) << "mapping " << w << "x" << h << " " <<
|
|
||||||
format_str << " buffer failed: " << strerror(-errno);
|
|
||||||
drawCheckerboard(mapped, w, h, pitch);
|
|
||||||
munmap(mapped, pitch * h);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(attach());
|
ASSERT_NO_FATAL_FAILURE(attach());
|
||||||
ASSERT_NO_FATAL_FAILURE(blank(DRM_MODE_DPMS_ON));
|
ASSERT_NO_FATAL_FAILURE(blank(DRM_MODE_DPMS_ON));
|
||||||
|
|
@ -342,3 +345,59 @@ TEST_F(AdfTest, simple_buffer) {
|
||||||
format_str << " buffer failed: " << strerror(-release_fence);
|
format_str << " buffer failed: " << strerror(-release_fence);
|
||||||
close(release_fence);
|
close(release_fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AdfTest, simple_buffer_v2) {
|
||||||
|
int buf_fd;
|
||||||
|
uint32_t w, h, format, offset, pitch;
|
||||||
|
char format_str[ADF_FORMAT_STR_SIZE];
|
||||||
|
ASSERT_NO_FATAL_FAILURE(drawCheckerboard(w, h, format, format_str,
|
||||||
|
buf_fd, offset, pitch));
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(attach());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(blank(DRM_MODE_DPMS_ON));
|
||||||
|
|
||||||
|
int config_1_release;
|
||||||
|
int err = adf_interface_simple_post_v2(intf, eng_id, w, h,
|
||||||
|
format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_RELEASE,
|
||||||
|
&config_1_release);
|
||||||
|
if (err == -ENOTTY) {
|
||||||
|
GTEST_LOG_(INFO) << "ADF_SIMPLE_POST_CONFIG_V2 not supported on this kernel";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
|
||||||
|
format_str << " buffer failed: " << strerror(-err);
|
||||||
|
|
||||||
|
err = sync_wait(config_1_release, 1000);
|
||||||
|
ASSERT_EQ(-1, err) <<
|
||||||
|
"waiting for config 1's release fence should not have suceeded";
|
||||||
|
ASSERT_EQ(ETIME, errno) <<
|
||||||
|
"config 1's release fence should have timed out, but failed instead: " <<
|
||||||
|
strerror(errno);
|
||||||
|
|
||||||
|
int config_2_present;
|
||||||
|
err = adf_interface_simple_post_v2(intf, eng_id, w, h,
|
||||||
|
format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_PRESENT,
|
||||||
|
&config_2_present);
|
||||||
|
ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
|
||||||
|
format_str << " buffer failed: " << strerror(-err);
|
||||||
|
|
||||||
|
err = sync_wait(config_2_present, 1000);
|
||||||
|
ASSERT_EQ(0, err) <<
|
||||||
|
"waiting for config 2's present fence failed: " << strerror(errno);
|
||||||
|
err = sync_wait(config_1_release, 0);
|
||||||
|
ASSERT_EQ(0, err) <<
|
||||||
|
"waiting for config 1's release fence failed: " << strerror(errno);
|
||||||
|
close(config_1_release);
|
||||||
|
close(config_2_present);
|
||||||
|
|
||||||
|
int config_3_no_fence;
|
||||||
|
err = adf_interface_simple_post_v2(intf, eng_id, w, h,
|
||||||
|
format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_NONE,
|
||||||
|
&config_3_no_fence);
|
||||||
|
ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
|
||||||
|
format_str << " buffer failed: " << strerror(-err);
|
||||||
|
ASSERT_EQ(-1, config_3_no_fence) <<
|
||||||
|
"fence returned even though the fence type was ADF_COMPLETE_FENCE_NONE";
|
||||||
|
|
||||||
|
close(buf_fd);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue