Files
DroidDeck/tools/linuxfs/preload/kgslpoll.c
T
2026-10-13 21:27:42 -04:00

63 lines
1.7 KiB
C

#define _GNU_SOURCE
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#define KGSL_IOC_TYPE 0x09
#define KGSL_TIMESTAMP_RETIRED 0x00000002
struct kgsl_device_waittimestamp_ctxtid {
unsigned int context_id;
unsigned int timestamp;
unsigned int timeout;
};
struct kgsl_cmdstream_readtimestamp_ctxtid {
unsigned int context_id;
unsigned int type;
unsigned int timestamp;
};
#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID \
_IOW(KGSL_IOC_TYPE, 0x7, struct kgsl_device_waittimestamp_ctxtid)
#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID \
_IOWR(KGSL_IOC_TYPE, 0x16, struct kgsl_cmdstream_readtimestamp_ctxtid)
static int enabled(void) {
static int cached = -1;
const char *off;
if (cached >= 0) return cached;
off = getenv("BL_NO_KGSL_POLL_FIX");
cached = !(off != NULL && off[0] == '1');
return cached;
}
__attribute__((visibility("hidden"))) int bl_kgsl_poll(int (*real)(int, unsigned long, void *),
int fd, unsigned long request, void *arg,
int *rc) {
const struct kgsl_device_waittimestamp_ctxtid *wait = arg;
struct kgsl_cmdstream_readtimestamp_ctxtid read;
int saved = errno;
if (request != IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID || arg == NULL || wait->timeout != 0 ||
!enabled())
return 0;
read.context_id = wait->context_id;
read.type = KGSL_TIMESTAMP_RETIRED;
read.timestamp = 0;
if (real(fd, IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID, &read) != 0) {
errno = saved;
return 0;
}
if ((int32_t)(read.timestamp - wait->timestamp) >= 0) {
errno = saved;
*rc = 0;
} else {
errno = ETIMEDOUT;
*rc = -1;
}
return 1;
}