summaryrefslogtreecommitdiffstats
path: root/modules/gralloc/mapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gralloc/mapper.cpp')
-rw-r--r--modules/gralloc/mapper.cpp171
1 files changed, 29 insertions, 142 deletions
diff --git a/modules/gralloc/mapper.cpp b/modules/gralloc/mapper.cpp
index e2caf79..33d0958 100644
--- a/modules/gralloc/mapper.cpp
+++ b/modules/gralloc/mapper.cpp
@@ -33,9 +33,6 @@
#include "gralloc_priv.h"
-// we need this for now because pmem cannot mmap at an offset
-#define PMEM_HACK 1
-
/* desktop Linux needs a little help with gettid() */
#if defined(ARCH_X86) && !defined(HAVE_ANDROID_OS)
#define __KERNEL__
@@ -53,9 +50,6 @@ static int gralloc_map(gralloc_module_t const* module,
private_handle_t* hnd = (private_handle_t*)handle;
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
size_t size = hnd->size;
-#if PMEM_HACK
- size += hnd->offset;
-#endif
void* mappedAddress = mmap(0, size,
PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
if (mappedAddress == MAP_FAILED) {
@@ -63,7 +57,7 @@ static int gralloc_map(gralloc_module_t const* module,
return -errno;
}
hnd->base = intptr_t(mappedAddress) + hnd->offset;
- //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
+ //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
// hnd->fd, hnd->offset, hnd->size, mappedAddress);
}
*vaddr = (void*)hnd->base;
@@ -77,10 +71,6 @@ static int gralloc_unmap(gralloc_module_t const* module,
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
void* base = (void*)hnd->base;
size_t size = hnd->size;
-#if PMEM_HACK
- base = (void*)(intptr_t(base) - hnd->offset);
- size += hnd->offset;
-#endif
//LOGD("unmapping from %p, size=%d", base, size);
if (munmap(base, size) < 0) {
LOGE("Could not unmap %s", strerror(errno));
@@ -102,23 +92,14 @@ int gralloc_register_buffer(gralloc_module_t const* module,
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
- // In this implementation, we don't need to do anything here
-
- /* NOTE: we need to initialize the buffer as not mapped/not locked
- * because it shouldn't when this function is called the first time
- * in a new process. Ideally these flags shouldn't be part of the
- * handle, but instead maintained in the kernel or at least
- * out-of-line
- */
-
// if this handle was created in this process, then we keep it as is.
+ int err = 0;
private_handle_t* hnd = (private_handle_t*)handle;
if (hnd->pid != getpid()) {
- hnd->base = 0;
- hnd->lockState = 0;
- hnd->writeOwner = 0;
+ void *vaddr;
+ err = gralloc_map(module, handle, &vaddr);
}
- return 0;
+ return err;
}
int gralloc_unregister_buffer(gralloc_module_t const* module,
@@ -127,52 +108,29 @@ int gralloc_unregister_buffer(gralloc_module_t const* module,
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
- /*
- * If the buffer has been mapped during a lock operation, it's time
- * to un-map it. It's an error to be here with a locked buffer.
- * NOTE: the framebuffer is handled differently and is never unmapped.
- */
-
- 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
+ private_handle_t* hnd = (private_handle_t*)handle;
if (hnd->pid != getpid()) {
- if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) {
+ if (hnd->base) {
gralloc_unmap(module, handle);
}
- hnd->base = 0;
- hnd->lockState = 0;
- hnd->writeOwner = 0;
}
return 0;
}
-int terminateBuffer(gralloc_module_t const* module,
+int mapBuffer(gralloc_module_t const* module,
private_handle_t* hnd)
{
- /*
- * If the buffer has been mapped during a lock operation, it's time
- * to un-map it. It's an error to be here with a locked buffer.
- */
+ void* vaddr;
+ return gralloc_map(module, hnd, &vaddr);
+}
- 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) {
+int terminateBuffer(gralloc_module_t const* module,
+ private_handle_t* hnd)
+{
+ if (hnd->base) {
// this buffer was mapped, unmap it now
- if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) &&
- (hnd->pid == getpid())) {
- // ... unless it's a "master" pmem buffer, that is a buffer
- // mapped in the process it's been allocated.
- // (see gralloc_alloc_buffer())
- } else {
- gralloc_unmap(module, hnd);
- }
+ gralloc_unmap(module, hnd);
}
return 0;
@@ -183,100 +141,29 @@ int gralloc_lock(gralloc_module_t const* module,
int l, int t, int w, int h,
void** vaddr)
{
+ // this is called when a buffer is being locked for software
+ // access. in thin implementation we have nothing to do since
+ // not synchronization with the h/w is needed.
+ // typically this is used to wait for the h/w to finish with
+ // this buffer if relevant. the data cache may need to be
+ // flushed or invalidated depending on the usage bits and the
+ // hardware.
+
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
- 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 (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
- if (!(current_value & private_handle_t::LOCK_STATE_MAPPED)) {
- // 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));
- }
- }
- pthread_mutex_unlock(lock);
- }
- *vaddr = (void*)hnd->base;
- }
-
- return err;
+ *vaddr = (void*)hnd->base;
+ return 0;
}
int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle)
{
+ // we're done with a software buffer. nothing to do in this
+ // implementation. typically this is used to flush the data cache.
+
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
-
- private_handle_t* hnd = (private_handle_t*)handle;
- int32_t current_value, new_value;
-
- 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);
- return -EINVAL;
- }
-
- new_value--;
-
- } while (android_atomic_cmpxchg(current_value, new_value,
- (volatile int32_t*)&hnd->lockState));
-
return 0;
}