graphics: rewrite libgralloc1-adapter
Rewrite libgralloc1-adapter to be based on Gralloc1On0Adapter.
Previously, the adapter targeted maximum portability and maximum
performance. The rewritten adapter targets ease of use instead.
This also fixes a bug in the adapter's GRALLOC1_FUNCTION_RELEASE. The
function does not imply native_handle_close/native_handle_delete. As a
result, IMapper and IComposer are also fixed to close/delete handles.
Test: builds and boots
Change-Id: I5c071453dc950583087ae07967bca2c22866c538
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 994feb3..f0c736c 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -34,7 +34,7 @@
cc_library_static {
name: "libgralloc1-adapter",
- srcs: ["gralloc1-adapter.c"],
+ srcs: ["gralloc1-adapter.cpp", "Gralloc1On0Adapter.cpp"],
include_dirs: ["system/core/libsync/include"],
cflags: ["-Wall", "-Wextra", "-Wno-unused-parameter"],
export_include_dirs: ["."],
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp b/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
index a0bbe63..4b9c9e1 100644
--- a/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
+++ b/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
@@ -18,11 +18,13 @@
#define LOG_TAG "Gralloc1On0Adapter"
//#define LOG_NDEBUG 0
+#include "Gralloc1On0Adapter.h"
+#include "gralloc1-adapter.h"
+
#include <hardware/gralloc.h>
-#include <ui/Gralloc1On0Adapter.h>
-
#include <utils/Log.h>
+#include <sync/sync.h>
#include <inttypes.h>
@@ -34,13 +36,26 @@
}
namespace android {
+namespace hardware {
Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
- : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
- mMinorVersion(mModule->common.module_api_version & 0xFF),
+ : gralloc1_device_t(),
+ mModule(reinterpret_cast<const gralloc_module_t*>(module)),
mDevice(nullptr)
{
ALOGV("Constructing");
+
+ int minor = 0;
+ mModule->perform(mModule,
+ GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR,
+ &minor);
+ mMinorVersion = minor;
+
+ common.tag = HARDWARE_DEVICE_TAG,
+ common.version = HARDWARE_DEVICE_API_VERSION(0, 0),
+ common.module = const_cast<struct hw_module_t*>(module),
+ common.close = closeHook,
+
getCapabilities = getCapabilitiesHook;
getFunction = getFunctionHook;
int error = ::gralloc_open(&(mModule->common), &mDevice);
@@ -62,21 +77,14 @@
void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
int32_t* outCapabilities)
{
- if (outCapabilities == nullptr) {
- *outCount = 1;
- return;
- }
- if (*outCount >= 1) {
- *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
- *outCount = 1;
- }
+ *outCount = 0;
}
gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
int32_t intDescriptor)
{
constexpr auto lastDescriptor =
- static_cast<int32_t>(GRALLOC1_LAST_ADAPTER_FUNCTION);
+ static_cast<int32_t>(GRALLOC1_LAST_FUNCTION);
if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
ALOGE("Invalid function descriptor");
return nullptr;
@@ -126,23 +134,15 @@
bufferHook<decltype(&Buffer::getStride),
&Buffer::getStride, uint32_t*>);
case GRALLOC1_FUNCTION_ALLOCATE:
- // Not provided, since we'll use ALLOCATE_WITH_ID
- return nullptr;
- case GRALLOC1_FUNCTION_ALLOCATE_WITH_ID:
if (mDevice != nullptr) {
- return asFP<GRALLOC1_PFN_ALLOCATE_WITH_ID>(allocateWithIdHook);
+ return asFP<GRALLOC1_PFN_ALLOCATE>(allocateHook);
} else {
return nullptr;
}
case GRALLOC1_FUNCTION_RETAIN:
- return asFP<GRALLOC1_PFN_RETAIN>(
- managementHook<&Gralloc1On0Adapter::retain>);
+ return asFP<GRALLOC1_PFN_RETAIN>(retainHook);
case GRALLOC1_FUNCTION_RELEASE:
- return asFP<GRALLOC1_PFN_RELEASE>(
- managementHook<&Gralloc1On0Adapter::release>);
- case GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER:
- return asFP<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER>(
- retainGraphicBufferHook);
+ return asFP<GRALLOC1_PFN_RELEASE>(releaseHook);
case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(
bufferHook<decltype(&Buffer::getNumFlexPlanes),
@@ -154,10 +154,6 @@
return asFP<GRALLOC1_PFN_LOCK_FLEX>(
lockHook<struct android_flex_layout,
&Gralloc1On0Adapter::lockFlex>);
- case GRALLOC1_FUNCTION_LOCK_YCBCR:
- return asFP<GRALLOC1_PFN_LOCK_YCBCR>(
- lockHook<struct android_ycbcr,
- &Gralloc1On0Adapter::lockYCbCr>);
case GRALLOC1_FUNCTION_UNLOCK:
return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
case GRALLOC1_FUNCTION_INVALID:
@@ -200,8 +196,7 @@
{
auto descriptorId = sNextBufferDescriptorId++;
std::lock_guard<std::mutex> lock(mDescriptorMutex);
- mDescriptors.emplace(descriptorId,
- std::make_shared<Descriptor>(this, descriptorId));
+ mDescriptors.emplace(descriptorId, std::make_shared<Descriptor>());
ALOGV("Created descriptor %" PRIu64, descriptorId);
@@ -225,20 +220,21 @@
Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle,
gralloc1_backing_store_t store, const Descriptor& descriptor,
- uint32_t stride, bool wasAllocated)
+ uint32_t stride, uint32_t numFlexPlanes, bool wasAllocated)
: mHandle(handle),
mReferenceCount(1),
mStore(store),
mDescriptor(descriptor),
mStride(stride),
+ mNumFlexPlanes(numFlexPlanes),
mWasAllocated(wasAllocated) {}
gralloc1_error_t Gralloc1On0Adapter::allocate(
+ gralloc1_buffer_descriptor_t id,
const std::shared_ptr<Descriptor>& descriptor,
- gralloc1_backing_store_t store,
buffer_handle_t* outBufferHandle)
{
- ALOGV("allocate(%" PRIu64 ", %#" PRIx64 ")", descriptor->id, store);
+ ALOGV("allocate(%" PRIu64 ")", id);
// If this function is being called, it's because we handed out its function
// pointer, which only occurs when mDevice has been loaded successfully and
@@ -260,9 +256,21 @@
return GRALLOC1_ERROR_NO_RESOURCES;
}
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_SET_USAGES,
+ handle,
+ static_cast<int>(descriptor->producerUsage),
+ static_cast<int>(descriptor->consumerUsage));
+
+ uint64_t backingStore = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
+ handle, &backingStore);
+ int numFlexPlanes = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
+ handle, &numFlexPlanes);
+
*outBufferHandle = handle;
- auto buffer = std::make_shared<Buffer>(handle, store, *descriptor, stride,
- true);
+ auto buffer = std::make_shared<Buffer>(handle, backingStore,
+ *descriptor, stride, numFlexPlanes, true);
std::lock_guard<std::mutex> lock(mBufferMutex);
mBuffers.emplace(handle, std::move(buffer));
@@ -270,24 +278,46 @@
return GRALLOC1_ERROR_NONE;
}
-gralloc1_error_t Gralloc1On0Adapter::allocateWithIdHook(
- gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptorId,
- gralloc1_backing_store_t store, buffer_handle_t* outBuffer)
+int32_t Gralloc1On0Adapter::allocateHook(gralloc1_device* device,
+ uint32_t numDescriptors,
+ const gralloc1_buffer_descriptor_t* descriptors,
+ buffer_handle_t* outBuffers)
{
+ if (!outBuffers) {
+ return GRALLOC1_ERROR_UNDEFINED;
+ }
+
auto adapter = getAdapter(device);
- auto descriptor = adapter->getDescriptor(descriptorId);
- if (!descriptor) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+ gralloc1_error_t error = GRALLOC1_ERROR_NONE;
+ uint32_t i;
+ for (i = 0; i < numDescriptors; i++) {
+ auto descriptor = adapter->getDescriptor(descriptors[i]);
+ if (!descriptor) {
+ error = GRALLOC1_ERROR_BAD_DESCRIPTOR;
+ break;
+ }
+
+ buffer_handle_t bufferHandle = nullptr;
+ error = adapter->allocate(descriptors[i], descriptor, &bufferHandle);
+ if (error != GRALLOC1_ERROR_NONE) {
+ break;
+ }
+
+ outBuffers[i] = bufferHandle;
}
- buffer_handle_t bufferHandle = nullptr;
- auto error = adapter->allocate(descriptor, store, &bufferHandle);
- if (error != GRALLOC1_ERROR_NONE) {
- return error;
+ if (error == GRALLOC1_ERROR_NONE) {
+ if (numDescriptors > 1) {
+ error = GRALLOC1_ERROR_NOT_SHARED;
+ }
+ } else {
+ for (uint32_t j = 0; j < i; j++) {
+ adapter->release(adapter->getBuffer(outBuffers[j]));
+ outBuffers[j] = nullptr;
+ }
}
- *outBuffer = bufferHandle;
return error;
}
@@ -326,58 +356,97 @@
return GRALLOC1_ERROR_NONE;
}
-gralloc1_error_t Gralloc1On0Adapter::retain(
- const android::GraphicBuffer* graphicBuffer)
+gralloc1_error_t Gralloc1On0Adapter::retain(buffer_handle_t bufferHandle)
{
- ALOGV("retainGraphicBuffer(%p, %#" PRIx64 ")",
- graphicBuffer->getNativeBuffer()->handle, graphicBuffer->getId());
+ ALOGV("retain(%p)", bufferHandle);
- buffer_handle_t handle = graphicBuffer->getNativeBuffer()->handle;
std::lock_guard<std::mutex> lock(mBufferMutex);
- if (mBuffers.count(handle) != 0) {
- mBuffers[handle]->retain();
+
+ if (mBuffers.count(bufferHandle) != 0) {
+ mBuffers[bufferHandle]->retain();
return GRALLOC1_ERROR_NONE;
}
- ALOGV("Calling registerBuffer(%p)", handle);
- int result = mModule->registerBuffer(mModule, handle);
+ ALOGV("Calling registerBuffer(%p)", bufferHandle);
+ int result = mModule->registerBuffer(mModule, bufferHandle);
if (result != 0) {
ALOGE("gralloc0 register failed: %d", result);
return GRALLOC1_ERROR_NO_RESOURCES;
}
- Descriptor descriptor{this, sNextBufferDescriptorId++};
- descriptor.setDimensions(graphicBuffer->getWidth(),
- graphicBuffer->getHeight());
- descriptor.setFormat(graphicBuffer->getPixelFormat());
+ uint64_t backingStore = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
+ bufferHandle, &backingStore);
+
+ int numFlexPlanes = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
+ bufferHandle, &numFlexPlanes);
+
+ int stride = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_STRIDE,
+ bufferHandle, &stride);
+
+ int width = 0;
+ int height = 0;
+ int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ int producerUsage = 0;
+ int consumerUsage = 0;
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS,
+ bufferHandle, &width, &height);
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_FORMAT,
+ bufferHandle, &format);
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE,
+ bufferHandle, &producerUsage);
+ mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE,
+ bufferHandle, &consumerUsage);
+
+ Descriptor descriptor;
+ descriptor.setDimensions(width, height);
+ descriptor.setFormat(format);
descriptor.setProducerUsage(
- static_cast<gralloc1_producer_usage_t>(graphicBuffer->getUsage()));
+ static_cast<gralloc1_producer_usage_t>(producerUsage));
descriptor.setConsumerUsage(
- static_cast<gralloc1_consumer_usage_t>(graphicBuffer->getUsage()));
- auto buffer = std::make_shared<Buffer>(handle,
- static_cast<gralloc1_backing_store_t>(graphicBuffer->getId()),
- descriptor, graphicBuffer->getStride(), false);
- mBuffers.emplace(handle, std::move(buffer));
+ static_cast<gralloc1_consumer_usage_t>(consumerUsage));
+
+ auto buffer = std::make_shared<Buffer>(bufferHandle, backingStore,
+ descriptor, stride, numFlexPlanes, false);
+ mBuffers.emplace(bufferHandle, std::move(buffer));
return GRALLOC1_ERROR_NONE;
}
+static void syncWaitForever(int fd, const char* logname)
+{
+ if (fd < 0) {
+ return;
+ }
+
+ const int warningTimeout = 3500;
+ const int error = sync_wait(fd, warningTimeout);
+ if (error < 0 && errno == ETIME) {
+ ALOGE("%s: fence %d didn't signal in %u ms", logname, fd,
+ warningTimeout);
+ sync_wait(fd, -1);
+ }
+}
+
gralloc1_error_t Gralloc1On0Adapter::lock(
const std::shared_ptr<Buffer>& buffer,
gralloc1_producer_usage_t producerUsage,
gralloc1_consumer_usage_t consumerUsage,
const gralloc1_rect_t& accessRegion, void** outData,
- const sp<Fence>& acquireFence)
+ int acquireFence)
{
if (mMinorVersion >= 3) {
int result = mModule->lockAsync(mModule, buffer->getHandle(),
static_cast<int32_t>(producerUsage | consumerUsage),
accessRegion.left, accessRegion.top, accessRegion.width,
- accessRegion.height, outData, acquireFence->dup());
+ accessRegion.height, outData, acquireFence);
if (result != 0) {
return GRALLOC1_ERROR_UNSUPPORTED;
}
} else {
- acquireFence->waitForever("Gralloc1On0Adapter::lock");
+ syncWaitForever(acquireFence, "Gralloc1On0Adapter::lock");
+
int result = mModule->lock(mModule, buffer->getHandle(),
static_cast<int32_t>(producerUsage | consumerUsage),
accessRegion.left, accessRegion.top, accessRegion.width,
@@ -385,50 +454,53 @@
ALOGV("gralloc0 lock returned %d", result);
if (result != 0) {
return GRALLOC1_ERROR_UNSUPPORTED;
+ } else if (acquireFence >= 0) {
+ close(acquireFence);
}
}
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t Gralloc1On0Adapter::lockFlex(
- const std::shared_ptr<Buffer>& /*buffer*/,
- gralloc1_producer_usage_t /*producerUsage*/,
- gralloc1_consumer_usage_t /*consumerUsage*/,
- const gralloc1_rect_t& /*accessRegion*/,
- struct android_flex_layout* /*outData*/,
- const sp<Fence>& /*acquireFence*/)
-{
- // TODO
- return GRALLOC1_ERROR_UNSUPPORTED;
-}
-
-gralloc1_error_t Gralloc1On0Adapter::lockYCbCr(
const std::shared_ptr<Buffer>& buffer,
gralloc1_producer_usage_t producerUsage,
gralloc1_consumer_usage_t consumerUsage,
- const gralloc1_rect_t& accessRegion, struct android_ycbcr* outData,
- const sp<Fence>& acquireFence)
+ const gralloc1_rect_t& accessRegion,
+ struct android_flex_layout* outFlex,
+ int acquireFence)
{
- if (mMinorVersion >= 3 && mModule->lockAsync_ycbcr) {
- int result = mModule->lockAsync_ycbcr(mModule, buffer->getHandle(),
- static_cast<int>(producerUsage | consumerUsage),
- accessRegion.left, accessRegion.top, accessRegion.width,
- accessRegion.height, outData, acquireFence->dup());
- if (result != 0) {
- return GRALLOC1_ERROR_UNSUPPORTED;
- }
- } else if (mModule->lock_ycbcr) {
- acquireFence->waitForever("Gralloc1On0Adapter::lockYCbCr");
- int result = mModule->lock_ycbcr(mModule, buffer->getHandle(),
- static_cast<int>(producerUsage | consumerUsage),
- accessRegion.left, accessRegion.top, accessRegion.width,
- accessRegion.height, outData);
- ALOGV("gralloc0 lockYCbCr returned %d", result);
+ if (mMinorVersion >= 3) {
+ int result = mModule->perform(mModule,
+ GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
+ buffer->getHandle(),
+ static_cast<int>(producerUsage),
+ static_cast<int>(consumerUsage),
+ accessRegion.left,
+ accessRegion.top,
+ accessRegion.width,
+ accessRegion.height,
+ outFlex, acquireFence);
if (result != 0) {
return GRALLOC1_ERROR_UNSUPPORTED;
}
} else {
- return GRALLOC1_ERROR_UNSUPPORTED;
+ syncWaitForever(acquireFence, "Gralloc1On0Adapter::lockFlex");
+
+ int result = mModule->perform(mModule,
+ GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
+ buffer->getHandle(),
+ static_cast<int>(producerUsage),
+ static_cast<int>(consumerUsage),
+ accessRegion.left,
+ accessRegion.top,
+ accessRegion.width,
+ accessRegion.height,
+ outFlex, -1);
+ if (result != 0) {
+ return GRALLOC1_ERROR_UNSUPPORTED;
+ } else if (acquireFence >= 0) {
+ close(acquireFence);
+ }
}
return GRALLOC1_ERROR_NONE;
@@ -436,7 +508,7 @@
gralloc1_error_t Gralloc1On0Adapter::unlock(
const std::shared_ptr<Buffer>& buffer,
- sp<Fence>* outReleaseFence)
+ int* outReleaseFence)
{
if (mMinorVersion >= 3) {
int fenceFd = -1;
@@ -446,12 +518,14 @@
close(fenceFd);
ALOGE("gralloc0 unlockAsync failed: %d", result);
} else {
- *outReleaseFence = new Fence(fenceFd);
+ *outReleaseFence = fenceFd;
}
} else {
int result = mModule->unlock(mModule, buffer->getHandle());
if (result != 0) {
ALOGE("gralloc0 unlock failed: %d", result);
+ } else {
+ *outReleaseFence = -1;
}
}
return GRALLOC1_ERROR_NONE;
@@ -482,4 +556,5 @@
std::atomic<gralloc1_buffer_descriptor_t>
Gralloc1On0Adapter::sNextBufferDescriptorId(1);
+} // namespace hardware
} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.h b/graphics/allocator/2.0/default/Gralloc1On0Adapter.h
index 2508ce9..180015d 100644
--- a/graphics/allocator/2.0/default/Gralloc1On0Adapter.h
+++ b/graphics/allocator/2.0/default/Gralloc1On0Adapter.h
@@ -14,49 +14,24 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
-#define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
-
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
+#ifndef ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
+#define ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
#include <hardware/gralloc1.h>
+#include <log/log.h>
+#include <atomic>
+#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
-#include <vector>
+#include <utility>
struct gralloc_module_t;
-
-// This is not an "official" capability (i.e., it is not found in gralloc1.h),
-// but we will use it to detect that we are running through the adapter, which
-// is capable of collaborating with GraphicBuffer such that queries on a
-// buffer_handle_t succeed
-static const auto GRALLOC1_CAPABILITY_ON_ADAPTER =
- static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1);
-
-static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER =
- static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1);
-static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID =
- static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2);
-static const auto GRALLOC1_FUNCTION_LOCK_YCBCR =
- static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3);
-static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR;
-
-typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)(
- gralloc1_device_t* device, const android::GraphicBuffer* buffer);
-typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)(
- gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
- gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
-typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)(
- gralloc1_device_t* device, buffer_handle_t buffer,
- uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
- uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
- const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr,
- int32_t acquireFence);
+struct alloc_device_t;
namespace android {
+namespace hardware {
class Gralloc1On0Adapter : public gralloc1_device_t
{
@@ -73,6 +48,11 @@
return static_cast<Gralloc1On0Adapter*>(device);
}
+ static int closeHook(struct hw_device_t* device) {
+ delete getAdapter(reinterpret_cast<gralloc1_device_t*>(device));
+ return 0;
+ }
+
// getCapabilities
void doGetCapabilities(uint32_t* outCount,
@@ -124,11 +104,8 @@
// Buffer descriptor modification functions
struct Descriptor : public std::enable_shared_from_this<Descriptor> {
- Descriptor(Gralloc1On0Adapter* _adapter,
- gralloc1_buffer_descriptor_t _id)
- : adapter(_adapter),
- id(_id),
- width(0),
+ Descriptor()
+ : width(0),
height(0),
format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
layerCount(1),
@@ -161,9 +138,6 @@
return GRALLOC1_ERROR_NONE;
}
- Gralloc1On0Adapter* const adapter;
- const gralloc1_buffer_descriptor_t id;
-
uint32_t width;
uint32_t height;
int32_t format;
@@ -223,7 +197,7 @@
public:
Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
const Descriptor& descriptor, uint32_t stride,
- bool wasAllocated);
+ uint32_t numFlexPlanes, bool wasAllocated);
buffer_handle_t getHandle() const { return mHandle; }
@@ -265,9 +239,7 @@
}
gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
- // TODO: This is conservative, and we could do better by examining
- // the format, but it won't hurt anything for now
- *outNumPlanes = 4;
+ *outNumPlanes = mNumFlexPlanes;
return GRALLOC1_ERROR_NONE;
}
@@ -287,13 +259,10 @@
const buffer_handle_t mHandle;
size_t mReferenceCount;
- // Since we're adapting to gralloc0, there will always be a 1:1
- // correspondence between buffer handles and backing stores, and the
- // backing store ID will be the same as the GraphicBuffer unique ID
const gralloc1_backing_store_t mStore;
-
const Descriptor mDescriptor;
const uint32_t mStride;
+ const uint32_t mNumFlexPlanes;
// Whether this buffer allocated in this process (as opposed to just
// being retained here), which determines whether to free or unregister
@@ -325,7 +294,7 @@
auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
auto error = callBufferFunction(device, bufferHandle,
&Buffer::getConsumerUsage, &usage);
- if (error != GRALLOC1_ERROR_NONE) {
+ if (error == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<uint64_t>(usage);
}
return error;
@@ -336,7 +305,7 @@
auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
auto error = callBufferFunction(device, bufferHandle,
&Buffer::getProducerUsage, &usage);
- if (error != GRALLOC1_ERROR_NONE) {
+ if (error == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<uint64_t>(usage);
}
return error;
@@ -344,23 +313,26 @@
// Buffer management functions
- // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be
- // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID
gralloc1_error_t allocate(
+ gralloc1_buffer_descriptor_t id,
const std::shared_ptr<Descriptor>& descriptor,
- gralloc1_backing_store_t id,
buffer_handle_t* outBufferHandle);
- static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device,
- gralloc1_buffer_descriptor_t descriptors,
- gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
+ static int32_t allocateHook(gralloc1_device* device,
+ uint32_t numDescriptors,
+ const gralloc1_buffer_descriptor_t* descriptors,
+ buffer_handle_t* outBuffers);
gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
- gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
+ gralloc1_error_t retain(buffer_handle_t bufferHandle);
+ static int32_t retainHook(gralloc1_device_t* device,
+ buffer_handle_t bufferHandle)
+ {
+ auto adapter = getAdapter(device);
+ return adapter->retain(bufferHandle);
+ }
- // Member function pointer 'member' will either be retain or release
- template <gralloc1_error_t (Gralloc1On0Adapter::*member)(
- const std::shared_ptr<Buffer>& buffer)>
- static int32_t managementHook(gralloc1_device_t* device,
+ gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
+ static int32_t releaseHook(gralloc1_device_t* device,
buffer_handle_t bufferHandle) {
auto adapter = getAdapter(device);
@@ -369,41 +341,28 @@
return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
}
- auto error = ((*adapter).*member)(buffer);
+ auto error = adapter->release(buffer);
return static_cast<int32_t>(error);
}
- gralloc1_error_t retain(const GraphicBuffer* buffer);
- static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device,
- const GraphicBuffer* buffer) {
- auto adapter = getAdapter(device);
- return adapter->retain(buffer);
- }
-
// Buffer access functions
gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
gralloc1_producer_usage_t producerUsage,
gralloc1_consumer_usage_t consumerUsage,
const gralloc1_rect_t& accessRegion, void** outData,
- const sp<Fence>& acquireFence);
+ int acquireFence);
gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
gralloc1_producer_usage_t producerUsage,
gralloc1_consumer_usage_t consumerUsage,
const gralloc1_rect_t& accessRegion,
struct android_flex_layout* outFlex,
- const sp<Fence>& acquireFence);
- gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer,
- gralloc1_producer_usage_t producerUsage,
- gralloc1_consumer_usage_t consumerUsage,
- const gralloc1_rect_t& accessRegion,
- struct android_ycbcr* outFlex,
- const sp<Fence>& acquireFence);
+ int acquireFence);
template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
- const sp<Fence>&)>
+ int)>
static int32_t lockHook(gralloc1_device_t* device,
buffer_handle_t bufferHandle,
uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
@@ -452,14 +411,13 @@
return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
}
- sp<Fence> acquireFence{new Fence(acquireFenceFd)};
auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
- *accessRegion, outData, acquireFence);
+ *accessRegion, outData, acquireFenceFd);
return static_cast<int32_t>(error);
}
gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
- sp<Fence>* outReleaseFence);
+ int* outReleaseFence);
static int32_t unlockHook(gralloc1_device_t* device,
buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
auto adapter = getAdapter(device);
@@ -469,10 +427,10 @@
return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
}
- sp<Fence> releaseFence = Fence::NO_FENCE;
+ int releaseFence = -1;
auto error = adapter->unlock(buffer, &releaseFence);
if (error == GRALLOC1_ERROR_NONE) {
- *outReleaseFenceFd = releaseFence->dup();
+ *outReleaseFenceFd = releaseFence;
}
return static_cast<int32_t>(error);
}
@@ -494,6 +452,7 @@
std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
};
+} // namespace hardware
} // namespace android
-#endif
+#endif // ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.c b/graphics/allocator/2.0/default/gralloc1-adapter.c
deleted file mode 100644
index 724cd47..0000000
--- a/graphics/allocator/2.0/default/gralloc1-adapter.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Gralloc1Adapter"
-
-#include <stdatomic.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <pthread.h>
-
-#include <cutils/native_handle.h>
-#include <hardware/gralloc1.h>
-#include <sync/sync.h>
-#include <log/log.h>
-
-#include "gralloc1-adapter.h"
-
-struct gralloc1_adapter_module {
- struct gralloc_module_t base;
- struct gralloc1_adapter adapter;
-};
-
-struct gralloc1_adapter_device {
- struct gralloc1_device base;
-
- struct alloc_device_t* alloc_dev;
-
- /* fixed size for thread safety */
- char saved_dump[4096];
- size_t saved_dump_size;
-};
-
-/* additional data associated with registered buffer_handle_t */
-struct gralloc1_adapter_buffer_data {
- struct gralloc1_adapter_buffer_info info;
-
- atomic_int refcount;
- bool owned;
-};
-
-struct gralloc1_adapter_buffer_descriptor {
- int width;
- int height;
- int format;
- int producer_usage;
- int consumer_usage;
-};
-
-static const struct gralloc1_adapter_module* gralloc1_adapter_module(
- struct gralloc1_device* dev)
-{
- return (const struct gralloc1_adapter_module*) dev->common.module;
-}
-
-static struct gralloc1_adapter_device* gralloc1_adapter_device(
- struct gralloc1_device* dev)
-{
- return (struct gralloc1_adapter_device*) dev;
-}
-
-static struct gralloc1_adapter_buffer_data* lookup_buffer_data(
- struct gralloc1_device* dev, buffer_handle_t buffer)
-{
- const struct gralloc1_adapter_module* mod = gralloc1_adapter_module(dev);
- if (!mod->adapter.is_registered(&mod->base, buffer))
- return NULL;
-
- return mod->adapter.get_data(&mod->base, buffer);
-}
-
-static struct gralloc1_adapter_buffer_descriptor* lookup_buffer_descriptor(
- struct gralloc1_device* dev, gralloc1_buffer_descriptor_t id)
-{
- /* do we want to validate? */
- return (struct gralloc1_adapter_buffer_descriptor*) ((uintptr_t) id);
-}
-
-static void device_dump(struct gralloc1_device* device,
- uint32_t* outSize, char* outBuffer)
-{
- struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
-
- if (outBuffer) {
- uint32_t copy = (uint32_t) dev->saved_dump_size;
- if (*outSize < copy) {
- copy = *outSize;
- } else {
- *outSize = copy;
- }
-
- memcpy(outBuffer, dev->saved_dump, copy);
- } else {
- /* dump is optional and may not null-terminate */
- if (dev->alloc_dev->dump) {
- dev->alloc_dev->dump(dev->alloc_dev, dev->saved_dump,
- sizeof(dev->saved_dump) - 1);
- dev->saved_dump_size = strlen(dev->saved_dump);
- }
-
- *outSize = (uint32_t) dev->saved_dump_size;
- }
-}
-
-static int32_t device_create_descriptor(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t* outDescriptor)
-{
- struct gralloc1_adapter_buffer_descriptor* desc;
-
- desc = calloc(1, sizeof(*desc));
- if (!desc) {
- return GRALLOC1_ERROR_NO_RESOURCES;
- }
-
- *outDescriptor = (gralloc1_buffer_descriptor_t) (uintptr_t) desc;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_destroy_descriptor(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t descriptor)
-{
- struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptor);
- if (!desc) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
- }
-
- free(desc);
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_consumer_usage(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
-{
- struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptor);
- if (!desc) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
- }
-
- desc->consumer_usage = (int) usage;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_dimensions(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t descriptor,
- uint32_t width, uint32_t height)
-{
- struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptor);
- if (!desc) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
- }
-
- desc->width = (int) width;
- desc->height = (int) height;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_format(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t descriptor, int32_t format)
-{
- struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptor);
- if (!desc) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
- }
-
- desc->format = format;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_producer_usage(struct gralloc1_device* device,
- gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
-{
- struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptor);
- if (!desc) {
- return GRALLOC1_ERROR_BAD_DESCRIPTOR;
- }
-
- desc->producer_usage = (int) usage;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_backing_store(struct gralloc1_device* device,
- buffer_handle_t buffer, gralloc1_backing_store_t* outStore)
-{
- /* we never share backing store */
- *outStore = (gralloc1_backing_store_t) (uintptr_t) buffer;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_consumer_usage(struct gralloc1_device* device,
- buffer_handle_t buffer, uint64_t* outUsage)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outUsage = data->info.usage;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_dimensions(struct gralloc1_device* device,
- buffer_handle_t buffer, uint32_t* outWidth, uint32_t* outHeight)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outWidth = data->info.width;
- *outHeight = data->info.height;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_format(struct gralloc1_device* device,
- buffer_handle_t buffer, int32_t* outFormat)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outFormat = data->info.format;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_producer_usage(struct gralloc1_device* device,
- buffer_handle_t buffer, uint64_t* outUsage)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outUsage = data->info.usage;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_stride(struct gralloc1_device* device,
- buffer_handle_t buffer, uint32_t* outStride)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outStride = data->info.stride;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_allocate(struct gralloc1_device* device,
- uint32_t numDescriptors,
- const gralloc1_buffer_descriptor_t* descriptors,
- buffer_handle_t* outBuffers)
-{
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
- gralloc1_error_t err = GRALLOC1_ERROR_NONE;
- uint32_t i;
-
- for (i = 0; i < numDescriptors; i++) {
- const struct gralloc1_adapter_buffer_descriptor* desc =
- lookup_buffer_descriptor(device, descriptors[i]);
- struct gralloc1_adapter_buffer_data* data;
- buffer_handle_t buffer;
- int dummy_stride;
- int ret;
-
- if (!desc) {
- err = GRALLOC1_ERROR_BAD_DESCRIPTOR;
- break;
- }
-
- data = calloc(1, sizeof(*data));
- if (!data) {
- err = GRALLOC1_ERROR_NO_RESOURCES;
- break;
- }
-
- ret = dev->alloc_dev->alloc(dev->alloc_dev, desc->width, desc->height,
- desc->format, desc->producer_usage | desc->consumer_usage,
- &buffer, &dummy_stride);
- if (ret) {
- free(data);
- err = GRALLOC1_ERROR_NO_RESOURCES;
- break;
- }
-
- mod->adapter.get_info(&mod->base, buffer, &data->info);
- data->refcount = 1;
- data->owned = true;
-
- mod->adapter.set_data(&mod->base, buffer, data);
-
- outBuffers[i] = buffer;
- }
-
- if (err != GRALLOC1_ERROR_NONE) {
- uint32_t j;
- for (j = 0; j < i; j++) {
- free(mod->adapter.get_data(&mod->base, outBuffers[i]));
- dev->alloc_dev->free(dev->alloc_dev, outBuffers[i]);
- }
-
- return err;
- }
-
- return (numDescriptors > 1) ?
- GRALLOC1_ERROR_NOT_SHARED : GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_retain(struct gralloc1_device* device,
- buffer_handle_t buffer)
-{
- static pthread_mutex_t register_mutex = PTHREAD_MUTEX_INITIALIZER;
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- struct gralloc1_adapter_buffer_data* data;
-
- pthread_mutex_lock(®ister_mutex);
-
- if (mod->adapter.is_registered(&mod->base, buffer)) {
- data = mod->adapter.get_data(&mod->base, buffer);
- data->refcount++;
- } else {
- int ret;
-
- data = calloc(1, sizeof(*data));
- if (!data) {
- pthread_mutex_unlock(®ister_mutex);
- return GRALLOC1_ERROR_NO_RESOURCES;
- }
-
- ret = mod->base.registerBuffer(&mod->base, buffer);
- if (ret) {
- pthread_mutex_unlock(®ister_mutex);
- free(data);
-
- return GRALLOC1_ERROR_NO_RESOURCES;
- }
-
- mod->adapter.get_info(&mod->base, buffer, &data->info);
- data->refcount = 1;
- data->owned = false;
-
- mod->adapter.set_data(&mod->base, buffer, data);
- }
-
- pthread_mutex_unlock(®ister_mutex);
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_release(struct gralloc1_device* device,
- buffer_handle_t buffer)
-{
- struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- ALOGE("unable to release unregistered buffer %p", buffer);
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- data->refcount--;
- if (!data->refcount) {
- if (data->owned) {
- struct gralloc1_adapter_device* dev =
- gralloc1_adapter_device(device);
- dev->alloc_dev->free(dev->alloc_dev, buffer);
- } else {
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- mod->base.unregisterBuffer(&mod->base, buffer);
-
- native_handle_close(buffer);
- native_handle_delete((native_handle_t*) buffer);
- }
-
- free(data);
- }
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_num_flex_planes(struct gralloc1_device* device,
- buffer_handle_t buffer, uint32_t* outNumPlanes)
-{
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- if (!data) {
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- *outNumPlanes = data->info.num_flex_planes;
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_lock(struct gralloc1_device* device,
- buffer_handle_t buffer,
- uint64_t producerUsage, uint64_t consumerUsage,
- const gralloc1_rect_t* accessRegion, void** outData,
- int32_t acquireFence)
-{
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- const int usage = (int) (producerUsage | consumerUsage);
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- int ret;
-
- if (!data) {
- ALOGE("unable to lock unregistered buffer %p", buffer);
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- if (mod->adapter.real_module_api_version >=
- GRALLOC_MODULE_API_VERSION_0_3) {
- ret = mod->base.lockAsync(&mod->base,
- buffer, usage,
- accessRegion->left,
- accessRegion->top,
- accessRegion->width,
- accessRegion->height,
- outData, acquireFence);
- } else {
- if (acquireFence >= 0) {
- sync_wait(acquireFence, -1);
- }
-
- ret = mod->base.lock(&mod->base,
- buffer, usage,
- accessRegion->left,
- accessRegion->top,
- accessRegion->width,
- accessRegion->height,
- outData);
-
- if (acquireFence >= 0 && !ret) {
- close(acquireFence);
- }
- }
-
- return (ret) ? GRALLOC1_ERROR_NO_RESOURCES : GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_lock_flex(struct gralloc1_device* device,
- buffer_handle_t buffer,
- uint64_t producerUsage, uint64_t consumerUsage,
- const gralloc1_rect_t* accessRegion,
- struct android_flex_layout* outFlexLayout,
- int32_t acquireFence)
-{
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- const int usage = (int) (producerUsage | consumerUsage);
- const struct gralloc1_adapter_buffer_data* data =
- lookup_buffer_data(device, buffer);
- struct android_ycbcr ycbcr;
- int ret;
-
- if (!data) {
- ALOGE("unable to lockFlex unregistered buffer %p", buffer);
- return GRALLOC1_ERROR_BAD_HANDLE;
- }
-
- if (outFlexLayout->num_planes < data->info.num_flex_planes) {
- return GRALLOC1_ERROR_BAD_VALUE;
- }
-
- if (mod->adapter.real_module_api_version >=
- GRALLOC_MODULE_API_VERSION_0_3 && mod->base.lockAsync_ycbcr) {
- ret = mod->base.lockAsync_ycbcr(&mod->base,
- buffer, usage,
- accessRegion->left,
- accessRegion->top,
- accessRegion->width,
- accessRegion->height,
- &ycbcr, acquireFence);
- } else if (mod->base.lock_ycbcr) {
- if (acquireFence >= 0) {
- sync_wait(acquireFence, -1);
- }
-
- ret = mod->base.lock_ycbcr(&mod->base,
- buffer, usage,
- accessRegion->left,
- accessRegion->top,
- accessRegion->width,
- accessRegion->height,
- &ycbcr);
-
- if (acquireFence >= 0 && !ret) {
- close(acquireFence);
- }
- } else {
- return GRALLOC1_ERROR_UNSUPPORTED;
- }
-
- if (ret) {
- return GRALLOC1_ERROR_NO_RESOURCES;
- }
-
- mod->adapter.get_flexible_layout(&mod->base, buffer,
- &ycbcr, outFlexLayout);
-
- return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_unlock(struct gralloc1_device* device,
- buffer_handle_t buffer, int32_t* outReleaseFence)
-{
- const struct gralloc1_adapter_module* mod =
- gralloc1_adapter_module(device);
- int ret;
-
- if (mod->adapter.real_module_api_version >=
- GRALLOC_MODULE_API_VERSION_0_3) {
- ret = mod->base.unlockAsync(&mod->base, buffer, outReleaseFence);
- } else {
- ret = mod->base.unlock(&mod->base, buffer);
- if (!ret) {
- *outReleaseFence = -1;
- }
- }
-
- return (ret) ? GRALLOC1_ERROR_BAD_HANDLE : GRALLOC1_ERROR_NONE;
-}
-
-static gralloc1_function_pointer_t device_get_function(
- struct gralloc1_device* device, int32_t descriptor)
-{
- switch ((gralloc1_function_descriptor_t) descriptor) {
-#define CASE(id, ptr) \
- case GRALLOC1_FUNCTION_ ## id: \
- return (gralloc1_function_pointer_t) device_ ## ptr
- CASE(DUMP, dump);
- CASE(CREATE_DESCRIPTOR, create_descriptor);
- CASE(DESTROY_DESCRIPTOR, destroy_descriptor);
- CASE(SET_CONSUMER_USAGE, set_consumer_usage);
- CASE(SET_DIMENSIONS, set_dimensions);
- CASE(SET_FORMAT, set_format);
- CASE(SET_PRODUCER_USAGE, set_producer_usage);
- CASE(GET_BACKING_STORE, get_backing_store);
- CASE(GET_CONSUMER_USAGE, get_consumer_usage);
- CASE(GET_DIMENSIONS, get_dimensions);
- CASE(GET_FORMAT, get_format);
- CASE(GET_PRODUCER_USAGE, get_producer_usage);
- CASE(GET_STRIDE, get_stride);
- CASE(ALLOCATE, allocate);
- CASE(RETAIN, retain);
- CASE(RELEASE, release);
- CASE(GET_NUM_FLEX_PLANES, get_num_flex_planes);
- CASE(LOCK, lock);
- CASE(LOCK_FLEX, lock_flex);
- CASE(UNLOCK, unlock);
-#undef CASE
- default: return NULL;
- }
-}
-
-static void device_get_capabilities(struct gralloc1_device* device,
- uint32_t* outCount, int32_t* outCapabilities)
-{
- *outCount = 0;
-}
-
-static int device_close(struct hw_device_t* device)
-{
- struct gralloc1_adapter_device* dev =
- (struct gralloc1_adapter_device*) device;
- int ret;
-
- ret = dev->alloc_dev->common.close(&dev->alloc_dev->common);
- if (!ret) {
- free(dev);
- }
-
- return ret;
-}
-
-int gralloc1_adapter_device_open(const struct hw_module_t* module,
- const char* id, struct hw_device_t** device)
-{
- const struct gralloc1_adapter_module* mod =
- (const struct gralloc1_adapter_module*) module;
- struct alloc_device_t* alloc_dev;
- struct gralloc1_adapter_device* dev;
- int ret;
-
- if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
- ALOGE("unknown gralloc1 device id: %s", id);
- return -EINVAL;
- }
-
- ret = module->methods->open(module, GRALLOC_HARDWARE_GPU0,
- (struct hw_device_t**) &alloc_dev);
- if (ret) {
- return ret;
- }
-
- dev = malloc(sizeof(*dev));
- if (!dev) {
- alloc_dev->common.close(&alloc_dev->common);
- return -ENOMEM;
- }
-
- *dev = (struct gralloc1_adapter_device) {
- .base = {
- .common = {
- .tag = HARDWARE_DEVICE_TAG,
- .version = HARDWARE_DEVICE_API_VERSION(0, 0),
- .module = (struct hw_module_t*) mod,
- .close = device_close,
- },
- .getCapabilities = device_get_capabilities,
- .getFunction = device_get_function,
- },
- .alloc_dev = alloc_dev,
- };
-
- *device = (struct hw_device_t*) dev;
-
- return 0;
-}
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.cpp b/graphics/allocator/2.0/default/gralloc1-adapter.cpp
new file mode 100644
index 0000000..fcc59cd
--- /dev/null
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Gralloc1On0Adapter.h"
+#include "gralloc1-adapter.h"
+
+int gralloc1_adapter_device_open(const struct hw_module_t* module,
+ const char* id, struct hw_device_t** device)
+{
+ if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
+ ALOGE("unknown gralloc1 device id: %s", id);
+ return -EINVAL;
+ }
+
+ auto adapter_device = new android::hardware::Gralloc1On0Adapter(module);
+ *device = &adapter_device->common;
+
+ return 0;
+}
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.h b/graphics/allocator/2.0/default/gralloc1-adapter.h
index f48cd9e..b912ef6 100644
--- a/graphics/allocator/2.0/default/gralloc1-adapter.h
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.h
@@ -16,52 +16,69 @@
#ifndef ANDROID_HARDWARE_GRALLOC1_ADAPTER_H
#define ANDROID_HARDWARE_GRALLOC1_ADAPTER_H
-#include <stdbool.h>
-#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
__BEGIN_DECLS
-struct gralloc1_adapter_buffer_info {
- int width;
- int height;
- int format;
- int usage;
+#define GRALLOC1_ADAPTER_MODULE_API_VERSION_1_0 \
+ HARDWARE_MODULE_API_VERSION(1, 0)
- int stride;
- uint32_t num_flex_planes;
-};
+enum {
+ GRALLOC1_ADAPTER_PERFORM_FIRST = 10000,
-/* This struct must be embedded in the HAL's HAL_MODULE_INFO_SYM and must
- * follow gralloc_module_t immediately. */
-struct gralloc1_adapter {
- uint16_t real_module_api_version;
+ // void getRealModuleApiVersionMinor(..., int* outMinorVersion);
+ GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR =
+ GRALLOC1_ADAPTER_PERFORM_FIRST,
- /* Return true if the buffer is registered. A locally allocated buffer is
- * always registered.
- *
- * This function is called frequently. It must be thread safe just like
- * other functions are.
- */
- bool (*is_registered)(const struct gralloc_module_t* mod,
- buffer_handle_t buffer);
+ // void setUsages(..., buffer_handle_t buffer,
+ // int producerUsage,
+ // int consumerUsage);
+ GRALLOC1_ADAPTER_PERFORM_SET_USAGES =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 1,
- /* Set the adapter data for a registered buffer. */
- void (*set_data)(const struct gralloc_module_t* mod,
- buffer_handle_t buffer, void* data);
+ // void getDimensions(..., buffer_handle_t buffer,
+ // int* outWidth,
+ // int* outHeight);
+ GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 2,
- /* Get the adapter data for a registered buffer. */
- void* (*get_data)(const struct gralloc_module_t* mod,
- buffer_handle_t buffer);
+ // void getFormat(..., buffer_handle_t buffer, int* outFormat);
+ GRALLOC1_ADAPTER_PERFORM_GET_FORMAT =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 3,
- /* Get the buffer info, such as width, height, etc. */
- void (*get_info)(const struct gralloc_module_t* mod,
- buffer_handle_t buffer,
- struct gralloc1_adapter_buffer_info* info);
+ // void getProducerUsage(..., buffer_handle_t buffer, int* outUsage);
+ GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 4,
- /* Get the flexilble layout matching ycbcr. */
- void (*get_flexible_layout)(const struct gralloc_module_t* mod,
- buffer_handle_t buffer, const struct android_ycbcr* ycbcr,
- struct android_flex_layout* layout);
+ // void getConsumerUsage(..., buffer_handle_t buffer, int* outUsage);
+ GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 5,
+
+ // void getBackingStore(..., buffer_handle_t buffer,
+ // uint64_t* outBackingStore);
+ GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 6,
+
+ // void getNumFlexPlanes(..., buffer_handle_t buffer,
+ // int* outNumFlexPlanes);
+ GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 7,
+
+ // void getStride(..., buffer_handle_t buffer, int* outStride);
+ GRALLOC1_ADAPTER_PERFORM_GET_STRIDE =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 8,
+
+ // void lockFlex(..., buffer_handle_t buffer,
+ // int producerUsage,
+ // int consumerUsage,
+ // int left,
+ // int top,
+ // int width,
+ // int height,
+ // android_flex_layout* outLayout,
+ // int acquireFence);
+ GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX =
+ GRALLOC1_ADAPTER_PERFORM_FIRST + 9,
};
int gralloc1_adapter_device_open(const struct hw_module_t* module,
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
index 8c2dd6d..54dfd89 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -176,9 +176,9 @@
mRelease(mDevice, handle);
} else {
mModule->unregisterBuffer(mModule, handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle_t*>(handle));
}
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle_t*>(handle));
}
// gralloc1
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 02ed877..c3d2281 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -19,6 +19,7 @@
srcs: ["GrallocMapper.cpp"],
cppflags: ["-Wall", "-Wextra"],
shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"libbase",
"libcutils",
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index cd9db38..3b6460a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -17,7 +17,9 @@
#include "GrallocMapper.h"
+#include <mutex>
#include <vector>
+#include <unordered_map>
#include <string.h>
@@ -100,6 +102,9 @@
GRALLOC1_PFN_LOCK_FLEX lockFlex;
GRALLOC1_PFN_UNLOCK unlock;
} mDispatch;
+
+ std::mutex mMutex;
+ std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
};
GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
@@ -201,12 +206,34 @@
Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
{
int32_t err = mDispatch.retain(mDevice, bufferHandle);
+ if (err == GRALLOC1_ERROR_NONE) {
+ auto nativeHandle = bufferHandle.getNativeHandle();
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ ++mBufferReferenceCounts[nativeHandle];
+ }
return static_cast<Error>(err);
}
Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
{
int32_t err = mDispatch.release(mDevice, bufferHandle);
+ if (err == GRALLOC1_ERROR_NONE) {
+ auto nativeHandle = bufferHandle.getNativeHandle();
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ auto iter = mBufferReferenceCounts.find(bufferHandle);
+ if (iter == mBufferReferenceCounts.end()) {
+ // this should never happen
+ err = GRALLOC1_ERROR_BAD_HANDLE;
+ } else if (--iter->second == 0) {
+ native_handle_close(nativeHandle);
+ native_handle_delete(const_cast<native_handle_t*>(nativeHandle));
+
+ mBufferReferenceCounts.erase(iter);
+ }
+ }
+
return static_cast<Error>(err);
}