diff --git a/libgenlock/genlock.cpp b/libgenlock/genlock.cpp index 2aa709a..299161d 100644 --- a/libgenlock/genlock.cpp +++ b/libgenlock/genlock.cpp @@ -66,25 +66,27 @@ namespace { } private_handle_t *hnd = reinterpret_cast(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(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(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(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(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; diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp index 9130b17..654b1d2 100755 --- a/libgralloc/gpu.cpp +++ b/libgralloc/gpu.cpp @@ -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, diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h index e1dc1ef..e33d721 100644 --- a/libgralloc/gralloc_priv.h +++ b/libgralloc/gralloc_priv.h @@ -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