libui: Convert Allocator and Mapper to gralloc1
Converts GraphicBufferAllocator and GraphicBufferMapper to speak
gralloc 1.0 (via the C++ shim and optionally the 1On0 adapter) instead
of gralloc 0.x.
Bug: 28401203
Change-Id: Ie1649f0ee72801579be2c2d3c47177b52962a825
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 5443f09..62ebbd5 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -27,42 +27,41 @@
#include <utils/threads.h>
#include <utils/Singleton.h>
+#include <ui/Gralloc1.h>
#include <ui/PixelFormat.h>
-#include <hardware/gralloc.h>
-
-
namespace android {
-// ---------------------------------------------------------------------------
+class Gralloc1Loader;
class String8;
class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
{
public:
enum {
- USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER,
- USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY,
- USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN,
- USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK,
+ USAGE_SW_READ_NEVER = GRALLOC1_CONSUMER_USAGE_CPU_READ_NEVER,
+ USAGE_SW_READ_RARELY = GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ USAGE_SW_READ_OFTEN = GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
+ USAGE_SW_READ_MASK = GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
- USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER,
- USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY,
- USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN,
- USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK,
+ USAGE_SW_WRITE_NEVER = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_NEVER,
+ USAGE_SW_WRITE_RARELY = GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+ USAGE_SW_WRITE_OFTEN = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
+ USAGE_SW_WRITE_MASK = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,
- USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE,
- USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER,
- USAGE_HW_2D = GRALLOC_USAGE_HW_2D,
- USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK
+ USAGE_HW_TEXTURE = GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE,
+ USAGE_HW_RENDER = GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+ USAGE_HW_2D = 0x00000400, // Deprecated
+ USAGE_HW_MASK = 0x00071F00, // Deprecated
};
static inline GraphicBufferAllocator& get() { return getInstance(); }
- status_t alloc(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
- buffer_handle_t* handle, uint32_t* stride);
+ status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
+ uint32_t usage, buffer_handle_t* handle, uint32_t* stride,
+ uint64_t graphicBufferId);
status_t free(buffer_handle_t handle);
@@ -86,7 +85,8 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
- alloc_device_t *mAllocDev;
+ std::unique_ptr<Gralloc1::Loader> mLoader;
+ std::unique_ptr<Gralloc1::Device> mDevice;
};
// ---------------------------------------------------------------------------
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 6099548..a25809c 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -20,13 +20,10 @@
#include <stdint.h>
#include <sys/types.h>
+#include <ui/Gralloc1.h>
+
#include <utils/Singleton.h>
-#include <hardware/gralloc.h>
-
-
-struct gralloc_module_t;
-
namespace android {
// ---------------------------------------------------------------------------
@@ -39,6 +36,7 @@
static inline GraphicBufferMapper& get() { return getInstance(); }
status_t registerBuffer(buffer_handle_t handle);
+ status_t registerBuffer(const GraphicBuffer* buffer);
status_t unregisterBuffer(buffer_handle_t handle);
@@ -59,13 +57,13 @@
status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
- // dumps information about the mapping of this handle
- void dump(buffer_handle_t handle);
-
private:
friend class Singleton<GraphicBufferMapper>;
+
GraphicBufferMapper();
- gralloc_module_t const *mAllocMod;
+
+ std::unique_ptr<Gralloc1::Loader> mLoader;
+ std::unique_ptr<Gralloc1::Device> mDevice;
};
// ---------------------------------------------------------------------------
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 4fe0946..f28af6e 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -169,8 +169,8 @@
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
- status_t err = allocator.alloc(inWidth, inHeight, inFormat, inUsage,
- &handle, &outStride);
+ status_t err = allocator.allocate(inWidth, inHeight, inFormat, inUsage,
+ &handle, &outStride, mId);
if (err == NO_ERROR) {
width = static_cast<int>(inWidth);
height = static_cast<int>(inHeight);
@@ -390,7 +390,7 @@
mOwner = ownHandle;
if (handle != 0) {
- status_t err = mBufferMapper.registerBuffer(handle);
+ status_t err = mBufferMapper.registerBuffer(this);
if (err != NO_ERROR) {
width = height = stride = format = usage = 0;
handle = NULL;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 9b265af..3b83fb6 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -25,6 +25,7 @@
#include <utils/Trace.h>
#include <ui/GraphicBufferAllocator.h>
+#include <ui/Gralloc1On0Adapter.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -36,20 +37,10 @@
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);
- }
-}
+ : mLoader(std::make_unique<Gralloc1::Loader>()),
+ mDevice(mLoader->getDevice()) {}
-GraphicBufferAllocator::~GraphicBufferAllocator()
-{
- gralloc_close(mAllocDev);
-}
+GraphicBufferAllocator::~GraphicBufferAllocator() {}
void GraphicBufferAllocator::dump(String8& result) const
{
@@ -77,10 +68,8 @@
}
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);
- }
+ std::string deviceDump = mDevice->dump();
+ result.append(deviceDump.c_str(), deviceDump.size());
}
void GraphicBufferAllocator::dumpToSystemLog()
@@ -90,9 +79,9 @@
ALOGD("%s", s.string());
}
-status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height,
+status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage, buffer_handle_t* handle,
- uint32_t* stride)
+ uint32_t* stride, uint64_t graphicBufferId)
{
ATRACE_CALL();
@@ -101,22 +90,46 @@
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);
+ auto descriptor = mDevice->createDescriptor();
+ auto error = descriptor->setDimensions(width, height);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set dimensions to (%u, %u): %d", width, height, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setFormat(static_cast<android_pixel_format_t>(format));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set format to %d: %d", format, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setProducerUsage(
+ static_cast<gralloc1_producer_usage_t>(usage));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set producer usage to %u: %d", usage, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setConsumerUsage(
+ static_cast<gralloc1_consumer_usage_t>(usage));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+ return BAD_VALUE;
+ }
- ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
- width, height, format, usage, err, strerror(-err));
+ 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);
+ return NO_MEMORY;
+ }
- if (err == NO_ERROR) {
+ error = mDevice->getStride(*handle, stride);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGW("Failed to get stride from buffer: %d", error);
+ }
+
+ if (error == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
uint32_t bpp = bytesPerPixel(format);
@@ -130,24 +143,23 @@
list.add(*handle, rec);
}
- return err;
+ return NO_ERROR;
}
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);
+ auto error = mDevice->release(handle);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to free buffer: %d", error);
}
- return err;
+ Mutex::Autolock _l(sLock);
+ KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+ list.removeItem(handle);
+
+ return NO_ERROR;
}
// ---------------------------------------------------------------------------
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 90a1c11..481d43c 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "GraphicBufferMapper"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define LOG_NDEBUG 0
#include <stdint.h>
#include <errno.h>
@@ -31,11 +32,11 @@
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <ui/Gralloc1On0Adapter.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/Rect.h>
-#include <hardware/gralloc.h>
-
+#include <system/graphics.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -43,151 +44,247 @@
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);
- }
-}
+ : mLoader(std::make_unique<Gralloc1::Loader>()),
+ mDevice(mLoader->getDevice()) {}
+
+
status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
{
ATRACE_CALL();
- status_t err;
- err = mAllocMod->registerBuffer(mAllocMod, handle);
+ gralloc1_error_t error = mDevice->retain(handle);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
+ handle, error);
- ALOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
- handle, err, strerror(-err));
- return err;
+ return error;
+}
+
+status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
+{
+ ATRACE_CALL();
+
+ gralloc1_error_t error = mDevice->retain(buffer);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
+ buffer->getNativeBuffer()->handle, error);
+
+ return error;
}
status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
{
ATRACE_CALL();
- status_t err;
- err = mAllocMod->unregisterBuffer(mAllocMod, handle);
+ gralloc1_error_t error = mDevice->release(handle);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
+ handle, error);
- ALOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
- handle, err, strerror(-err));
- return err;
+ return error;
}
-status_t GraphicBufferMapper::lock(buffer_handle_t handle,
- uint32_t 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;
+static inline gralloc1_rect_t asGralloc1Rect(const Rect& rect) {
+ gralloc1_rect_t outRect{};
+ outRect.left = rect.left;
+ outRect.top = rect.top;
+ outRect.width = rect.width();
+ outRect.height = rect.height();
+ return outRect;
}
-status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle,
- uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr)
+status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
+ const Rect& bounds, void** vaddr)
{
- ATRACE_CALL();
- status_t err;
+ return lockAsync(handle, usage, bounds, vaddr, -1);
+}
- 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::lockYCbCr(buffer_handle_t handle, uint32_t usage,
+ const Rect& bounds, android_ycbcr *ycbcr)
+{
+ return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
}
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;
+ int32_t fenceFd = -1;
+ status_t error = unlockAsync(handle, &fenceFd);
+ if (error == NO_ERROR) {
+ sync_wait(fenceFd, -1);
+ close(fenceFd);
+ }
+ return error;
}
status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
{
ATRACE_CALL();
- status_t err;
- if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
- err = mAllocMod->lockAsync(mAllocMod, handle, static_cast<int>(usage),
- bounds.left, bounds.top, bounds.width(), bounds.height(),
- vaddr, fenceFd);
- } else {
- if (fenceFd >= 0) {
- sync_wait(fenceFd, -1);
- close(fenceFd);
- }
- err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
- bounds.left, bounds.top, bounds.width(), bounds.height(),
- vaddr);
+ gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
+ sp<Fence> fence = new Fence(fenceFd);
+ gralloc1_error_t error = mDevice->lock(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, vaddr, fence);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
+ error);
+
+ return error;
+}
+
+static inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
+ if (plane.bits_per_component != 8) {
+ ALOGV("Invalid number of bits per component: %d",
+ plane.bits_per_component);
+ return false;
+ }
+ if (plane.bits_used != 8) {
+ ALOGV("Invalid number of bits used: %d", plane.bits_used);
+ return false;
}
- ALOGW_IF(err, "lockAsync(...) failed %d (%s)", err, strerror(-err));
- return err;
+ bool hasValidIncrement = plane.h_increment == 1 ||
+ (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
+ hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
+ if (!hasValidIncrement) {
+ ALOGV("Invalid increment: h %d v %d", plane.h_increment,
+ plane.v_increment);
+ return false;
+ }
+
+ return true;
}
status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
{
ATRACE_CALL();
- status_t err;
- if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3
- && mAllocMod->lockAsync_ycbcr != NULL) {
- err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle,
- static_cast<int>(usage), bounds.left, bounds.top,
- bounds.width(), bounds.height(), ycbcr, fenceFd);
- } else if (mAllocMod->lock_ycbcr != NULL) {
- if (fenceFd >= 0) {
- sync_wait(fenceFd, -1);
- close(fenceFd);
- }
- err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
- bounds.left, bounds.top, bounds.width(), bounds.height(),
- ycbcr);
- } else {
- if (fenceFd >= 0) {
- close(fenceFd);
- }
- return -EINVAL; // do not log failure
+ gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
+ sp<Fence> fence = new Fence(fenceFd);
+
+ if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+ gralloc1_error_t error = mDevice->lockYCbCr(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, ycbcr, fence);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lockYCbCr(%p, ...) failed: %d",
+ handle, error);
+ return error;
}
- ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
- return err;
+ uint32_t numPlanes = 0;
+ gralloc1_error_t error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGV("Failed to retrieve number of flex planes: %d", error);
+ return error;
+ }
+ if (numPlanes < 3) {
+ ALOGV("Not enough planes for YCbCr (%u found)", numPlanes);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+
+ std::vector<android_flex_plane_t> planes(numPlanes);
+ android_flex_layout_t flexLayout{};
+ flexLayout.num_planes = numPlanes;
+ flexLayout.planes = planes.data();
+
+ error = mDevice->lockFlex(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, &flexLayout, fence);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
+ return error;
+ }
+ if (flexLayout.format != FLEX_FORMAT_YCbCr) {
+ ALOGV("Unable to convert flex-format buffer to YCbCr");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+
+ // Find planes
+ auto yPlane = planes.cend();
+ auto cbPlane = planes.cend();
+ auto crPlane = planes.cend();
+ for (auto planeIter = planes.cbegin(); planeIter != planes.cend();
+ ++planeIter) {
+ if (planeIter->component == FLEX_COMPONENT_Y) {
+ yPlane = planeIter;
+ } else if (planeIter->component == FLEX_COMPONENT_Cb) {
+ cbPlane = planeIter;
+ } else if (planeIter->component == FLEX_COMPONENT_Cr) {
+ crPlane = planeIter;
+ }
+ }
+ if (yPlane == planes.cend()) {
+ ALOGV("Unable to find Y plane");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (cbPlane == planes.cend()) {
+ ALOGV("Unable to find Cb plane");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (crPlane == planes.cend()) {
+ ALOGV("Unable to find Cr plane");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+
+ // Validate planes
+ if (!isValidYCbCrPlane(*yPlane)) {
+ ALOGV("Y plane is invalid");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (!isValidYCbCrPlane(*cbPlane)) {
+ ALOGV("Cb plane is invalid");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (!isValidYCbCrPlane(*crPlane)) {
+ ALOGV("Cr plane is invalid");
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (cbPlane->v_increment != crPlane->v_increment) {
+ ALOGV("Cb and Cr planes have different step (%d vs. %d)",
+ cbPlane->v_increment, crPlane->v_increment);
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ if (cbPlane->h_increment != crPlane->h_increment) {
+ ALOGV("Cb and Cr planes have different stride (%d vs. %d)",
+ cbPlane->h_increment, crPlane->h_increment);
+ unlock(handle);
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ }
+
+ // Pack plane data into android_ycbcr struct
+ ycbcr->y = yPlane->top_left;
+ ycbcr->cb = cbPlane->top_left;
+ ycbcr->cr = crPlane->top_left;
+ ycbcr->ystride = static_cast<size_t>(yPlane->v_increment);
+ ycbcr->cstride = static_cast<size_t>(cbPlane->v_increment);
+ ycbcr->chroma_step = static_cast<size_t>(cbPlane->h_increment);
+
+ return error;
}
status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
{
ATRACE_CALL();
- status_t err;
- if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
- err = mAllocMod->unlockAsync(mAllocMod, handle, fenceFd);
- } else {
- *fenceFd = -1;
- err = mAllocMod->unlock(mAllocMod, handle);
+ sp<Fence> fence = Fence::NO_FENCE;
+ gralloc1_error_t error = mDevice->unlock(handle, &fence);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("unlock(%p) failed: %d", handle, error);
+ return error;
}
- ALOGW_IF(err, "unlockAsync(...) failed %d (%s)", err, strerror(-err));
- return err;
+ *fenceFd = fence->dup();
+ return error;
}
// ---------------------------------------------------------------------------