summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/gralloc/Android.mk1
-rw-r--r--modules/gralloc/allocator.cpp165
-rw-r--r--modules/gralloc/allocator.h129
-rw-r--r--modules/gralloc/framebuffer.cpp13
-rw-r--r--modules/gralloc/gr.h1
-rw-r--r--modules/gralloc/gralloc.cpp180
-rw-r--r--modules/gralloc/gralloc_priv.h22
-rw-r--r--modules/gralloc/mapper.cpp171
8 files changed, 45 insertions, 637 deletions
diff --git a/modules/gralloc/Android.mk b/modules/gralloc/Android.mk
index 8f044c5..8946fac 100644
--- a/modules/gralloc/Android.mk
+++ b/modules/gralloc/Android.mk
@@ -23,7 +23,6 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_SRC_FILES := \
- allocator.cpp \
gralloc.cpp \
framebuffer.cpp \
mapper.cpp
diff --git a/modules/gralloc/allocator.cpp b/modules/gralloc/allocator.cpp
deleted file mode 100644
index e7645b1..0000000
--- a/modules/gralloc/allocator.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cutils/log.h>
-
-#include "allocator.h"
-
-
-// align all the memory blocks on a cache-line boundary
-const int SimpleBestFitAllocator::kMemoryAlign = 32;
-
-SimpleBestFitAllocator::SimpleBestFitAllocator()
- : mHeapSize(0)
-{
-}
-
-SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
- : mHeapSize(0)
-{
- setSize(size);
-}
-
-SimpleBestFitAllocator::~SimpleBestFitAllocator()
-{
- while(!mList.isEmpty()) {
- delete mList.remove(mList.head());
- }
-}
-
-ssize_t SimpleBestFitAllocator::setSize(size_t size)
-{
- Locker::Autolock _l(mLock);
- if (mHeapSize != 0) return -EINVAL;
- size_t pagesize = getpagesize();
- mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
- chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
- mList.insertHead(node);
- return size;
-}
-
-
-size_t SimpleBestFitAllocator::size() const
-{
- return mHeapSize;
-}
-
-ssize_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
-{
- Locker::Autolock _l(mLock);
- if (mHeapSize == 0) return -EINVAL;
- ssize_t offset = alloc(size, flags);
- return offset;
-}
-
-ssize_t SimpleBestFitAllocator::deallocate(size_t offset)
-{
- Locker::Autolock _l(mLock);
- if (mHeapSize == 0) return -EINVAL;
- chunk_t const * const freed = dealloc(offset);
- if (freed) {
- return 0;
- }
- return -ENOENT;
-}
-
-ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
-{
- if (size == 0) {
- return 0;
- }
- size = (size + kMemoryAlign-1) / kMemoryAlign;
- chunk_t* free_chunk = 0;
- chunk_t* cur = mList.head();
-
- size_t pagesize = getpagesize();
- while (cur) {
- int extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
-
- // best fit
- if (cur->free && (cur->size >= (size+extra))) {
- if ((!free_chunk) || (cur->size < free_chunk->size)) {
- free_chunk = cur;
- }
- if (cur->size == size) {
- break;
- }
- }
- cur = cur->next;
- }
-
- if (free_chunk) {
- const size_t free_size = free_chunk->size;
- free_chunk->free = 0;
- free_chunk->size = size;
- if (free_size > size) {
- int extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
- if (extra) {
- chunk_t* split = new chunk_t(free_chunk->start, extra);
- free_chunk->start += extra;
- mList.insertBefore(free_chunk, split);
- }
-
- LOGE_IF(((free_chunk->start*kMemoryAlign)&(pagesize-1)),
- "page is not aligned!!!");
-
- const ssize_t tail_free = free_size - (size+extra);
- if (tail_free > 0) {
- chunk_t* split = new chunk_t(
- free_chunk->start + free_chunk->size, tail_free);
- mList.insertAfter(free_chunk, split);
- }
- }
- return (free_chunk->start)*kMemoryAlign;
- }
- return -ENOMEM;
-}
-
-SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
-{
- start = start / kMemoryAlign;
- chunk_t* cur = mList.head();
- while (cur) {
- if (cur->start == start) {
- LOG_FATAL_IF(cur->free,
- "block at offset 0x%08lX of size 0x%08lX already freed",
- cur->start*kMemoryAlign, cur->size*kMemoryAlign);
-
- // merge freed blocks together
- chunk_t* freed = cur;
- cur->free = 1;
- do {
- chunk_t* const p = cur->prev;
- chunk_t* const n = cur->next;
- if (p && (p->free || !cur->size)) {
- freed = p;
- p->size += cur->size;
- mList.remove(cur);
- delete cur;
- }
- cur = n;
- } while (cur && cur->free);
-
- LOG_FATAL_IF(!freed->free,
- "freed block at offset 0x%08lX of size 0x%08lX is not free!",
- freed->start * kMemoryAlign, freed->size * kMemoryAlign);
-
- return freed;
- }
- cur = cur->next;
- }
- return 0;
-}
diff --git a/modules/gralloc/allocator.h b/modules/gralloc/allocator.h
deleted file mode 100644
index b0d89e9..0000000
--- a/modules/gralloc/allocator.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef GRALLOC_ALLOCATOR_H_
-#define GRALLOC_ALLOCATOR_H_
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "gr.h"
-
-// ----------------------------------------------------------------------------
-
-/*
- * A simple templatized doubly linked-list implementation
- */
-
-template <typename NODE>
-class LinkedList
-{
- NODE* mFirst;
- NODE* mLast;
-
-public:
- LinkedList() : mFirst(0), mLast(0) { }
- bool isEmpty() const { return mFirst == 0; }
- NODE const* head() const { return mFirst; }
- NODE* head() { return mFirst; }
- NODE const* tail() const { return mLast; }
- NODE* tail() { return mLast; }
-
- void insertAfter(NODE* node, NODE* newNode) {
- newNode->prev = node;
- newNode->next = node->next;
- if (node->next == 0) mLast = newNode;
- else node->next->prev = newNode;
- node->next = newNode;
- }
-
- void insertBefore(NODE* node, NODE* newNode) {
- newNode->prev = node->prev;
- newNode->next = node;
- if (node->prev == 0) mFirst = newNode;
- else node->prev->next = newNode;
- node->prev = newNode;
- }
-
- void insertHead(NODE* newNode) {
- if (mFirst == 0) {
- mFirst = mLast = newNode;
- newNode->prev = newNode->next = 0;
- } else {
- newNode->prev = 0;
- newNode->next = mFirst;
- mFirst->prev = newNode;
- mFirst = newNode;
- }
- }
-
- void insertTail(NODE* newNode) {
- if (mLast == 0) {
- insertHead(newNode);
- } else {
- newNode->prev = mLast;
- newNode->next = 0;
- mLast->next = newNode;
- mLast = newNode;
- }
- }
-
- NODE* remove(NODE* node) {
- if (node->prev == 0) mFirst = node->next;
- else node->prev->next = node->next;
- if (node->next == 0) mLast = node->prev;
- else node->next->prev = node->prev;
- return node;
- }
-};
-
-class SimpleBestFitAllocator
-{
-public:
-
- SimpleBestFitAllocator();
- SimpleBestFitAllocator(size_t size);
- ~SimpleBestFitAllocator();
-
- ssize_t setSize(size_t size);
-
- ssize_t allocate(size_t size, uint32_t flags = 0);
- ssize_t deallocate(size_t offset);
- size_t size() const;
-
-private:
- struct chunk_t {
- chunk_t(size_t start, size_t size)
- : start(start), size(size), free(1), prev(0), next(0) {
- }
- size_t start;
- size_t size : 28;
- int free : 4;
- mutable chunk_t* prev;
- mutable chunk_t* next;
- };
-
- ssize_t alloc(size_t size, uint32_t flags);
- chunk_t* dealloc(size_t start);
-
- static const int kMemoryAlign;
- mutable Locker mLock;
- LinkedList<chunk_t> mList;
- size_t mHeapSize;
-};
-
-#endif /* GRALLOC_ALLOCATOR_H_ */
diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp
index 7d2b582..0195103 100644
--- a/modules/gralloc/framebuffer.cpp
+++ b/modules/gralloc/framebuffer.cpp
@@ -92,18 +92,8 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
-
- if (m->currentBuffer) {
- m->base.unlock(&m->base, m->currentBuffer);
- m->currentBuffer = 0;
- }
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
-
- m->base.lock(&m->base, buffer,
- private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
- 0, 0, m->info.xres, m->info.yres, NULL);
-
const size_t offset = hnd->base - m->framebuffer->base;
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = offset / m->finfo.line_length;
@@ -292,8 +282,7 @@ int mapFrameBufferLocked(struct private_module_t* module)
int err;
size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual);
- module->framebuffer = new private_handle_t(dup(fd), fbSize,
- private_handle_t::PRIV_FLAGS_USES_PMEM);
+ module->framebuffer = new private_handle_t(dup(fd), fbSize, 0);
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
diff --git a/modules/gralloc/gr.h b/modules/gralloc/gr.h
index 1775bfa..3a43aa7 100644
--- a/modules/gralloc/gr.h
+++ b/modules/gralloc/gr.h
@@ -42,6 +42,7 @@ inline size_t roundUpToPageSize(size_t x) {
int mapFrameBufferLocked(struct private_module_t* module);
int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
+int mapBuffer(gralloc_module_t const* module, private_handle_t* hnd);
/*****************************************************************************/
diff --git a/modules/gralloc/gralloc.cpp b/modules/gralloc/gralloc.cpp
index 404d8b8..a9ae784 100644
--- a/modules/gralloc/gralloc.cpp
+++ b/modules/gralloc/gralloc.cpp
@@ -35,15 +35,7 @@
#include <hardware/gralloc.h>
#include "gralloc_priv.h"
-#include "allocator.h"
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-/*****************************************************************************/
-
-static SimpleBestFitAllocator sAllocator;
+#include "gr.h"
/*****************************************************************************/
@@ -105,8 +97,6 @@ struct private_module_t HAL_MODULE_INFO_SYM = {
bufferMask: 0,
lock: PTHREAD_MUTEX_INITIALIZER,
currentBuffer: 0,
- pmem_master: -1,
- pmem_master_base: 0
};
/*****************************************************************************/
@@ -146,7 +136,6 @@ static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,
// create a "fake" handles for it
intptr_t vaddr = intptr_t(m->framebuffer->base);
private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,
- private_handle_t::PRIV_FLAGS_USES_PMEM |
private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
// find a free slot
@@ -176,160 +165,28 @@ static int gralloc_alloc_framebuffer(alloc_device_t* dev,
return err;
}
-static int init_pmem_area_locked(private_module_t* m)
-{
- int err = 0;
-#if HAVE_ANDROID_OS // should probably define HAVE_PMEM somewhere
- int master_fd = open("/dev/pmem", O_RDWR, 0);
- if (master_fd >= 0) {
-
- size_t size;
- pmem_region region;
- if (ioctl(master_fd, PMEM_GET_TOTAL_SIZE, &region) < 0) {
- LOGE("PMEM_GET_TOTAL_SIZE failed, limp mode");
- size = 8<<20; // 8 MiB
- } else {
- size = region.len;
- }
- sAllocator.setSize(size);
-
- void* base = mmap(0, size,
- PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0);
- if (base == MAP_FAILED) {
- err = -errno;
- base = 0;
- close(master_fd);
- master_fd = -1;
- }
- m->pmem_master = master_fd;
- m->pmem_master_base = base;
- } else {
- err = -errno;
- }
- return err;
-#else
- return -1;
-#endif
-}
-
-static int init_pmem_area(private_module_t* m)
-{
- pthread_mutex_lock(&m->lock);
- int err = m->pmem_master;
- if (err == -1) {
- // first time, try to initialize pmem
- err = init_pmem_area_locked(m);
- if (err) {
- m->pmem_master = err;
- }
- } else if (err < 0) {
- // pmem couldn't be initialized, never use it
- } else {
- // pmem OK
- err = 0;
- }
- pthread_mutex_unlock(&m->lock);
- return err;
-}
-
static int gralloc_alloc_buffer(alloc_device_t* dev,
size_t size, int usage, buffer_handle_t* pHandle)
{
int err = 0;
- int flags = 0;
-
int fd = -1;
- void* base = 0;
- int offset = 0;
- int lockState = 0;
size = roundUpToPageSize(size);
-#if HAVE_ANDROID_OS // should probably define HAVE_PMEM somewhere
-
- if (usage & GRALLOC_USAGE_HW_TEXTURE) {
- // enable pmem in that case, so our software GL can fallback to
- // the copybit module.
- flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
- }
-
- if (usage & GRALLOC_USAGE_HW_2D) {
- flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
- }
-
- if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0) {
-try_ashmem:
- fd = ashmem_create_region("gralloc-buffer", size);
- if (fd < 0) {
- LOGE("couldn't create ashmem (%s)", strerror(-errno));
- err = -errno;
- }
- } else {
- private_module_t* m = reinterpret_cast<private_module_t*>(
- dev->common.module);
-
- err = init_pmem_area(m);
- if (err == 0) {
- // PMEM buffers are always mmapped
- base = m->pmem_master_base;
- lockState |= private_handle_t::LOCK_STATE_MAPPED;
-
- offset = sAllocator.allocate(size);
- if (offset < 0) {
- // no more pmem memory
- err = -ENOMEM;
- } else {
- struct pmem_region sub = { offset, size };
-
- // now create the "sub-heap"
- fd = open("/dev/pmem", O_RDWR, 0);
- err = fd < 0 ? fd : 0;
-
- // and connect to it
- if (err == 0)
- err = ioctl(fd, PMEM_CONNECT, m->pmem_master);
-
- // and make it available to the client process
- if (err == 0)
- err = ioctl(fd, PMEM_MAP, &sub);
-
- if (err < 0) {
- err = -errno;
- close(fd);
- sAllocator.deallocate(offset);
- fd = -1;
- }
- //LOGD_IF(!err, "allocating pmem size=%d, offset=%d", size, offset);
- memset((char*)base + offset, 0, size);
- }
- } else {
- if ((usage & GRALLOC_USAGE_HW_2D) == 0) {
- // the caller didn't request PMEM, so we can try something else
- flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
- err = 0;
- goto try_ashmem;
- } else {
- LOGE("couldn't open pmem (%s)", strerror(-errno));
- }
- }
- }
-
-#else // HAVE_ANDROID_OS
-
- fd = ashmem_create_region("Buffer", size);
+ fd = ashmem_create_region("gralloc-buffer", size);
if (fd < 0) {
LOGE("couldn't create ashmem (%s)", strerror(-errno));
err = -errno;
}
-#endif // HAVE_ANDROID_OS
-
if (err == 0) {
- private_handle_t* hnd = new private_handle_t(fd, size, flags);
- hnd->offset = offset;
- hnd->base = int(base)+offset;
- hnd->lockState = lockState;
- *pHandle = hnd;
+ private_handle_t* hnd = new private_handle_t(fd, size, 0);
+ gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
+ dev->common.module);
+ err = mapBuffer(module, hnd);
+ if (err == 0) {
+ *pHandle = hnd;
+ }
}
LOGE_IF(err, "gralloc failed err=%s", strerror(-err));
@@ -348,7 +205,7 @@ static int gralloc_alloc(alloc_device_t* dev,
size_t size, stride;
if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP ||
- format == HAL_PIXEL_FORMAT_YCbCr_422_SP)
+ format == HAL_PIXEL_FORMAT_YCbCr_422_SP)
{
// FIXME: there is no way to return the vstride
int vstride;
@@ -419,23 +276,6 @@ static int gralloc_free(alloc_device_t* dev,
int index = (hnd->base - m->framebuffer->base) / bufferSize;
m->bufferMask &= ~(1<<index);
} else {
-#if HAVE_ANDROID_OS
- if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
- if (hnd->fd >= 0) {
- struct pmem_region sub = { hnd->offset, hnd->size };
- int err = ioctl(hnd->fd, PMEM_UNMAP, &sub);
- LOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
- "fd=%d, sub.offset=%lu, sub.size=%lu",
- strerror(errno), hnd->fd, hnd->offset, hnd->size);
- if (err == 0) {
- // we can't deallocate the memory in case of UNMAP failure
- // because it would give that process access to someone else's
- // surfaces, which would be a security breach.
- sAllocator.deallocate(hnd->offset);
- }
- }
- }
-#endif // HAVE_ANDROID_OS
gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
terminateBuffer(module, const_cast<private_handle_t*>(hnd));
diff --git a/modules/gralloc/gralloc_priv.h b/modules/gralloc/gralloc_priv.h
index c3655a5..5d7db26 100644
--- a/modules/gralloc/gralloc_priv.h
+++ b/modules/gralloc/gralloc_priv.h
@@ -51,11 +51,6 @@ struct private_module_t {
float xdpi;
float ydpi;
float fps;
-
- enum {
- // flag to indicate we'll post this buffer
- PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
- };
};
/*****************************************************************************/
@@ -68,14 +63,7 @@ struct private_handle_t {
#endif
enum {
- PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
- PRIV_FLAGS_USES_PMEM = 0x00000002,
- };
-
- enum {
- LOCK_STATE_WRITE = 1<<31,
- LOCK_STATE_MAPPED = 1<<30,
- LOCK_STATE_READ_MASK = 0x3FFFFFFF
+ PRIV_FLAGS_FRAMEBUFFER = 0x00000001
};
// file-descriptors
@@ -88,18 +76,16 @@ struct private_handle_t {
// FIXME: the attributes below should be out-of-line
int base;
- int lockState;
- int writeOwner;
int pid;
#ifdef __cplusplus
- static const int sNumInts = 8;
+ static const int sNumInts = 6;
static const int sNumFds = 1;
static const int sMagic = 0x3141592;
private_handle_t(int fd, int size, int flags) :
fd(fd), magic(sMagic), flags(flags), size(size), offset(0),
- base(0), lockState(0), writeOwner(0), pid(getpid())
+ base(0), pid(getpid())
{
version = sizeof(native_handle);
numInts = sNumInts;
@@ -110,7 +96,7 @@ struct private_handle_t {
}
bool usesPhysicallyContiguousMemory() {
- return (flags & PRIV_FLAGS_USES_PMEM) != 0;
+ return false;
}
static int validate(const native_handle* h) {
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;
}