From 6ebc46a7c01b22bc19d3c00b493f8d930b15b43a Mon Sep 17 00:00:00 2001 From: Craig Donner Date: Fri, 21 Oct 2016 15:23:44 -0700 Subject: Add layered buffer support to libui and libgui. Bug: 31686534 Test: manual Change-Id: Ia40270701467f4b785660324cad883e7da08989a --- libs/ui/GraphicBuffer.cpp | 92 ++++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 32 deletions(-) (limited to 'libs/ui/GraphicBuffer.cpp') diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 6d729006f7..07164a4f44 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -50,6 +50,7 @@ GraphicBuffer::GraphicBuffer() height = stride = format = + layerCount = usage = 0; handle = NULL; } @@ -63,15 +64,33 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, height = stride = format = + layerCount = usage = 0; handle = NULL; - mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage, + mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, std::move(requestorName)); } GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage, uint32_t inStride, - native_handle_t* inHandle, bool keepOwnership) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, + std::string requestorName) + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) +{ + width = + height = + stride = + format = + layerCount = + usage = 0; + handle = NULL; + mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, + std::move(requestorName)); +} + +GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inLayerCount, 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()), mGenerationNumber(0) @@ -80,6 +99,7 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, height = static_cast(inHeight); stride = static_cast(inStride); format = inFormat; + layerCount = inLayerCount; usage = static_cast(inUsage); handle = inHandle; } @@ -94,6 +114,7 @@ GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) height = buffer->height; stride = buffer->stride; format = buffer->format; + layerCount = buffer->layerCount; usage = buffer->usage; handle = buffer->handle; } @@ -138,7 +159,7 @@ ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const } status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage) { if (mOwner != ownData) return INVALID_OPERATION; @@ -147,6 +168,7 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, static_cast(inWidth) == width && static_cast(inHeight) == height && inFormat == format && + inLayerCount == layerCount && static_cast(inUsage) == usage) return NO_ERROR; @@ -155,30 +177,34 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, allocator.free(handle); handle = 0; } - return initSize(inWidth, inHeight, inFormat, inUsage, "[Reallocation]"); + return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, + "[Reallocation]"); } bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage) { if (static_cast(inWidth) != width) return true; if (static_cast(inHeight) != height) return true; if (inFormat != format) return true; + if (inLayerCount != layerCount) return true; if ((static_cast(usage) & inUsage) != inUsage) return true; return false; } status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage, std::string requestorName) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, + std::string requestorName) { GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); uint32_t outStride = 0; - status_t err = allocator.allocate(inWidth, inHeight, inFormat, inUsage, - &handle, &outStride, mId, std::move(requestorName)); + status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount, + inUsage, &handle, &outStride, mId, std::move(requestorName)); if (err == NO_ERROR) { width = static_cast(inWidth); height = static_cast(inHeight); format = inFormat; + layerCount = inLayerCount; usage = static_cast(inUsage); stride = static_cast(outStride); } @@ -284,7 +310,7 @@ status_t GraphicBuffer::unlockAsync(int *fenceFd) } size_t GraphicBuffer::getFlattenedSize() const { - return static_cast(11 + (handle ? handle->numInts : 0)) * sizeof(int); + return static_cast(12 + (handle ? handle->numInts : 0)) * sizeof(int); } size_t GraphicBuffer::getFdCount() const { @@ -304,19 +330,20 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& buf[2] = height; buf[3] = stride; buf[4] = format; - buf[5] = usage; - buf[6] = static_cast(mId >> 32); - buf[7] = static_cast(mId & 0xFFFFFFFFull); - buf[8] = static_cast(mGenerationNumber); - buf[9] = 0; + buf[5] = static_cast(layerCount); + buf[6] = usage; + buf[7] = static_cast(mId >> 32); + buf[8] = static_cast(mId & 0xFFFFFFFFull); + buf[9] = static_cast(mGenerationNumber); buf[10] = 0; + buf[11] = 0; if (handle) { - buf[9] = handle->numFds; - buf[10] = handle->numInts; + buf[10] = handle->numFds; + buf[11] = handle->numInts; memcpy(fds, handle->data, static_cast(handle->numFds) * sizeof(int)); - memcpy(&buf[11], handle->data + handle->numFds, + memcpy(&buf[12], handle->data + handle->numFds, static_cast(handle->numInts) * sizeof(int)); } @@ -332,28 +359,28 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& status_t GraphicBuffer::unflatten( void const*& buffer, size_t& size, int const*& fds, size_t& count) { - if (size < 11 * sizeof(int)) return NO_MEMORY; + if (size < 12 * sizeof(int)) return NO_MEMORY; int const* buf = static_cast(buffer); if (buf[0] != 'GBFR') return BAD_TYPE; - const size_t numFds = static_cast(buf[9]); - const size_t numInts = static_cast(buf[10]); + const size_t numFds = static_cast(buf[10]); + const size_t numInts = static_cast(buf[11]); // 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 - 11)) { - width = height = stride = format = usage = 0; + if (numFds >= maxNumber || numInts >= (maxNumber - 12)) { + width = height = stride = format = layerCount = usage = 0; handle = NULL; ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts); return BAD_VALUE; } - const size_t sizeNeeded = (11 + numInts) * sizeof(int); + const size_t sizeNeeded = (12 + numInts) * sizeof(int); if (size < sizeNeeded) return NO_MEMORY; size_t fdCountNeeded = numFds; @@ -369,34 +396,35 @@ status_t GraphicBuffer::unflatten( height = buf[2]; stride = buf[3]; format = buf[4]; - usage = buf[5]; + layerCount = static_cast(buf[5]); + usage = buf[6]; native_handle* h = native_handle_create( static_cast(numFds), static_cast(numInts)); if (!h) { - width = height = stride = format = usage = 0; + width = height = stride = format = layerCount = 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[11], numInts * sizeof(int)); + memcpy(h->data + numFds, &buf[12], numInts * sizeof(int)); handle = h; } else { - width = height = stride = format = usage = 0; + width = height = stride = format = layerCount = usage = 0; handle = NULL; } - mId = static_cast(buf[6]) << 32; - mId |= static_cast(buf[7]); + mId = static_cast(buf[7]) << 32; + mId |= static_cast(buf[8]); - mGenerationNumber = static_cast(buf[8]); + mGenerationNumber = static_cast(buf[9]); mOwner = ownHandle; if (handle != 0) { status_t err = mBufferMapper.registerBuffer(this); if (err != NO_ERROR) { - width = height = stride = format = usage = 0; + width = height = stride = format = layerCount = usage = 0; handle = NULL; ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err); -- cgit v1.2.3-59-g8ed1b