diff options
author | Mathias Agopian <mathias@google.com> | 2009-10-05 18:19:57 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-10-06 17:00:25 -0700 |
commit | 6f5f5a095a5a4d42fc656cf8c1e6d0f67594f88d (patch) | |
tree | 3e4391ac9de9fe573abe63c88aee3d234b75be32 /libs | |
parent | 6950e428feaccc8164b989ef64e771a99948797a (diff) | |
download | frameworks_base-6f5f5a095a5a4d42fc656cf8c1e6d0f67594f88d.zip frameworks_base-6f5f5a095a5a4d42fc656cf8c1e6d0f67594f88d.tar.gz frameworks_base-6f5f5a095a5a4d42fc656cf8c1e6d0f67594f88d.tar.bz2 |
fix [2168531] have software-only gralloc buffer side-step the HAL
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ui/GraphicBufferAllocator.cpp | 22 | ||||
-rw-r--r-- | libs/ui/GraphicBufferMapper.cpp | 158 |
2 files changed, 170 insertions, 10 deletions
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 10b1051..57d5fc3 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -22,6 +22,7 @@ #include <ui/GraphicBufferAllocator.h> +#include <private/ui/sw_gralloc_handle.h> namespace android { // --------------------------------------------------------------------------- @@ -29,7 +30,8 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) Mutex GraphicBufferAllocator::sLock; -KeyedVector<buffer_handle_t, GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList; +KeyedVector<buffer_handle_t, + GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList; GraphicBufferAllocator::GraphicBufferAllocator() : mAllocDev(0) @@ -83,8 +85,13 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma h = clamp(h); // we have a h/w allocator and h/w buffer is requested - status_t err = mAllocDev->alloc(mAllocDev, - w, h, format, usage, handle, stride); + status_t err; + + if (usage & GRALLOC_USAGE_HW_MASK) { + err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); + } else { + err = sw_gralloc_handle_t::alloc(w, h, format, usage, handle, stride); + } LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", w, h, format, usage, err, strerror(-err)); @@ -113,9 +120,14 @@ status_t GraphicBufferAllocator::free(buffer_handle_t handle) { Mutex::Autolock _l(mLock); - status_t err = mAllocDev->free(mAllocDev, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocDev->free(mAllocDev, handle); + } else { + err = sw_gralloc_handle_t::free((sw_gralloc_handle_t*)handle); + } + LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index dd529e6..ce2acd0 100644 --- a/libs/ui/GraphicBufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -17,7 +17,15 @@ #define LOG_TAG "GraphicBufferMapper" #include <stdint.h> +#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define +# include <asm/page.h> +#else +# include <sys/user.h> +#endif #include <errno.h> +#include <sys/mman.h> + +#include <cutils/ashmem.h> #include <utils/Errors.h> #include <utils/Log.h> @@ -27,6 +35,8 @@ #include <hardware/gralloc.h> +#include <private/ui/sw_gralloc_handle.h> + namespace android { // --------------------------------------------------------------------------- @@ -46,7 +56,12 @@ GraphicBufferMapper::GraphicBufferMapper() status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) { - status_t err = mAllocMod->registerBuffer(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->registerBuffer(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::registerBuffer((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", handle, err, strerror(-err)); return err; @@ -54,7 +69,12 @@ status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) { - status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->unregisterBuffer(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::unregisterBuffer((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", handle, err, strerror(-err)); return err; @@ -63,18 +83,146 @@ status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) status_t GraphicBufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds, void** vaddr) { - status_t err = mAllocMod->lock(mAllocMod, handle, usage, - bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->lock(mAllocMod, handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height(), + vaddr); + } else { + err = sw_gralloc_handle_t::lock((sw_gralloc_handle_t*)handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height(), + vaddr); + } LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); return err; } status_t GraphicBufferMapper::unlock(buffer_handle_t handle) { - status_t err = mAllocMod->unlock(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->unlock(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::unlock((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); return err; } // --------------------------------------------------------------------------- + +status_t sw_gralloc_handle_t::alloc(uint32_t w, uint32_t h, int format, + int usage, buffer_handle_t* pHandle, int32_t* pStride) +{ + int align = 4; + int bpp = 0; + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + bpp = 4; + break; + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + break; + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + default: + return -EINVAL; + } + size_t bpr = (w*bpp + (align-1)) & ~(align-1); + size_t size = bpr * h; + size_t stride = bpr / bpp; + size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); + + int fd = ashmem_create_region("sw-gralloc-buffer", size); + if (fd < 0) { + LOGE("ashmem_create_region(size=%d) failed (%s)", + size, strerror(-errno)); + return -errno; + } + + int prot = PROT_READ; + if (usage & GRALLOC_USAGE_SW_WRITE_MASK) + prot |= PROT_WRITE; + + if (ashmem_set_prot_region(fd, prot) < 0) { + LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)", + fd, prot, strerror(-errno)); + close(fd); + return -errno; + } + + void* base = mmap(0, size, prot, MAP_SHARED, fd, 0); + if (base == MAP_FAILED) { + LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)", + fd, size, prot, strerror(-errno)); + close(fd); + return -errno; + } + + sw_gralloc_handle_t* hnd = new sw_gralloc_handle_t(); + hnd->fd = fd; + hnd->size = size; + hnd->base = intptr_t(base); + hnd->prot = prot; + *pStride = stride; + *pHandle = hnd; + + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::free(sw_gralloc_handle_t* hnd) +{ + if (hnd->base) { + munmap((void*)hnd->base, hnd->size); + } + if (hnd->fd >= 0) { + close(hnd->fd); + } + delete hnd; + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::registerBuffer(sw_gralloc_handle_t* hnd) +{ + if (hnd->pid != getpid()) { + void* base = mmap(0, hnd->size, hnd->prot, MAP_SHARED, hnd->fd, 0); + if (base == MAP_FAILED) { + LOGE("registerBuffer mmap(fd=%d, size=%d, prot=%x) failed (%s)", + hnd->fd, hnd->size, hnd->prot, strerror(-errno)); + return -errno; + } + hnd->base = intptr_t(base); + } + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::unregisterBuffer(sw_gralloc_handle_t* hnd) +{ + if (hnd->pid != getpid()) { + if (hnd->base) { + munmap((void*)hnd->base, hnd->size); + } + hnd->base = 0; + } + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::lock(sw_gralloc_handle_t* hnd, int usage, + int l, int t, int w, int h, void** vaddr) +{ + *vaddr = (void*)hnd->base; + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::unlock(sw_gralloc_handle_t* hnd) +{ + return NO_ERROR; +} + +// --------------------------------------------------------------------------- }; // namespace android |