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
This commit is contained in:
Naomi Luis 2011-11-20 00:40:05 -08:00
parent 09367ef6e8
commit 1e74639826
3 changed files with 42 additions and 105 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}