diff options
Diffstat (limited to 'libshims/ui')
-rw-r--r-- | libshims/ui/GraphicBuffer.cpp | 320 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferAllocator.cpp | 103 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferMapper.cpp | 101 |
3 files changed, 314 insertions, 210 deletions
diff --git a/libshims/ui/GraphicBuffer.cpp b/libshims/ui/GraphicBuffer.cpp index a1cf872..3fc6a2d 100644 --- a/libshims/ui/GraphicBuffer.cpp +++ b/libshims/ui/GraphicBuffer.cpp @@ -15,6 +15,7 @@ */ #define LOG_TAG "GraphicBuffer" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <ui/GraphicBuffer.h> @@ -22,10 +23,14 @@ #include <grallocusage/GrallocUsageConversion.h> -#include <ui/DetachedBufferHandle.h> +#ifndef LIBUI_IN_VNDK +#include <ui/BufferHubBuffer.h> +#endif // LIBUI_IN_VNDK + #include <ui/Gralloc2.h> #include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBufferMapper.h> +#include <utils/Trace.h> namespace android { @@ -44,6 +49,22 @@ sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { return static_cast<GraphicBuffer *>(anwb); } +GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) { + return reinterpret_cast<GraphicBuffer*>(buffer); +} + +GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) { + return reinterpret_cast<GraphicBuffer const*>(buffer); +} + +AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() { + return reinterpret_cast<AHardwareBuffer*>(this); +} + +AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const { + return reinterpret_cast<AHardwareBuffer const*>(this); +} + GraphicBuffer::GraphicBuffer() : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) @@ -55,57 +76,66 @@ GraphicBuffer::GraphicBuffer() usage_deprecated = 0; usage = 0; layerCount = 0; - handle = NULL; + handle = nullptr; } +// deprecated GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage) - : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()) + PixelFormat inFormat, uint32_t inUsage, std::string requestorName) + : GraphicBuffer(inWidth, inHeight, inFormat, 1, static_cast<uint64_t>(inUsage), requestorName) { - width = - height = - stride = - format = - usage = 0; - handle = NULL; - mInitCheck = initWithSize(inWidth, inHeight, inFormat, 1, - static_cast<uint64_t>(inUsage), "<Unknown>"); } +GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, std::string requestorName) + : GraphicBuffer() { + mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, + std::move(requestorName)); +} + +// deprecated 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), mId(getUniqueId()) -{ - 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), mId(getUniqueId()) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, + uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) + : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE, + inWidth, inHeight, inFormat, inLayerCount, static_cast<uint64_t>(inUsage), + inStride) { - width = buffer->width; - height = buffer->height; - stride = buffer->stride; - format = buffer->format; - usage = buffer->usage; - handle = buffer->handle; } +GraphicBuffer::GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, + uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) + : GraphicBuffer() { + mInitCheck = initWithHandle(inHandle, method, inWidth, inHeight, inFormat, inLayerCount, + inUsage, inStride); +} + +#ifndef LIBUI_IN_VNDK +GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() { + if (buffer == nullptr) { + mInitCheck = BAD_VALUE; + return; + } + + mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, + buffer->desc().width, buffer->desc().height, + static_cast<PixelFormat>(buffer->desc().format), + buffer->desc().layers, buffer->desc().usage, buffer->desc().stride); + mBufferId = buffer->id(); + mBufferHubBuffer = std::move(buffer); +} +#endif // LIBUI_IN_VNDK + GraphicBuffer::~GraphicBuffer() { + ATRACE_CALL(); if (handle) { free_handle(); } + for (auto& [callback, context] : mDeathCallbacks) { + callback(context, mId); + } } void GraphicBuffer::free_handle() @@ -116,7 +146,7 @@ void GraphicBuffer::free_handle() GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); } - handle = NULL; + handle = nullptr; } status_t GraphicBuffer::initCheck() const { @@ -130,7 +160,6 @@ void GraphicBuffer::dumpAllocationsToSystemLog() ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const { - LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer"); return static_cast<ANativeWindowBuffer*>( const_cast<GraphicBuffer*>(this)); } @@ -152,7 +181,7 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, if (handle) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); - handle = 0; + handle = nullptr; } return initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, "[Reallocation]"); } @@ -165,6 +194,7 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, if (inFormat != format) return true; if (inLayerCount != layerCount) return true; if ((usage & inUsage) != inUsage) return true; + if ((usage & USAGE_PROTECTED) != (inUsage & USAGE_PROTECTED)) return true; return false; } @@ -191,26 +221,24 @@ status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight, return err; } -status_t GraphicBuffer::initWithHandle(const native_handle_t* handle, - HandleWrapMethod method, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, uint64_t usage, - uint32_t stride) -{ - ANativeWindowBuffer::width = static_cast<int>(width); - ANativeWindowBuffer::height = static_cast<int>(height); - ANativeWindowBuffer::stride = static_cast<int>(stride); - ANativeWindowBuffer::format = format; - ANativeWindowBuffer::usage = usage; - ANativeWindowBuffer::usage_deprecated = int(usage); +status_t GraphicBuffer::initWithHandle(const native_handle_t* inHandle, HandleWrapMethod method, + uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) { + ANativeWindowBuffer::width = static_cast<int>(inWidth); + ANativeWindowBuffer::height = static_cast<int>(inHeight); + ANativeWindowBuffer::stride = static_cast<int>(inStride); + ANativeWindowBuffer::format = inFormat; + ANativeWindowBuffer::usage = inUsage; + ANativeWindowBuffer::usage_deprecated = int(inUsage); - ANativeWindowBuffer::layerCount = layerCount; + ANativeWindowBuffer::layerCount = inLayerCount; mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle; if (method == TAKE_UNREGISTERED_HANDLE || method == CLONE_HANDLE) { buffer_handle_t importedHandle; - status_t err = mBufferMapper.importBuffer(handle, width, height, - layerCount, format, usage, stride, &importedHandle); + status_t err = mBufferMapper.importBuffer(inHandle, inWidth, inHeight, inLayerCount, + inFormat, inUsage, inStride, &importedHandle); if (err != NO_ERROR) { initWithHandle(nullptr, WRAP_HANDLE, 0, 0, 0, 0, 0, 0); @@ -218,28 +246,28 @@ status_t GraphicBuffer::initWithHandle(const native_handle_t* handle, } if (method == TAKE_UNREGISTERED_HANDLE) { - native_handle_close(handle); - native_handle_delete(const_cast<native_handle_t*>(handle)); + native_handle_close(inHandle); + native_handle_delete(const_cast<native_handle_t*>(inHandle)); } - handle = importedHandle; - mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); + inHandle = importedHandle; + mBufferMapper.getTransportSize(inHandle, &mTransportNumFds, &mTransportNumInts); } - ANativeWindowBuffer::handle = handle; + ANativeWindowBuffer::handle = inHandle; return NO_ERROR; } -status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr) -{ +status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { const Rect lockBounds(width, height); - status_t res = lock(inUsage, lockBounds, vaddr); + status_t res = lock(inUsage, lockBounds, vaddr, outBytesPerPixel, outBytesPerStride); return res; } -status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr) -{ +status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 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)", @@ -247,7 +275,10 @@ status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr) width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr); + + status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr, outBytesPerPixel, + outBytesPerStride); + return res; } @@ -278,22 +309,22 @@ status_t GraphicBuffer::unlock() return res; } -status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd) -{ +status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { const Rect lockBounds(width, height); - status_t res = lockAsync(inUsage, lockBounds, vaddr, fenceFd); + status_t res = + lockAsync(inUsage, lockBounds, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); return res; } -status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, - void** vaddr, int fenceFd) -{ - return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd); +status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { + return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); } -status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, - uint64_t inConsumerUsage, const Rect& rect, void** vaddr, int fenceFd) -{ +status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, + const Rect& rect, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 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)", @@ -301,8 +332,10 @@ status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, - inConsumerUsage, rect, vaddr, fenceFd); + + status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect, + vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); + return res; } @@ -334,15 +367,37 @@ status_t GraphicBuffer::unlockAsync(int *fenceFd) return res; } +status_t GraphicBuffer::isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, + bool* outSupported) const { + return mBufferMapper.isSupported(inWidth, inHeight, inFormat, inLayerCount, inUsage, + outSupported); +} + size_t GraphicBuffer::getFlattenedSize() const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return 48; + } +#endif return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int); } size_t GraphicBuffer::getFdCount() const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return 0; + } +#endif return static_cast<size_t>(handle ? mTransportNumFds : 0); } status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return flattenBufferHubBuffer(buffer, size); + } +#endif size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); if (size < sizeNeeded) return NO_MEMORY; @@ -369,7 +424,7 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& buf[11] = int32_t(mTransportNumInts); memcpy(fds, handle->data, static_cast<size_t>(mTransportNumFds) * sizeof(int)); memcpy(buf + 13, handle->data + handle->numFds, - static_cast<size_t>(mTransportNumInts) * sizeof(int)); + static_cast<size_t>(mTransportNumInts) * sizeof(int)); } buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded); @@ -378,14 +433,13 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& fds += mTransportNumFds; count -= static_cast<size_t>(mTransportNumFds); } - return NO_ERROR; } -status_t GraphicBuffer::unflatten( - void const*& buffer, size_t& size, int const*& fds, size_t& count) { - if (size < 12 * sizeof(int)) { - android_errorWriteLog(0x534e4554, "114223584"); +status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& fds, + size_t& count) { + // Check if size is not smaller than buf[0] is supposed to take. + if (size < sizeof(int)) { return NO_MEMORY; } @@ -400,10 +454,21 @@ status_t GraphicBuffer::unflatten( } else if (buf[0] == 'GBFR') { // old version, when usage bits were 32-bits flattenWordCount = 12; + } else if (buf[0] == 'BHBB') { // BufferHub backed buffer. +#ifndef LIBUI_IN_VNDK + return unflattenBufferHubBuffer(buffer, size); +#else + return BAD_TYPE; +#endif } else { return BAD_TYPE; } + if (size < 12 * sizeof(int)) { + android_errorWriteLog(0x534e4554, "114223584"); + return NO_MEMORY; + } + const size_t numFds = static_cast<size_t>(buf[10]); const size_t numInts = static_cast<size_t>(buf[11]); @@ -416,7 +481,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts); return BAD_VALUE; } @@ -444,13 +509,13 @@ status_t GraphicBuffer::unflatten( } else { usage = uint64_t(usage_deprecated); } - native_handle* h = native_handle_create( - static_cast<int>(numFds), static_cast<int>(numInts)); + native_handle* h = + native_handle_create(static_cast<int>(numFds), static_cast<int>(numInts)); if (!h) { width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: native_handle_create failed"); return NO_MEMORY; } @@ -461,7 +526,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; } mId = static_cast<uint64_t>(buf[7]) << 32; @@ -471,7 +536,7 @@ status_t GraphicBuffer::unflatten( mOwner = ownHandle; - if (handle != 0) { + if (handle != nullptr) { buffer_handle_t importedHandle; status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height), uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle); @@ -479,7 +544,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err); return err; } @@ -494,27 +559,82 @@ status_t GraphicBuffer::unflatten( size -= sizeNeeded; fds += numFds; count -= numFds; - return NO_ERROR; } -bool GraphicBuffer::isDetachedBuffer() const { - return mDetachedBufferHandle && mDetachedBufferHandle->isValid(); +void GraphicBuffer::addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context) { + mDeathCallbacks.emplace_back(deathCallback, context); } -status_t GraphicBuffer::setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> channel) { - if (isDetachedBuffer()) { - ALOGW("setDetachedBuffer: there is already a BufferHub channel associated with this " - "GraphicBuffer. Replacing the old one."); +#ifndef LIBUI_IN_VNDK +status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size) const { + sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate(); + if (tokenHandle == nullptr || tokenHandle->handle() == nullptr || + tokenHandle->handle()->numFds != 0) { + return BAD_VALUE; + } + + // Size needed for one label, one number of ints inside the token, one generation number and + // the token itself. + int numIntsInToken = tokenHandle->handle()->numInts; + const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); + if (size < sizeNeeded) { + ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, + static_cast<int>(sizeNeeded), static_cast<int>(size)); + return NO_MEMORY; + } + size -= sizeNeeded; + + int* buf = static_cast<int*>(buffer); + buf[0] = 'BHBB'; + buf[1] = numIntsInToken; + memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int)); + buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber); + + return NO_ERROR; +} + +status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size) { + const int* buf = static_cast<const int*>(buffer); + int numIntsInToken = buf[1]; + // Size needed for one label, one number of ints inside the token, one generation number and + // the token itself. + const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); + if (size < sizeNeeded) { + ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, + static_cast<int>(sizeNeeded), static_cast<int>(size)); + return NO_MEMORY; + } + size -= sizeNeeded; + native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken); + memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int)); + sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true); + std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle); + if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) { + return BAD_VALUE; + } + // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object. + if (handle) { + free_handle(); } + mId = 0; + mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]); + mInitCheck = + initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, + bufferHubBuffer->desc().width, bufferHubBuffer->desc().height, + static_cast<PixelFormat>(bufferHubBuffer->desc().format), + bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage, + bufferHubBuffer->desc().stride); + mBufferId = bufferHubBuffer->id(); + mBufferHubBuffer.reset(std::move(bufferHubBuffer.get())); - mDetachedBufferHandle = std::move(channel); return NO_ERROR; } -std::unique_ptr<DetachedBufferHandle> GraphicBuffer::takeDetachedBufferHandle() { - return std::move(mDetachedBufferHandle); +bool GraphicBuffer::isBufferHubBuffer() const { + return mBufferHubBuffer != nullptr; } +#endif // LIBUI_IN_VNDK // --------------------------------------------------------------------------- diff --git a/libshims/ui/GraphicBufferAllocator.cpp b/libshims/ui/GraphicBufferAllocator.cpp index 3806a8d..0861a1f 100644 --- a/libshims/ui/GraphicBufferAllocator.cpp +++ b/libshims/ui/GraphicBufferAllocator.cpp @@ -24,79 +24,82 @@ #include <grallocusage/GrallocUsageConversion.h> +#include <android-base/stringprintf.h> #include <log/log.h> #include <utils/Singleton.h> -#include <utils/String8.h> #include <utils/Trace.h> +#include <ui/Gralloc.h> #include <ui/Gralloc2.h> +#include <ui/Gralloc3.h> #include <ui/GraphicBufferMapper.h> namespace android { // --------------------------------------------------------------------------- +using base::StringAppendF; + 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() : mMapper(GraphicBufferMapper::getInstance()) { + mAllocator = std::make_unique<const Gralloc3Allocator>( + reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper())); + if (!mAllocator->isLoaded()) { + mAllocator = std::make_unique<const Gralloc2Allocator>( + reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper())); + } + + if (!mAllocator->isLoaded()) { + LOG_ALWAYS_FATAL("gralloc-allocator is missing"); } } -GraphicBufferAllocator::~GraphicBufferAllocator() -{ - gralloc_close(mAllocDev); +GraphicBufferAllocator::~GraphicBufferAllocator() {} + +size_t GraphicBufferAllocator::getTotalSize() const { + Mutex::Autolock _l(sLock); + size_t total = 0; + for (size_t i = 0; i < sAllocList.size(); ++i) { + total += sAllocList.valueAt(i).size; + } + return total; } -void GraphicBufferAllocator::dump(String8& result) const -{ +void GraphicBufferAllocator::dump(std::string& 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); + result.append("Allocated buffers:\n"); 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 | %4u | %8X | 0x%" PRIx64 - " | %s\n", - list.keyAt(i), rec.size/1024.0, - rec.width, rec.stride, rec.height, rec.layerCount, rec.format, - rec.usage, rec.requestorName.c_str()); + StringAppendF(&result, + "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n", + list.keyAt(i), rec.size / 1024.0, rec.width, rec.stride, rec.height, + rec.layerCount, rec.format, rec.usage, rec.requestorName.c_str()); } else { - snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 - " | %s\n", - list.keyAt(i), - rec.width, rec.stride, rec.height, rec.layerCount, rec.format, - rec.usage, rec.requestorName.c_str()); + StringAppendF(&result, + "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n", + list.keyAt(i), rec.width, rec.stride, rec.height, rec.layerCount, + rec.format, rec.usage, rec.requestorName.c_str()); } - result.append(buffer); total += rec.size; } - snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0); - result.append(buffer); + StringAppendF(&result, "Total allocated (estimate): %.2f KB\n", total / 1024.0); - std::string deviceDump = mAllocator->dumpDebugInfo(); - result.append(deviceDump.c_str(), deviceDump.size()); + result.append(mAllocator->dumpDebugInfo()); } void GraphicBufferAllocator::dumpToSystemLog() { - String8 s; + std::string s; GraphicBufferAllocator::getInstance().dump(s); - ALOGD("%s", s.string()); + ALOGD("%s", s.c_str()); } status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, @@ -115,15 +118,12 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, if (layerCount < 1) layerCount = 1; - Gralloc2::IMapper::BufferDescriptorInfo info = {}; - info.width = width; - info.height = height; - info.layerCount = layerCount; - info.format = static_cast<Gralloc2::PixelFormat>(format); - info.usage = usage; + // TODO(b/72323293, b/72703005): Remove these invalid bits from callers + usage &= ~static_cast<uint64_t>((1 << 10) | (1 << 13)); - Gralloc2::Error error = mAllocator->allocate(info, stride, handle); - if (error == Gralloc2::Error::NONE) { + status_t error = + mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle); + if (error == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); uint32_t bpp = bytesPerPixel(format); @@ -150,18 +150,17 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, status_t GraphicBufferAllocator::free(buffer_handle_t handle) { - status_t err; + ATRACE_CALL(); - err = mAllocDev->free(mAllocDev, handle); + // We allocated a buffer from the allocator and imported it into the + // mapper to get the handle. We just need to free the handle now. + mMapper.freeBuffer(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); - } + Mutex::Autolock _l(sLock); + KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); + list.removeItem(handle); - return err; + return NO_ERROR; } // --------------------------------------------------------------------------- diff --git a/libshims/ui/GraphicBufferMapper.cpp b/libshims/ui/GraphicBufferMapper.cpp index 2d8e582..25b7247 100644 --- a/libshims/ui/GraphicBufferMapper.cpp +++ b/libshims/ui/GraphicBufferMapper.cpp @@ -32,7 +32,9 @@ #include <utils/Log.h> #include <utils/Trace.h> +#include <ui/Gralloc.h> #include <ui/Gralloc2.h> +#include <ui/Gralloc3.h> #include <ui/GraphicBuffer.h> #include <system/graphics.h> @@ -43,12 +45,22 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) void GraphicBufferMapper::preloadHal() { - Gralloc2::Mapper::preload(); + Gralloc2Mapper::preload(); + Gralloc3Mapper::preload(); } -GraphicBufferMapper::GraphicBufferMapper() - : mMapper(std::make_unique<const Gralloc2::Mapper>()) -{ +GraphicBufferMapper::GraphicBufferMapper() { + mMapper = std::make_unique<const Gralloc3Mapper>(); + if (!mMapper->isLoaded()) { + mMapper = std::make_unique<const Gralloc2Mapper>(); + mMapperVersion = Version::GRALLOC_2; + } else { + mMapperVersion = Version::GRALLOC_3; + } + + if (!mMapper->isLoaded()) { + LOG_ALWAYS_FATAL("gralloc-mapper is missing"); + } } status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle, @@ -59,22 +71,15 @@ status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle, ATRACE_CALL(); buffer_handle_t bufferHandle; - Gralloc2::Error error = mMapper->importBuffer( - hardware::hidl_handle(rawHandle), &bufferHandle); - if (error != Gralloc2::Error::NONE) { + status_t error = mMapper->importBuffer(hardware::hidl_handle(rawHandle), &bufferHandle); + if (error != NO_ERROR) { ALOGW("importBuffer(%p) failed: %d", rawHandle, error); - return static_cast<status_t>(error); + return error; } - Gralloc2::IMapper::BufferDescriptorInfo info = {}; - info.width = width; - info.height = height; - info.layerCount = layerCount; - info.format = static_cast<Gralloc2::PixelFormat>(format); - info.usage = usage; - - error = mMapper->validateBufferSize(bufferHandle, info, stride); - if (error != Gralloc2::Error::NONE) { + error = mMapper->validateBufferSize(bufferHandle, width, height, format, layerCount, usage, + stride); + if (error != NO_ERROR) { ALOGE("validateBufferSize(%p) failed: %d", rawHandle, error); freeBuffer(bufferHandle); return static_cast<status_t>(error); @@ -100,19 +105,10 @@ status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle) return NO_ERROR; } -static inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) { - Gralloc2::IMapper::Rect outRect{}; - outRect.left = rect.left; - outRect.top = rect.top; - outRect.width = rect.width(); - outRect.height = rect.height(); - return outRect; -} - -status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, - const Rect& bounds, void** vaddr) -{ - return lockAsync(handle, usage, bounds, vaddr, -1); +status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { + return lockAsync(handle, usage, bounds, vaddr, -1, outBytesPerPixel, outBytesPerStride); } status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage, @@ -132,27 +128,23 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle) return error; } -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, - uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd) -{ - return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd); +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr, int fenceFd, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { + return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd, outBytesPerPixel, + outBytesPerStride); } -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, - uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds, - void** vaddr, int fenceFd) -{ +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage, + uint64_t consumerUsage, const Rect& bounds, void** vaddr, + int fenceFd, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { ATRACE_CALL(); const uint64_t usage = static_cast<uint64_t>( android_convertGralloc1To0Usage(producerUsage, consumerUsage)); - Gralloc2::Error error = mMapper->lock(handle, usage, - asGralloc2Rect(bounds), fenceFd, vaddr); - - ALOGW_IF(error != Gralloc2::Error::NONE, "lock(%p, ...) failed: %d", - handle, error); - - return static_cast<status_t>(error); + return mMapper->lock(handle, usage, bounds, fenceFd, vaddr, outBytesPerPixel, + outBytesPerStride); } status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, @@ -160,19 +152,7 @@ status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, { ATRACE_CALL(); - Gralloc2::YCbCrLayout layout; - Gralloc2::Error error = mMapper->lock(handle, usage, - asGralloc2Rect(bounds), fenceFd, &layout); - if (error == Gralloc2::Error::NONE) { - ycbcr->y = layout.y; - ycbcr->cb = layout.cb; - ycbcr->cr = layout.cr; - ycbcr->ystride = static_cast<size_t>(layout.yStride); - ycbcr->cstride = static_cast<size_t>(layout.cStride); - ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep); - } - - return static_cast<status_t>(error); + return mMapper->lock(handle, usage, bounds, fenceFd, ycbcr); } status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) @@ -184,5 +164,10 @@ status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) return NO_ERROR; } +status_t GraphicBufferMapper::isSupported(uint32_t width, uint32_t height, + android::PixelFormat format, uint32_t layerCount, + uint64_t usage, bool* outSupported) { + return mMapper->isSupported(width, height, format, layerCount, usage, outSupported); +} // --------------------------------------------------------------------------- }; // namespace android |