Add layered buffer support to libui and libgui.
Bug: 31686534
Test: manual
Change-Id: Ia40270701467f4b785660324cad883e7da08989a
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 90b4b9d..9241c7c 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -42,6 +42,8 @@
namespace android {
+static constexpr uint32_t BQ_LAYER_COUNT = 1;
+
BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
bool consumerIsSurfaceFlinger) :
mCore(core),
@@ -414,7 +416,8 @@
// buffer. If this buffer would require reallocation to meet the
// requested attributes, we free it and attempt to get another one.
if (!mCore->mAllowAllocation) {
- if (buffer->needsReallocation(width, height, format, usage)) {
+ if (buffer->needsReallocation(width, height, format,
+ BQ_LAYER_COUNT, usage)) {
if (mCore->mSharedBufferSlot == found) {
BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
"buffer");
@@ -430,7 +433,8 @@
const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
if (mCore->mSharedBufferSlot == found &&
- buffer->needsReallocation(width, height, format, usage)) {
+ buffer->needsReallocation(width, height, format,
+ BQ_LAYER_COUNT, usage)) {
BQ_LOGE("dequeueBuffer: cannot re-allocate a shared"
"buffer");
@@ -449,7 +453,8 @@
mSlots[found].mBufferState.dequeue();
if ((buffer == NULL) ||
- buffer->needsReallocation(width, height, format, usage))
+ buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT,
+ usage))
{
mSlots[found].mAcquireCalled = false;
mSlots[found].mGraphicBuffer = NULL;
@@ -500,7 +505,7 @@
status_t error;
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
- width, height, format, usage,
+ width, height, format, BQ_LAYER_COUNT, usage,
{mConsumerName.string(), mConsumerName.size()}, &error));
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
@@ -1039,6 +1044,10 @@
case NATIVE_WINDOW_FORMAT:
value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
break;
+ case NATIVE_WINDOW_LAYER_COUNT:
+ // All BufferQueue buffers have a single layer.
+ value = BQ_LAYER_COUNT;
+ break;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
value = mCore->getMinUndequeuedBufferCountLocked();
break;
@@ -1287,8 +1296,9 @@
for (size_t i = 0; i < newBufferCount; ++i) {
status_t result = NO_ERROR;
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
- allocWidth, allocHeight, allocFormat, allocUsage,
- {mConsumerName.string(), mConsumerName.size()}, &result));
+ allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,
+ allocUsage, {mConsumerName.string(), mConsumerName.size()},
+ &result));
if (result != NO_ERROR) {
BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
" %u, usage %u)", width, height, format, usage);
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index e6150f4..9d045dd 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -32,19 +32,21 @@
}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
- uint32_t height, PixelFormat format, uint32_t usage,
- std::string requestorName, status_t* error) {
+ uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint32_t usage, std::string requestorName, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
- width, height, format, usage, std::move(requestorName)));
+ width, height, format, layerCount, usage,
+ std::move(requestorName)));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
if (err == NO_MEMORY) {
GraphicBuffer::dumpAllocationsToSystemLog();
}
- ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
+ ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) "
"failed (%s), handle=%p",
- width, height, strerror(-err), graphicBuffer->handle);
+ width, height, layerCount, strerror(-err),
+ graphicBuffer->handle);
return 0;
}
return graphicBuffer;
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 2fb380c..a3d3b74 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -45,13 +45,14 @@
virtual ~BpGraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
- uint32_t height, PixelFormat format, uint32_t usage,
- std::string requestorName, status_t* error) {
+ uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint32_t usage, std::string requestorName, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeUint32(width);
data.writeUint32(height);
data.writeInt32(static_cast<int32_t>(format));
+ data.writeUint32(layerCount);
data.writeUint32(usage);
if (requestorName.empty()) {
requestorName += "[PID ";
@@ -106,12 +107,13 @@
uint32_t width = data.readUint32();
uint32_t height = data.readUint32();
PixelFormat format = static_cast<PixelFormat>(data.readInt32());
+ uint32_t layerCount = data.readUint32();
uint32_t usage = data.readUint32();
status_t error = NO_ERROR;
std::string requestorName;
data.readUtf8FromUtf16(&requestorName);
sp<GraphicBuffer> result = createGraphicBuffer(width, height,
- format, usage, requestorName, &error);
+ format, layerCount, usage, requestorName, &error);
reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 0de60c9..1aa03a5 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -140,6 +140,14 @@
EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
}
+TEST_F(SurfaceTest, LayerCountIsOne) {
+ sp<ANativeWindow> anw(mSurface);
+ int result = -123;
+ int err = anw->query(anw.get(), NATIVE_WINDOW_LAYER_COUNT, &result);
+ EXPECT_EQ(NO_ERROR, err);
+ EXPECT_EQ(1, result);
+}
+
TEST_F(SurfaceTest, QueryConsumerUsage) {
const int TEST_USAGE_FLAGS =
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
diff --git a/libs/ui/Gralloc1.cpp b/libs/ui/Gralloc1.cpp
index 4c73ce4..367d1ce 100644
--- a/libs/ui/Gralloc1.cpp
+++ b/libs/ui/Gralloc1.cpp
@@ -77,6 +77,17 @@
mShimDevice.mDevice, mDeviceId, format, &mFormat);
}
+gralloc1_error_t Descriptor::setLayerCount(uint32_t layerCount)
+{
+ if (mShimDevice.hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
+ return setHelper<uint32_t>(mShimDevice.mFunctions.setLayerCount.pfn,
+ mShimDevice.mDevice, mDeviceId, layerCount, &mLayerCount);
+ } else {
+ // Layered buffers are not supported on this device.
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+}
+
gralloc1_error_t Descriptor::setProducerUsage(gralloc1_producer_usage_t usage)
{
return setHelper<uint64_t>(mShimDevice.mFunctions.setProducerUsage.pfn,
@@ -366,6 +377,15 @@
mFunctions.allocate.load(mDevice, false);
}
+ if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
+ if (!mFunctions.setLayerCount.load(mDevice, true)) {
+ return false;
+ }
+ if (!mFunctions.getLayerCount.load(mDevice, true)) {
+ return false;
+ }
+ }
+
return true;
}
diff --git a/libs/ui/Gralloc1On0Adapter.cpp b/libs/ui/Gralloc1On0Adapter.cpp
index d5b88de..111879a 100644
--- a/libs/ui/Gralloc1On0Adapter.cpp
+++ b/libs/ui/Gralloc1On0Adapter.cpp
@@ -97,6 +97,8 @@
return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
case GRALLOC1_FUNCTION_SET_FORMAT:
return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
+ case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
+ return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook);
case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
case GRALLOC1_FUNCTION_GET_BACKING_STORE:
@@ -113,6 +115,10 @@
return asFP<GRALLOC1_PFN_GET_FORMAT>(
bufferHook<decltype(&Buffer::getFormat),
&Buffer::getFormat, int32_t*>);
+ case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
+ return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>(
+ bufferHook<decltype(&Buffer::getLayerCount),
+ &Buffer::getLayerCount, uint32_t*>);
case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
case GRALLOC1_FUNCTION_GET_STRIDE:
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 6d72900..07164a4 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -50,6 +50,7 @@
height =
stride =
format =
+ layerCount =
usage = 0;
handle = NULL;
}
@@ -63,15 +64,33 @@
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 @@
height = static_cast<int>(inHeight);
stride = static_cast<int>(inStride);
format = inFormat;
+ layerCount = inLayerCount;
usage = static_cast<int>(inUsage);
handle = inHandle;
}
@@ -94,6 +114,7 @@
height = buffer->height;
stride = buffer->stride;
format = buffer->format;
+ layerCount = buffer->layerCount;
usage = buffer->usage;
handle = buffer->handle;
}
@@ -138,7 +159,7 @@
}
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 @@
static_cast<int>(inWidth) == width &&
static_cast<int>(inHeight) == height &&
inFormat == format &&
+ inLayerCount == layerCount &&
static_cast<int>(inUsage) == usage)
return NO_ERROR;
@@ -155,30 +177,34 @@
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<int>(inWidth) != width) return true;
if (static_cast<int>(inHeight) != height) return true;
if (inFormat != format) return true;
+ if (inLayerCount != layerCount) return true;
if ((static_cast<uint32_t>(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<int>(inWidth);
height = static_cast<int>(inHeight);
format = inFormat;
+ layerCount = inLayerCount;
usage = static_cast<int>(inUsage);
stride = static_cast<int>(outStride);
}
@@ -284,7 +310,7 @@
}
size_t GraphicBuffer::getFlattenedSize() const {
- return static_cast<size_t>(11 + (handle ? handle->numInts : 0)) * sizeof(int);
+ return static_cast<size_t>(12 + (handle ? handle->numInts : 0)) * sizeof(int);
}
size_t GraphicBuffer::getFdCount() const {
@@ -304,19 +330,20 @@
buf[2] = height;
buf[3] = stride;
buf[4] = format;
- buf[5] = usage;
- buf[6] = static_cast<int32_t>(mId >> 32);
- buf[7] = static_cast<int32_t>(mId & 0xFFFFFFFFull);
- buf[8] = static_cast<int32_t>(mGenerationNumber);
- buf[9] = 0;
+ buf[5] = static_cast<int32_t>(layerCount);
+ buf[6] = usage;
+ buf[7] = static_cast<int32_t>(mId >> 32);
+ buf[8] = static_cast<int32_t>(mId & 0xFFFFFFFFull);
+ buf[9] = static_cast<int32_t>(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<size_t>(handle->numFds) * sizeof(int));
- memcpy(&buf[11], handle->data + handle->numFds,
+ memcpy(&buf[12], handle->data + handle->numFds,
static_cast<size_t>(handle->numInts) * sizeof(int));
}
@@ -332,28 +359,28 @@
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<int const*>(buffer);
if (buf[0] != 'GBFR') return BAD_TYPE;
- const size_t numFds = static_cast<size_t>(buf[9]);
- const size_t numInts = static_cast<size_t>(buf[10]);
+ const size_t numFds = static_cast<size_t>(buf[10]);
+ const size_t numInts = static_cast<size_t>(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 @@
height = buf[2];
stride = buf[3];
format = buf[4];
- usage = buf[5];
+ layerCount = static_cast<uintptr_t>(buf[5]);
+ usage = buf[6];
native_handle* h = native_handle_create(
static_cast<int>(numFds), static_cast<int>(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<uint64_t>(buf[6]) << 32;
- mId |= static_cast<uint32_t>(buf[7]);
+ mId = static_cast<uint64_t>(buf[7]) << 32;
+ mId |= static_cast<uint32_t>(buf[8]);
- mGenerationNumber = static_cast<uint32_t>(buf[8]);
+ mGenerationNumber = static_cast<uint32_t>(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);
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 693c7cb..e333bc1 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -64,15 +64,15 @@
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 | %s\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
list.keyAt(i), rec.size/1024.0f,
- rec.width, rec.stride, rec.height, rec.format, rec.usage,
- rec.requestorName.c_str());
+ 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 | %8X | 0x%08x | %s\n",
+ snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%08x | %s\n",
list.keyAt(i),
- rec.width, rec.stride, rec.height, rec.format, rec.usage,
- rec.requestorName.c_str());
+ rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
+ rec.usage, rec.requestorName.c_str());
}
result.append(buffer);
total += rec.size;
@@ -103,21 +103,22 @@
public:
HalBuffer(const Gralloc2::Allocator* allocator,
uint32_t width, uint32_t height,
- PixelFormat format, uint32_t usage)
+ PixelFormat format, uint32_t layerCount, uint32_t usage)
: mAllocator(allocator), mBufferValid(false)
{
Gralloc2::IAllocator::BufferDescriptorInfo info = {};
info.width = width;
info.height = height;
info.format = static_cast<Gralloc2::PixelFormat>(format);
+ info.layerCount = layerCount;
info.producerUsageMask = usage;
info.consumerUsageMask = usage;
Gralloc2::BufferDescriptor descriptor;
auto error = mAllocator->createBufferDescriptor(info, descriptor);
if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to create desc (%u x %u) format %d usage %u: %d",
- width, height, format, usage, error);
+ ALOGE("Failed to create desc (%u x %u) layerCount %u format %d usage %u: %d",
+ width, height, layerCount, format, usage, error);
return;
}
@@ -127,8 +128,8 @@
}
if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
- width, height, format, usage, error);
+ ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
+ width, height, layerCount, format, usage, error);
mAllocator->destroyBufferDescriptor(descriptor);
return;
}
@@ -195,8 +196,9 @@
} // namespace
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
- PixelFormat format, uint32_t usage, buffer_handle_t* handle,
- uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
+ PixelFormat format, uint32_t layerCount, uint32_t usage,
+ buffer_handle_t* handle, uint32_t* stride, uint64_t graphicBufferId,
+ std::string requestorName)
{
ATRACE_CALL();
@@ -205,12 +207,17 @@
if (!width || !height)
width = height = 1;
+ // Ensure that layerCount is valid.
+ if (layerCount < 1)
+ layerCount = 1;
+
// Filter out any usage bits that should not be passed to the gralloc module
usage &= GRALLOC_USAGE_ALLOC_MASK;
gralloc1_error_t error;
if (mAllocator->valid()) {
- HalBuffer buffer(mAllocator.get(), width, height, format, usage);
+ HalBuffer buffer(mAllocator.get(), width, height, format, layerCount,
+ usage);
if (!buffer.exportHandle(mMapper, handle, stride)) {
return NO_MEMORY;
}
@@ -229,6 +236,17 @@
ALOGE("Failed to set format to %d: %d", format, error);
return BAD_VALUE;
}
+ if (mDevice->hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
+ error = descriptor->setLayerCount(layerCount);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set layer count to %u: %d", layerCount, error);
+ return BAD_VALUE;
+ }
+ } else if (layerCount > 1) {
+ ALOGE("Failed to set layer count to %u: capability unsupported",
+ layerCount);
+ return BAD_VALUE;
+ }
error = descriptor->setProducerUsage(
static_cast<gralloc1_producer_usage_t>(usage));
if (error != GRALLOC1_ERROR_NONE) {
@@ -244,8 +262,8 @@
error = mDevice->allocate(descriptor, graphicBufferId, handle);
if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
- width, height, format, usage, error);
+ ALOGE("Failed to allocate (%u x %u) layerCount %u format %d usage %u: %d",
+ width, height, layerCount, format, usage, error);
return NO_MEMORY;
}
@@ -264,6 +282,7 @@
rec.height = height;
rec.stride = *stride;
rec.format = format;
+ rec.layerCount = layerCount;
rec.usage = usage;
rec.size = static_cast<size_t>(height * (*stride) * bpp);
rec.requestorName = std::move(requestorName);