diff options
author | Nikhil Punathil <nikhilpe@gmail.com> | 2019-06-17 21:14:34 -0700 |
---|---|---|
committer | Arian <arian.kulmer@web.de> | 2019-10-25 22:16:13 +0200 |
commit | fd201d3c1df49d4af95d2c48709b5a98b6e6d8e9 (patch) | |
tree | b4f84e360112bf9b36f05a35f8a305f08d8fbfdc /libshims/ui | |
parent | e37adcfc67e23451386efab1ca7c2a7774829cb7 (diff) |
shinano-common: bring in libshim_camera from msm8974-common
we need updated sources that break rhine compatibility for working cam
Change-Id: I274c91efc797b0304a2074baf4b908766d321356
Signed-off-by: Nikhil Punathil <nikhilpe@gmail.com>
Diffstat (limited to 'libshims/ui')
-rw-r--r-- | libshims/ui/GraphicBuffer.cpp | 336 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferAllocator.cpp | 159 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferMapper.cpp | 119 |
3 files changed, 614 insertions, 0 deletions
diff --git a/libshims/ui/GraphicBuffer.cpp b/libshims/ui/GraphicBuffer.cpp new file mode 100644 index 0000000..dad41b4 --- /dev/null +++ b/libshims/ui/GraphicBuffer.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2007 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. + */ + +#define LOG_TAG "GraphicBuffer" + +#include <stdlib.h> +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/Log.h> + +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferAllocator.h> +#include <ui/GraphicBufferMapper.h> +#include <ui/PixelFormat.h> + +namespace android { + +// =========================================================================== +// Buffer and implementation of ANativeWindowBuffer +// =========================================================================== + +GraphicBuffer::GraphicBuffer() + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR) +{ + width = + height = + stride = + format = + usage = 0; + handle = NULL; +} + +GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage) + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR) +{ + width = + height = + stride = + format = + usage = 0; + handle = NULL; + mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage); +} + +GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage, uint32_t inStride, + native_handle_t* inHandle, bool keepOwnership) + : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), + mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR) +{ + width = static_cast<int>(inWidth); + height = static_cast<int>(inHeight); + stride = static_cast<int>(inStride); + format = inFormat; + usage = static_cast<int>(inUsage); + handle = inHandle; +} + +GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) + : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), + mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mWrappedBuffer(buffer) +{ + width = buffer->width; + height = buffer->height; + stride = buffer->stride; + format = buffer->format; + usage = buffer->usage; + handle = buffer->handle; +} + +GraphicBuffer::~GraphicBuffer() +{ + if (handle) { + free_handle(); + } +} + +void GraphicBuffer::free_handle() +{ + if (mOwner == ownHandle) { + mBufferMapper.unregisterBuffer(handle); + native_handle_close(handle); + native_handle_delete(const_cast<native_handle*>(handle)); + } else if (mOwner == ownData) { + GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); + allocator.free(handle); + } + + mWrappedBuffer = 0; +} + +status_t GraphicBuffer::initCheck() const { + return static_cast<status_t>(mInitCheck); +} + +void GraphicBuffer::dumpAllocationsToSystemLog() +{ + GraphicBufferAllocator::dumpToSystemLog(); +} + +ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const +{ + LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer"); + return static_cast<ANativeWindowBuffer*>( + const_cast<GraphicBuffer*>(this)); +} + +status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage) +{ + if (mOwner != ownData) + return INVALID_OPERATION; + + if (handle && + static_cast<int>(inWidth) == width && + static_cast<int>(inHeight) == height && + inFormat == format && + static_cast<int>(inUsage) == usage) + return NO_ERROR; + + if (handle) { + GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); + allocator.free(handle); + handle = 0; + } + return initSize(inWidth, inHeight, inFormat, inUsage); +} + +status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage) +{ + GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); + int outStride = 0; + status_t err = allocator.alloc(inWidth, inHeight, inFormat, inUsage, + &handle, &outStride); + if (err == NO_ERROR) { + width = static_cast<int>(inWidth); + height = static_cast<int>(inHeight); + format = inFormat; + usage = static_cast<int>(inUsage); + stride = static_cast<int>(outStride); + } + return err; +} + +status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr) +{ + const Rect lockBounds(width, height); + status_t res = lock(inUsage, lockBounds, vaddr); + return res; +} + +status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr) +{ + if (rect.left < 0 || rect.right > width || + rect.top < 0 || rect.bottom > height) { + ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", + rect.left, rect.top, rect.right, rect.bottom, + width, height); + return BAD_VALUE; + } + status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr); + return res; +} + +status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, android_ycbcr* ycbcr) +{ + const Rect lockBounds(width, height); + status_t res = lockYCbCr(inUsage, lockBounds, ycbcr); + return res; +} + +status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, const Rect& rect, + android_ycbcr* ycbcr) +{ + if (rect.left < 0 || rect.right > width || + rect.top < 0 || rect.bottom > height) { + ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", + rect.left, rect.top, rect.right, rect.bottom, + width, height); + return BAD_VALUE; + } + status_t res = getBufferMapper().lockYCbCr(handle, inUsage, rect, ycbcr); + return res; +} + +status_t GraphicBuffer::unlock() +{ + status_t res = getBufferMapper().unlock(handle); + return res; +} + +size_t GraphicBuffer::getFlattenedSize() const { + return static_cast<size_t>(8 + (handle ? handle->numInts : 0)) * sizeof(int); +} + +size_t GraphicBuffer::getFdCount() const { + return static_cast<size_t>(handle ? handle->numFds : 0); +} + +status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { + size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); + if (size < sizeNeeded) return NO_MEMORY; + + size_t fdCountNeeded = GraphicBuffer::getFdCount(); + if (count < fdCountNeeded) return NO_MEMORY; + + int* buf = static_cast<int*>(buffer); + buf[0] = 'GBFR'; + buf[1] = width; + buf[2] = height; + buf[3] = stride; + buf[4] = format; + buf[5] = usage; + buf[6] = 0; + buf[7] = 0; + + if (handle) { + buf[6] = handle->numFds; + buf[7] = handle->numInts; + memcpy(fds, handle->data, + static_cast<size_t>(handle->numFds) * sizeof(int)); + memcpy(&buf[8], handle->data + handle->numFds, + static_cast<size_t>(handle->numInts) * sizeof(int)); + } + + buffer = static_cast<void*>(static_cast<int*>(buffer) + sizeNeeded); + size -= sizeNeeded; + if (handle) { + fds += handle->numFds; + count -= static_cast<size_t>(handle->numFds); + } + + return NO_ERROR; +} + +status_t GraphicBuffer::unflatten( + void const*& buffer, size_t& size, int const*& fds, size_t& count) { + if (size < 8 * sizeof(int)) return NO_MEMORY; + + int const* buf = static_cast<int const*>(buffer); + if (buf[0] != 'GBFR') return BAD_TYPE; + + const size_t numFds = static_cast<size_t>(buf[6]); + const size_t numInts = static_cast<size_t>(buf[7]); + + // Limit the maxNumber to be relatively small. The number of fds or ints + // should not come close to this number, and the number itself was simply + // chosen to be high enough to not cause issues and low enough to prevent + // overflow problems. + const size_t maxNumber = 4096; + if (numFds >= maxNumber || numInts >= (maxNumber - 10)) { + width = height = stride = format = usage = 0; + handle = NULL; + ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", + numFds, numInts); + return BAD_VALUE; + } + + const size_t sizeNeeded = (8 + numInts) * sizeof(int); + if (size < sizeNeeded) return NO_MEMORY; + + size_t fdCountNeeded = numFds; + if (count < fdCountNeeded) return NO_MEMORY; + + if (handle) { + // free previous handle if any + free_handle(); + } + + if (numFds || numInts) { + width = buf[1]; + height = buf[2]; + stride = buf[3]; + format = buf[4]; + usage = buf[5]; + native_handle* h = native_handle_create( + static_cast<int>(numFds), static_cast<int>(numInts)); + if (!h) { + width = height = stride = format = usage = 0; + handle = NULL; + ALOGE("unflatten: native_handle_create failed"); + return NO_MEMORY; + } + memcpy(h->data, fds, numFds * sizeof(int)); + memcpy(h->data + numFds, &buf[8], numInts * sizeof(int)); + handle = h; + } else { + width = height = stride = format = usage = 0; + handle = NULL; + } + + mOwner = ownHandle; + + if (handle != 0) { + status_t err = mBufferMapper.registerBuffer(handle); + if (err != NO_ERROR) { + width = height = stride = format = usage = 0; + handle = NULL; + ALOGE("unflatten: registerBuffer failed: %s (%d)", + strerror(-err), err); + return err; + } + } + + buffer = static_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded); + size -= sizeNeeded; + fds += numFds; + count -= numFds; + + return NO_ERROR; +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libshims/ui/GraphicBufferAllocator.cpp b/libshims/ui/GraphicBufferAllocator.cpp new file mode 100644 index 0000000..4f93fb6 --- /dev/null +++ b/libshims/ui/GraphicBufferAllocator.cpp @@ -0,0 +1,159 @@ +/* +** +** Copyright 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. +*/ + +#define LOG_TAG "GraphicBufferAllocator" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include <cutils/log.h> + +#include <utils/Singleton.h> +#include <utils/String8.h> +#include <utils/Trace.h> + +#include <ui/GraphicBufferAllocator.h> + +namespace android { +// --------------------------------------------------------------------------- + +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) + +Mutex GraphicBufferAllocator::sLock; +KeyedVector<buffer_handle_t, + GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList; + +GraphicBufferAllocator::GraphicBufferAllocator() + : mAllocDev(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + gralloc_open(module, &mAllocDev); + } +} + +GraphicBufferAllocator::~GraphicBufferAllocator() +{ + gralloc_close(mAllocDev); +} + +void GraphicBufferAllocator::dump(String8& result) const +{ + Mutex::Autolock _l(sLock); + KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); + size_t total = 0; + const size_t SIZE = 4096; + char buffer[SIZE]; + snprintf(buffer, SIZE, "Allocated buffers:\n"); + result.append(buffer); + const size_t c = list.size(); + for (size_t i=0 ; i<c ; i++) { + const alloc_rec_t& rec(list.valueAt(i)); + if (rec.size) { + snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n", + list.keyAt(i), rec.size/1024.0f, + rec.width, rec.stride, rec.height, rec.format, rec.usage); + } else { + snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n", + list.keyAt(i), + rec.width, rec.stride, rec.height, rec.format, rec.usage); + } + result.append(buffer); + total += rec.size; + } + snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f); + result.append(buffer); + if (mAllocDev->common.version >= 1 && mAllocDev->dump) { + mAllocDev->dump(mAllocDev, buffer, SIZE); + result.append(buffer); + } +} + +void GraphicBufferAllocator::dumpToSystemLog() +{ + String8 s; + GraphicBufferAllocator::getInstance().dump(s); + ALOGD("%s", s.string()); +} + +status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height, + PixelFormat format, int usage, buffer_handle_t* handle, + int32_t* stride) +{ + ATRACE_CALL(); + + // make sure to not allocate a N x 0 or 0 x N buffer, since this is + // allowed from an API stand-point allocate a 1x1 buffer instead. + if (!width || !height) + width = height = 1; + + // we have a h/w allocator and h/w buffer is requested + status_t err; + + // Filter out any usage bits that should not be passed to the gralloc module + usage &= GRALLOC_USAGE_ALLOC_MASK; + + int outStride = 0; + err = mAllocDev->alloc(mAllocDev, static_cast<int>(width), + static_cast<int>(height), format, static_cast<int>(usage), handle, + &outStride); + *stride = static_cast<uint32_t>(outStride); + + ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", + width, height, format, usage, err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); + int bpp = bytesPerPixel(format); + if (bpp < 0) { + // probably a HAL custom format. in any case, we don't know + // what its pixel size is. + bpp = 0; + } + alloc_rec_t rec; + rec.width = width; + rec.height = height; + rec.stride = *stride; + rec.format = format; + rec.usage = usage; + rec.size = static_cast<size_t>(height * (*stride) * bpp); + list.add(*handle, rec); + } + + return err; +} + +status_t GraphicBufferAllocator::free(buffer_handle_t handle) +{ + ATRACE_CALL(); + status_t err; + + err = mAllocDev->free(mAllocDev, handle); + + ALOGW_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); + list.removeItem(handle); + } + + return err; +} + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libshims/ui/GraphicBufferMapper.cpp b/libshims/ui/GraphicBufferMapper.cpp new file mode 100644 index 0000000..18be8ae --- /dev/null +++ b/libshims/ui/GraphicBufferMapper.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2007 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. + */ + +#define LOG_TAG "GraphicBufferMapper" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include <stdint.h> +#include <errno.h> + +#include <sync/sync.h> + +#include <utils/Errors.h> +#include <utils/Log.h> +#include <utils/Trace.h> + +#include <ui/GraphicBufferMapper.h> +#include <ui/Rect.h> + +#include <hardware/gralloc.h> + + +namespace android { +// --------------------------------------------------------------------------- + +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) + +GraphicBufferMapper::GraphicBufferMapper() + : mAllocMod(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + mAllocMod = reinterpret_cast<gralloc_module_t const *>(module); + } +} + +status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) +{ + ATRACE_CALL(); + status_t err; + + err = mAllocMod->registerBuffer(mAllocMod, handle); + + ALOGW_IF(err, "registerBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) +{ + ATRACE_CALL(); + status_t err; + + err = mAllocMod->unregisterBuffer(mAllocMod, handle); + + ALOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::lock(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr) +{ + ATRACE_CALL(); + status_t err; + + err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage), + bounds.left, bounds.top, bounds.width(), bounds.height(), + vaddr); + + ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, + int usage, const Rect& bounds, android_ycbcr *ycbcr) +{ + ATRACE_CALL(); + status_t err; + + if (mAllocMod->lock_ycbcr == NULL) { + return -EINVAL; // do not log failure + } + + err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage), + bounds.left, bounds.top, bounds.width(), bounds.height(), + ycbcr); + + ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::unlock(buffer_handle_t handle) +{ + ATRACE_CALL(); + status_t err; + + err = mAllocMod->unlock(mAllocMod, handle); + + ALOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +// --------------------------------------------------------------------------- +}; // namespace android |