graphics: add mapper HAL support library
Add a header-only support library
android.hardware.graphics.mapper@2.0-hal that can be used by
implementations. There are two classes in the support library.
MapperHal is an abstract class to be implemented by implementations.
Mapper is an implementation of HIDL IMapper interface on top of
MapperHal.
An implementation can
class VendorHal : public MapperHal { ... };
auto mapper = std::make_unique<Mapper>();
mapper->init(std::make_unique<VendorHal>(...));
Or, if vendor extensions are to be added to the IMapper,
class MapperHalExt : public MapperHal { ... };
class VendorHal : public MapperHalExt { ... };
class MapperExt : public MapperImpl<IMapperExt, MapperHalExt> { ... };
auto mapper = std::make_unique<MapperExt>();
mapper->init(std::make_unique<VendorHal>(...));
Test: builds
Change-Id: Ib23c1f5977744f7e116bb93db53e882e2dad7ce3
diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS
new file mode 100644
index 0000000..3aa5fa1
--- /dev/null
+++ b/graphics/mapper/2.0/utils/OWNERS
@@ -0,0 +1,4 @@
+# Graphics team
+jessehall@google.com
+olv@google.com
+stoza@google.com
diff --git a/graphics/mapper/2.0/utils/hal/Android.bp b/graphics/mapper/2.0/utils/hal/Android.bp
new file mode 100644
index 0000000..5610a69
--- /dev/null
+++ b/graphics/mapper/2.0/utils/hal/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2018 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.
+
+cc_library_headers {
+ name: "android.hardware.graphics.mapper@2.0-hal",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ shared_libs: [
+ "android.hardware.graphics.mapper@2.0",
+ ],
+ export_shared_lib_headers: [
+ "android.hardware.graphics.mapper@2.0",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h
new file mode 100644
index 0000000..5ad2a65
--- /dev/null
+++ b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/Mapper.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#ifndef LOG_TAG
+#warning "Mapper.h included without LOG_TAG"
+#endif
+
+#include <memory>
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <log/log.h>
+#include <mapper-hal/2.0/MapperHal.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace hal {
+
+namespace detail {
+
+// MapperImpl implements V2_*::IMapper on top of V2_*::hal::MapperHal
+template <typename Interface, typename Hal>
+class MapperImpl : public Interface {
+ public:
+ bool init(std::unique_ptr<Hal> hal) {
+ mHal = std::move(hal);
+ return true;
+ }
+
+ // IMapper 2.0 interface
+
+ Return<void> createDescriptor(const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo,
+ IMapper::createDescriptor_cb hidl_cb) override {
+ BufferDescriptor descriptor;
+ Error error = mHal->createDescriptor(descriptorInfo, &descriptor);
+ hidl_cb(error, descriptor);
+ return Void();
+ }
+
+ Return<void> importBuffer(const hidl_handle& rawHandle,
+ IMapper::importBuffer_cb hidl_cb) override {
+ if (!rawHandle.getNativeHandle()) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ native_handle_t* bufferHandle = nullptr;
+ Error error = mHal->importBuffer(rawHandle.getNativeHandle(), &bufferHandle);
+ if (error != Error::NONE) {
+ hidl_cb(error, nullptr);
+ return Void();
+ }
+
+ void* buffer = addImportedBuffer(bufferHandle);
+ if (!buffer) {
+ mHal->freeBuffer(bufferHandle);
+ hidl_cb(Error::NO_RESOURCES, nullptr);
+ return Void();
+ }
+
+ hidl_cb(error, buffer);
+ return Void();
+ }
+
+ Return<Error> freeBuffer(void* buffer) override {
+ native_handle_t* bufferHandle = removeImportedBuffer(buffer);
+ if (!bufferHandle) {
+ return Error::BAD_BUFFER;
+ }
+
+ return mHal->freeBuffer(bufferHandle);
+ }
+
+ Return<void> lock(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb) override {
+ const native_handle_t* bufferHandle = getImportedBuffer(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ base::unique_fd fenceFd;
+ Error error = getFenceFd(acquireFence, &fenceFd);
+ if (error != Error::NONE) {
+ hidl_cb(error, nullptr);
+ return Void();
+ }
+
+ void* data = nullptr;
+ error = mHal->lock(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &data);
+ hidl_cb(error, data);
+ return Void();
+ }
+
+ Return<void> lockYCbCr(void* buffer, uint64_t cpuUsage, const V2_0::IMapper::Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ IMapper::lockYCbCr_cb hidl_cb) override {
+ const native_handle_t* bufferHandle = getImportedBuffer(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, YCbCrLayout{});
+ return Void();
+ }
+
+ base::unique_fd fenceFd;
+ Error error = getFenceFd(acquireFence, &fenceFd);
+ if (error != Error::NONE) {
+ hidl_cb(error, YCbCrLayout{});
+ return Void();
+ }
+
+ YCbCrLayout layout{};
+ error = mHal->lockYCbCr(bufferHandle, cpuUsage, accessRegion, std::move(fenceFd), &layout);
+ hidl_cb(error, layout);
+ return Void();
+ }
+
+ Return<void> unlock(void* buffer, IMapper::unlock_cb hidl_cb) override {
+ const native_handle_t* bufferHandle = getImportedBuffer(buffer);
+ if (!bufferHandle) {
+ hidl_cb(Error::BAD_BUFFER, nullptr);
+ return Void();
+ }
+
+ base::unique_fd fenceFd;
+ Error error = mHal->unlock(bufferHandle, &fenceFd);
+ if (error != Error::NONE) {
+ hidl_cb(error, nullptr);
+ return Void();
+ }
+
+ NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+ hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
+ return Void();
+ }
+
+ protected:
+ // these functions can be overriden to do true imported buffer management
+ virtual void* addImportedBuffer(native_handle_t* bufferHandle) {
+ return static_cast<void*>(bufferHandle);
+ }
+
+ virtual native_handle_t* removeImportedBuffer(void* buffer) {
+ return static_cast<native_handle_t*>(buffer);
+ }
+
+ virtual const native_handle_t* getImportedBuffer(void* buffer) const {
+ return static_cast<const native_handle_t*>(buffer);
+ }
+
+ // convert fenceFd to or from hidl_handle
+ static Error getFenceFd(const hidl_handle& fenceHandle, base::unique_fd* outFenceFd) {
+ auto handle = fenceHandle.getNativeHandle();
+ if (handle && handle->numFds > 1) {
+ ALOGE("invalid fence handle with %d fds", handle->numFds);
+ return Error::BAD_VALUE;
+ }
+
+ int fenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
+ if (fenceFd >= 0) {
+ fenceFd = dup(fenceFd);
+ if (fenceFd < 0) {
+ return Error::NO_RESOURCES;
+ }
+ }
+
+ outFenceFd->reset(fenceFd);
+
+ return Error::NONE;
+ }
+
+ static hidl_handle getFenceHandle(const base::unique_fd& fenceFd, char* handleStorage) {
+ native_handle_t* handle = nullptr;
+ if (fenceFd >= 0) {
+ handle = native_handle_init(handleStorage, 1, 0);
+ handle->data[0] = fenceFd;
+ }
+
+ return hidl_handle(handle);
+ }
+
+ std::unique_ptr<Hal> mHal;
+};
+
+} // namespace detail
+
+using Mapper = detail::MapperImpl<IMapper, MapperHal>;
+
+} // namespace hal
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h
new file mode 100644
index 0000000..ab2e5cf
--- /dev/null
+++ b/graphics/mapper/2.0/utils/hal/include/mapper-hal/2.0/MapperHal.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace hal {
+
+class MapperHal {
+ public:
+ virtual ~MapperHal() = default;
+
+ // create a BufferDescriptor
+ virtual Error createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor* outDescriptor) = 0;
+
+ // import a raw handle owned by the caller
+ virtual Error importBuffer(const native_handle_t* rawHandle,
+ native_handle_t** outBufferHandle) = 0;
+
+ // free an imported buffer handle
+ virtual Error freeBuffer(native_handle_t* bufferHandle) = 0;
+
+ // lock a buffer
+ virtual Error lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, base::unique_fd fenceFd,
+ void** outData) = 0;
+
+ // lock a YCbCr buffer
+ virtual Error lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, base::unique_fd fenceFd,
+ YCbCrLayout* outLayout) = 0;
+
+ // unlock a buffer
+ virtual Error unlock(const native_handle_t* bufferHandle, base::unique_fd* outFenceFd) = 0;
+};
+
+} // namespace hal
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android