From 1e746398262084c4d9edf5d34670cfe05189cc20 Mon Sep 17 00:00:00 2001 From: Naomi Luis Date: Sun, 20 Nov 2011 00:40:05 -0800 Subject: [PATCH] libgralloc: Invoke genlock during gralloc_lock/gralloc_unlock gralloc_lock and gralloc_unlock invokes genlock to perform the buffer locking operation. Remove unused gralloc handle variables. Change-Id: I5283613c5f67f708123916653af1b2d1ec155577 --- libgralloc/gpu.cpp | 1 - libgralloc/gralloc_priv.h | 15 ++--- libgralloc/mapper.cpp | 131 +++++++++++--------------------------- 3 files changed, 42 insertions(+), 105 deletions(-) diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp index da9f4c1..014c54b 100755 --- a/libgralloc/gpu.cpp +++ b/libgralloc/gpu.cpp @@ -172,7 +172,6 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, hnd->offset = data.offset; hnd->base = int(data.base) + data.offset; - hnd->lockState = private_handle_t::LOCK_STATE_MAPPED; *pHandle = hnd; } diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h index 1d990ba..ced31f6 100644 --- a/libgralloc/gralloc_priv.h +++ b/libgralloc/gralloc_priv.h @@ -278,12 +278,7 @@ struct private_handle_t { PRIV_FLAGS_USES_ASHMEM = 0x00000010, PRIV_FLAGS_NEEDS_FLUSH = 0x00000020, PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040, - }; - - enum { - LOCK_STATE_WRITE = 1<<31, - LOCK_STATE_MAPPED = 1<<30, - LOCK_STATE_READ_MASK = 0x3FFFFFFF + PRIV_FLAGS_SW_LOCK = 0x00000080, }; // file-descriptors @@ -298,8 +293,6 @@ struct private_handle_t { // FIXME: the attributes below should be out-of-line int base; - int lockState; - int writeOwner; int gpuaddr; // The gpu address mapped into the mmu. If using ashmem, set to 0 They don't care int pid; int format; @@ -308,14 +301,14 @@ struct private_handle_t { int genlockPrivFd; // local fd of the genlock device. #ifdef __cplusplus - static const int sNumInts = 14; + static const int sNumInts = 12; static const int sNumFds = 2; static const int sMagic = 'gmsm'; private_handle_t(int fd, int size, int flags, int bufferType, int format, int width, int height) : fd(fd), genlockHandle(-1), magic(sMagic), flags(flags), size(size), offset(0), - bufferType(bufferType), base(0), lockState(0), writeOwner(0), gpuaddr(0), - pid(getpid()), format(format), width(width), height(height), genlockPrivFd(-1) + bufferType(bufferType), base(0), gpuaddr(0), pid(getpid()), format(format), + width(width), height(height), genlockPrivFd(-1) { version = sizeof(native_handle); numInts = sNumInts; diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp index da1b2fa..2c01b15 100755 --- a/libgralloc/mapper.cpp +++ b/libgralloc/mapper.cpp @@ -140,8 +140,6 @@ int gralloc_register_buffer(gralloc_module_t const* module, return err; } - hnd->lockState = 0; - hnd->writeOwner = 0; // Reset the genlock private fd flag in the handle hnd->genlockPrivFd = -1; @@ -178,19 +176,12 @@ int gralloc_unregister_buffer(gralloc_module_t const* module, private_handle_t* hnd = (private_handle_t*)handle; - LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, - "[unregister] handle %p still locked (state=%08x)", - hnd, hnd->lockState); - // never unmap buffers that were created in this process if (hnd->pid != getpid()) { - if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) { + if (hnd->base != 0) { gralloc_unmap(module, handle); } hnd->base = 0; - hnd->lockState = 0; - hnd->writeOwner = 0; - // Release the genlock if (-1 != hnd->genlockHandle) { return genlock_release_lock((native_handle_t *)handle); @@ -210,11 +201,7 @@ int terminateBuffer(gralloc_module_t const* module, * to un-map it. It's an error to be here with a locked buffer. */ - LOGE_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, - "[terminate] handle %p still locked (state=%08x)", - hnd, hnd->lockState); - - if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) { + if (hnd->base != 0) { // this buffer was mapped, unmap it now if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM | private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP | @@ -245,70 +232,43 @@ int gralloc_lock(gralloc_module_t const* module, int err = 0; private_handle_t* hnd = (private_handle_t*)handle; - int32_t current_value, new_value; - int retry; - - do { - current_value = hnd->lockState; - new_value = current_value; - - if (current_value & private_handle_t::LOCK_STATE_WRITE) { - // already locked for write - LOGE("handle %p already locked for write", handle); - return -EBUSY; - } else if (current_value & private_handle_t::LOCK_STATE_READ_MASK) { - // already locked for read - if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) { - LOGE("handle %p already locked for read", handle); - return -EBUSY; - } else { - // this is not an error - //LOGD("%p already locked for read... count = %d", - // handle, (current_value & ~(1<<31))); - } - } - - // not currently locked - if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) { - // locking for write - new_value |= private_handle_t::LOCK_STATE_WRITE; - } - new_value++; - - retry = android_atomic_cmpxchg(current_value, new_value, - (volatile int32_t*)&hnd->lockState); - } while (retry); - - if (new_value & private_handle_t::LOCK_STATE_WRITE) { - // locking for write, store the tid - hnd->writeOwner = gettid(); - } - - // if requesting sw write for non-framebuffer handles, flag for - // flushing at unlock - - if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && - !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { - hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; - } - if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { - if (!(current_value & private_handle_t::LOCK_STATE_MAPPED)) { + if (hnd->base == 0) { // we need to map for real pthread_mutex_t* const lock = &sMapLock; pthread_mutex_lock(lock); - if (!(hnd->lockState & private_handle_t::LOCK_STATE_MAPPED)) { - err = gralloc_map(module, handle, vaddr); - if (err == 0) { - android_atomic_or(private_handle_t::LOCK_STATE_MAPPED, - (volatile int32_t*)&(hnd->lockState)); - } - } + err = gralloc_map(module, handle, vaddr); pthread_mutex_unlock(lock); } *vaddr = (void*)hnd->base; - } + // Lock the buffer for read/write operation as specified. Write lock + // has a higher priority over read lock. + int lockType = 0; + if (usage & GRALLOC_USAGE_SW_WRITE_MASK) { + lockType = GENLOCK_WRITE_LOCK; + } else if (usage & GRALLOC_USAGE_SW_READ_MASK) { + lockType = GENLOCK_READ_LOCK; + } + + int timeout = GENLOCK_MAX_TIMEOUT; + if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t *)handle, + (genlock_lock_type)lockType, + timeout)) { + LOGE("%s: genlock_lock_buffer (lockType=0x%x) failed", __FUNCTION__, + lockType); + return -EINVAL; + } else { + // Mark this buffer as locked for SW read/write operation. + hnd->flags |= private_handle_t::PRIV_FLAGS_SW_LOCK; + } + + if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) && + !(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { + // Mark the buffer to be flushed after cpu read/write + hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; + } + } return err; } @@ -319,7 +279,6 @@ int gralloc_unlock(gralloc_module_t const* module, return -EINVAL; private_handle_t* hnd = (private_handle_t*)handle; - int32_t current_value, new_value; if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { int err; @@ -331,28 +290,14 @@ int gralloc_unlock(gralloc_module_t const* module, hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } - do { - current_value = hnd->lockState; - new_value = current_value; - - if (current_value & private_handle_t::LOCK_STATE_WRITE) { - // locked for write - if (hnd->writeOwner == gettid()) { - hnd->writeOwner = 0; - new_value &= ~private_handle_t::LOCK_STATE_WRITE; - } - } - - if ((new_value & private_handle_t::LOCK_STATE_READ_MASK) == 0) { - LOGE("handle %p not locked", handle); + if ((hnd->flags & private_handle_t::PRIV_FLAGS_SW_LOCK)) { + // Unlock the buffer. + if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *)handle)) { + LOGE("%s: genlock_unlock_buffer failed", __FUNCTION__); return -EINVAL; - } - - new_value--; - - } while (android_atomic_cmpxchg(current_value, new_value, - (volatile int32_t*)&hnd->lockState)); - + } else + hnd->flags &= ~private_handle_t::PRIV_FLAGS_SW_LOCK; + } return 0; }