Adding lock function that obtains bytesPerPixel and bytesPerStride
Bug: 123423521
Test: build, boot, manual
Change-Id: I480d60fe4975c5ffee6d6c253c37ffd20cea79c3
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 52fc9d5..bf80481 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -93,8 +93,57 @@
outDesc->rfu1 = 0;
}
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, void** outVirtualAddress,
+ int32_t* outBytesPerPixel, int32_t* outBytesPerStride) {
+ if (!buffer) return BAD_VALUE;
+
+ if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
+ ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+ "AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
+ return BAD_VALUE;
+ }
+
+ usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+ GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+
+ //Mapper implementations before 3.0 will not return bytes per pixel or
+ //bytes per stride information.
+ if (gbuffer->getBufferMapperVersion() == GraphicBufferMapper::Version::GRALLOC_2) {
+ ALOGE("Mapper versions before 3.0 cannot retrieve bytes per pixel and bytes per stride info");
+ return INVALID_OPERATION;
+ }
+
+ if (gbuffer->getLayerCount() > 1) {
+ ALOGE("Buffer with multiple layers passed to AHardwareBuffer_lock; "
+ "only buffers with one layer are allowed");
+ return INVALID_OPERATION;
+ }
+
+ Rect bounds;
+ if (!rect) {
+ bounds.set(Rect(gbuffer->getWidth(), gbuffer->getHeight()));
+ } else {
+ bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+ }
+ int result = gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, outBytesPerPixel, outBytesPerStride);
+
+ // if hardware returns -1 for bytes per pixel or bytes per stride, we fail
+ // and unlock the buffer
+ if (*outBytesPerPixel == -1 || *outBytesPerStride == -1) {
+ gbuffer->unlock();
+ return INVALID_OPERATION;
+ }
+
+ return result;
+}
+
int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
- int32_t fence, const ARect* rect, void** outVirtualAddress) {
+ int32_t fence, const ARect* rect, void** outVirtualAddress) {
+ int32_t bytesPerPixel;
+ int32_t bytesPerStride;
+
if (!buffer) return BAD_VALUE;
if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
@@ -119,7 +168,7 @@
} else {
bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
}
- return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
+ return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, &bytesPerPixel, &bytesPerStride);
}
int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 02c7c1b..165b75a 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -422,6 +422,18 @@
int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
/**
+ * Lock an AHardwareBuffer for direct CPU access.
+ *
+ * This function is the same as the above lock function, but passes back
+ * additional information about the bytes per pixel and the bytes per stride
+ * of the locked buffer. If the bytes per pixel or bytes per stride are unknown
+ * or variable, or if the underlying mapper implementation does not support returning
+ * additional information, then this call will fail with INVALID_OPERATION
+ */
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, void** outVirtualAddress,
+ int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29);
+/**
* Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
*
* This function is similar to AHardwareBuffer_lock, but can lock multi-planar
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index a796e97..23a05f3 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -7,6 +7,7 @@
AHardwareBuffer_getNativeHandle; # vndk
AHardwareBuffer_isSupported; # introduced=29
AHardwareBuffer_lock;
+ AHardwareBuffer_lockAndGetInfo; # introduced=29
AHardwareBuffer_recvHandleFromUnixSocket;
AHardwareBuffer_release;
AHardwareBuffer_sendHandleToUnixSocket;