add GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED for explicit synchronization.

Change-Id: I3d78f0517f7eeafc58ec5b0edfc6a04901ad48b2
(cherry picked from commit 35229ceb772a4a3c0a9dbfcb42fdb45344a91b4e)
This commit is contained in:
Jeff Boody 2012-01-19 11:23:16 -07:00 committed by Andrew Sutherland
parent e806dc448b
commit 1077e7cce3
3 changed files with 107 additions and 82 deletions

View File

@ -66,25 +66,27 @@ namespace {
}
private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock has not been created, or has not been attached",
__FUNCTION__);
return GENLOCK_FAILURE;
}
if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock has not been created, or has not been attached",
__FUNCTION__);
return GENLOCK_FAILURE;
}
genlock_lock lock;
lock.op = lockType;
lock.flags = 0;
lock.timeout = timeout;
lock.fd = hnd->genlockHandle;
genlock_lock lock;
lock.op = lockType;
lock.flags = 0;
lock.timeout = timeout;
lock.fd = hnd->genlockHandle;
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_LOCK, &lock)) {
LOGE("%s: GENLOCK_IOC_LOCK failed (lockType0x%x, err=%s fd=%d)", __FUNCTION__,
lockType, strerror(errno), hnd->fd);
if (ETIMEDOUT == errno)
return GENLOCK_TIMEDOUT;
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_LOCK, &lock)) {
LOGE("%s: GENLOCK_IOC_LOCK failed (lockType0x%x, err=%s fd=%d)", __FUNCTION__,
lockType, strerror(errno), hnd->fd);
if (ETIMEDOUT == errno)
return GENLOCK_TIMEDOUT;
return GENLOCK_FAILURE;
return GENLOCK_FAILURE;
}
}
return GENLOCK_NO_ERROR;
}
@ -121,36 +123,40 @@ genlock_status_t genlock_create_lock(native_handle_t *buffer_handle)
private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
#ifdef USE_GENLOCK
// Open the genlock device
int fd = open(GENLOCK_DEVICE, O_RDWR);
if (fd < 0) {
LOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
strerror(errno));
return GENLOCK_FAILURE;
}
if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
// Open the genlock device
int fd = open(GENLOCK_DEVICE, O_RDWR);
if (fd < 0) {
LOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
strerror(errno));
return GENLOCK_FAILURE;
}
// Create a new lock
genlock_lock lock;
if (ioctl(fd, GENLOCK_IOC_NEW, NULL)) {
LOGE("%s: GENLOCK_IOC_NEW failed (error=%s)", __FUNCTION__,
strerror(errno));
close_genlock_fd_and_handle(fd, lock.fd);
ret = GENLOCK_FAILURE;
}
// Export the lock for other processes to be able to use it.
if (GENLOCK_FAILURE != ret) {
if (ioctl(fd, GENLOCK_IOC_EXPORT, &lock)) {
LOGE("%s: GENLOCK_IOC_EXPORT failed (error=%s)", __FUNCTION__,
// Create a new lock
genlock_lock lock;
if (ioctl(fd, GENLOCK_IOC_NEW, NULL)) {
LOGE("%s: GENLOCK_IOC_NEW failed (error=%s)", __FUNCTION__,
strerror(errno));
close_genlock_fd_and_handle(fd, lock.fd);
ret = GENLOCK_FAILURE;
}
}
// Store the lock params in the handle.
hnd->genlockPrivFd = fd;
hnd->genlockHandle = lock.fd;
// Export the lock for other processes to be able to use it.
if (GENLOCK_FAILURE != ret) {
if (ioctl(fd, GENLOCK_IOC_EXPORT, &lock)) {
LOGE("%s: GENLOCK_IOC_EXPORT failed (error=%s)", __FUNCTION__,
strerror(errno));
close_genlock_fd_and_handle(fd, lock.fd);
ret = GENLOCK_FAILURE;
}
}
// Store the lock params in the handle.
hnd->genlockPrivFd = fd;
hnd->genlockHandle = lock.fd;
} else {
hnd->genlockHandle = 0;
}
#else
hnd->genlockHandle = 0;
#endif
@ -174,19 +180,21 @@ genlock_status_t genlock_release_lock(native_handle_t *buffer_handle)
}
private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock is invalid", __FUNCTION__);
return GENLOCK_FAILURE;
}
if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock is invalid", __FUNCTION__);
return GENLOCK_FAILURE;
}
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_RELEASE, NULL)) {
LOGE("%s: GENLOCK_IOC_RELEASE failed (err=%s)", __FUNCTION__,
strerror(errno));
ret = GENLOCK_FAILURE;
}
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_RELEASE, NULL)) {
LOGE("%s: GENLOCK_IOC_RELEASE failed (err=%s)", __FUNCTION__,
strerror(errno));
ret = GENLOCK_FAILURE;
}
// Close the fd and reset the parameters.
close_genlock_fd_and_handle(hnd->genlockPrivFd, hnd->genlockHandle);
// Close the fd and reset the parameters.
close_genlock_fd_and_handle(hnd->genlockPrivFd, hnd->genlockHandle);
}
#endif
return ret;
}
@ -207,27 +215,29 @@ genlock_status_t genlock_attach_lock(native_handle_t *buffer_handle)
return GENLOCK_FAILURE;
}
// Open the genlock device
int fd = open(GENLOCK_DEVICE, O_RDWR);
if (fd < 0) {
LOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
strerror(errno));
return GENLOCK_FAILURE;
}
// Attach the local handle to an existing lock
private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
genlock_lock lock;
lock.fd = hnd->genlockHandle;
if (ioctl(fd, GENLOCK_IOC_ATTACH, &lock)) {
LOGE("%s: GENLOCK_IOC_ATTACH failed (err=%s)", __FUNCTION__,
strerror(errno));
close_genlock_fd_and_handle(fd, lock.fd);
ret = GENLOCK_FAILURE;
}
if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
// Open the genlock device
int fd = open(GENLOCK_DEVICE, O_RDWR);
if (fd < 0) {
LOGE("%s: open genlock device failed (err=%s)", __FUNCTION__,
strerror(errno));
return GENLOCK_FAILURE;
}
// Store the relavant information in the handle
hnd->genlockPrivFd = fd;
// Attach the local handle to an existing lock
genlock_lock lock;
lock.fd = hnd->genlockHandle;
if (ioctl(fd, GENLOCK_IOC_ATTACH, &lock)) {
LOGE("%s: GENLOCK_IOC_ATTACH failed (err=%s)", __FUNCTION__,
strerror(errno));
close_genlock_fd_and_handle(fd, lock.fd);
ret = GENLOCK_FAILURE;
}
// Store the relavant information in the handle
hnd->genlockPrivFd = fd;
}
#endif
return ret;
}
@ -299,20 +309,22 @@ genlock_status_t genlock_wait(native_handle_t *buffer_handle, int timeout) {
}
private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock is invalid", __FUNCTION__);
return GENLOCK_FAILURE;
}
if ((hnd->flags & private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED) == 0) {
if (hnd->genlockPrivFd < 0) {
LOGE("%s: the lock is invalid", __FUNCTION__);
return GENLOCK_FAILURE;
}
if (0 == timeout)
LOGW("%s: timeout = 0", __FUNCTION__);
if (0 == timeout)
LOGW("%s: timeout = 0", __FUNCTION__);
genlock_lock lock;
lock.fd = hnd->genlockHandle;
lock.timeout = timeout;
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_WAIT, &lock)) {
LOGE("%s: GENLOCK_IOC_WAIT failed (err=%s)", __FUNCTION__, strerror(errno));
return GENLOCK_FAILURE;
genlock_lock lock;
lock.fd = hnd->genlockHandle;
lock.timeout = timeout;
if (ioctl(hnd->genlockPrivFd, GENLOCK_IOC_WAIT, &lock)) {
LOGE("%s: GENLOCK_IOC_WAIT failed (err=%s)", __FUNCTION__, strerror(errno));
return GENLOCK_FAILURE;
}
}
#endif
return GENLOCK_NO_ERROR;

View File

@ -160,6 +160,10 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage,
data.pHandle = (unsigned int) pHandle;
err = mAllocCtrl->allocate(data, usage, compositionType);
if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
}
if (err == 0) {
flags |= data.allocType;
private_handle_t* hnd = new private_handle_t(data.fd, size, flags,

View File

@ -66,6 +66,14 @@ enum {
* If not set, the system heap is assumed to be coming from ashmem
*/
GRALLOC_USAGE_PRIVATE_ION = 0x00020000,
/* This flag can be set to disable genlock synchronization
* for the gralloc buffer. If this flag is set the caller
* is required to perform explicit synchronization.
* WARNING - flag is outside the standard PRIVATE region
* and may need to be moved if the gralloc API changes
*/
GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED = 0X00040000,
};
enum {
@ -303,6 +311,7 @@ struct private_handle_t {
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
PRIV_FLAGS_HWC_LOCK = 0x00000200, // Set by HWC when storing the handle
PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800, // For explicit synchronization
};
// file-descriptors