summaryrefslogtreecommitdiffstats
path: root/modules/gralloc
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-12-14 18:27:09 -0800
committerMathias Agopian <mathias@google.com>2009-12-15 15:00:57 -0800
commitf96b2064d7753af7ab75f05eff9559f401e1a4ad (patch)
tree3f94f2204cf1b9f12762e83701a52fb0622358d4 /modules/gralloc
parent058c1fce990a54b1dfdfb511c752b32914d32f6f (diff)
downloadhardware_libhardware-f96b2064d7753af7ab75f05eff9559f401e1a4ad.zip
hardware_libhardware-f96b2064d7753af7ab75f05eff9559f401e1a4ad.tar.gz
hardware_libhardware-f96b2064d7753af7ab75f05eff9559f401e1a4ad.tar.bz2
remove all references to pmem and simplify the lock/unlock hooks
this gralloc module is only used on the emulator or without a h/w renderer. therefore there is no synchronization to do in lock/unlock and pmem buffers are not relevant. hopefully this will remove some of the confusion about how gralloc should be implemented and make it more obvious that this implementation is not intended to be used by h/w renderers.
Diffstat (limited to 'modules/gralloc')
-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;
}