Merge "libui: add support for android.hardware.graphics"
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h
new file mode 100644
index 0000000..23b78ed
--- /dev/null
+++ b/include/ui/GrallocAllocator.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_UI_GRALLOC_ALLOCATOR_H
+#define ANDROID_UI_GRALLOC_ALLOCATOR_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::Error;
+using hardware::graphics::allocator::V2_0::PixelFormat;
+using hardware::graphics::allocator::V2_0::ProducerUsage;
+using hardware::graphics::allocator::V2_0::ConsumerUsage;
+using hardware::graphics::allocator::V2_0::BufferDescriptor;
+using hardware::graphics::allocator::V2_0::Buffer;
+using hardware::graphics::allocator::V2_0::IAllocator;
+
+// Allocator is a wrapper to IAllocator, a proxy to server-side allocator.
+class Allocator {
+public:
+ Allocator();
+
+ // this will be removed and Allocator will be always valid
+ bool valid() const { return (mService != nullptr); }
+
+ std::string dumpDebugInfo() const;
+
+ Error createBufferDescriptor(
+ const IAllocator::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor& descriptor) const;
+ void destroyBufferDescriptor(BufferDescriptor descriptor) const;
+
+ Error allocate(BufferDescriptor descriptor, Buffer& buffer) const;
+ void free(Buffer buffer) const;
+
+ Error exportHandle(BufferDescriptor descriptor, Buffer buffer,
+ native_handle_t*& bufferHandle) const;
+
+private:
+ sp<IAllocator> mService;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_ALLOCATOR_H
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
new file mode 100644
index 0000000..5517449
--- /dev/null
+++ b/include/ui/GrallocMapper.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_UI_GRALLOC_MAPPER_H
+#define ANDROID_UI_GRALLOC_MAPPER_H
+
+#include <memory>
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::Error;
+using hardware::graphics::allocator::V2_0::PixelFormat;
+using hardware::graphics::allocator::V2_0::ProducerUsage;
+using hardware::graphics::allocator::V2_0::ConsumerUsage;
+using hardware::graphics::mapper::V2_0::FlexLayout;
+using hardware::graphics::mapper::V2_0::BackingStore;
+using hardware::graphics::mapper::V2_0::Device;
+using hardware::graphics::mapper::V2_0::IMapper;
+
+// Mapper is a wrapper to IMapper, a client-side graphics buffer mapper.
+class Mapper {
+public:
+ Mapper();
+ ~Mapper();
+
+ // this will be removed and Mapper will be always valid
+ bool valid() const { return (mMapper != nullptr); }
+
+ Error retain(buffer_handle_t handle) const
+ {
+ return mMapper->retain(mDevice, handle);
+ }
+
+ void release(buffer_handle_t handle) const;
+
+ Error getDimensions(buffer_handle_t handle,
+ uint32_t& width, uint32_t& height) const
+ {
+ return mMapper->getDimensions(mDevice, handle, &width, &height);
+ }
+
+ Error getFormat(buffer_handle_t handle,
+ PixelFormat& format) const
+ {
+ return mMapper->getFormat(mDevice, handle, &format);
+ }
+
+ Error getProducerUsageMask(buffer_handle_t handle,
+ uint64_t& usageMask) const
+ {
+ return mMapper->getProducerUsageMask(mDevice, handle, &usageMask);
+ }
+
+ Error getConsumerUsageMask(buffer_handle_t handle,
+ uint64_t& usageMask) const
+ {
+ return mMapper->getConsumerUsageMask(mDevice, handle, &usageMask);
+ }
+
+ Error getBackingStore(buffer_handle_t handle,
+ BackingStore& store) const
+ {
+ return mMapper->getBackingStore(mDevice, handle, &store);
+ }
+
+ Error getStride(buffer_handle_t handle, uint32_t& stride) const
+ {
+ return mMapper->getStride(mDevice, handle, &stride);
+ }
+
+ Error getNumFlexPlanes(buffer_handle_t handle, uint32_t& numPlanes) const
+ {
+ return mMapper->getNumFlexPlanes(mDevice, handle, &numPlanes);
+ }
+
+ Error lock(buffer_handle_t handle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ const Device::Rect& accessRegion,
+ int acquireFence, void*& data) const
+ {
+ return mMapper->lock(mDevice, handle,
+ producerUsageMask, consumerUsageMask,
+ &accessRegion, acquireFence, &data);
+ }
+
+ Error lock(buffer_handle_t handle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ const Device::Rect& accessRegion,
+ int acquireFence, FlexLayout& flexLayout) const
+ {
+ return mMapper->lockFlex(mDevice, handle,
+ producerUsageMask, consumerUsageMask,
+ &accessRegion, acquireFence, &flexLayout);
+ }
+
+ int unlock(buffer_handle_t handle) const;
+
+private:
+ const IMapper* mMapper;
+ Device* mDevice;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_MAPPER_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 28d0238..9cc5806 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -32,7 +32,12 @@
namespace android {
+namespace Gralloc2 {
+class Allocator;
+}
+
class Gralloc1Loader;
+class GraphicBufferMapper;
class String8;
class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
@@ -86,6 +91,9 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
+ const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
+ GraphicBufferMapper& mMapper;
+
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 a25809c..b6de1b2 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -28,6 +28,10 @@
// ---------------------------------------------------------------------------
+namespace Gralloc2 {
+class Mapper;
+}
+
class Rect;
class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
@@ -57,11 +61,18 @@
status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
+ const Gralloc2::Mapper& getGrallocMapper() const
+ {
+ return *mMapper;
+ }
+
private:
friend class Singleton<GraphicBufferMapper>;
GraphicBufferMapper();
+ const std::unique_ptr<const Gralloc2::Mapper> mMapper;
+
std::unique_ptr<Gralloc1::Loader> mLoader;
std::unique_ptr<Gralloc1::Device> mDevice;
};
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index d5ff753..37b2873 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -45,6 +45,8 @@
"FrameStats.cpp",
"Gralloc1.cpp",
"Gralloc1On0Adapter.cpp",
+ "GrallocAllocator.cpp",
+ "GrallocMapper.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
@@ -55,10 +57,17 @@
"UiConfig.cpp",
],
+ static_libs: [
+ "android.hardware.graphics.mapper@2.0",
+ ],
+
shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
"libbinder",
"libcutils",
"libhardware",
+ "libhidl",
+ "libhwbinder",
"libsync",
"libutils",
"liblog",
diff --git a/libs/ui/GrallocAllocator.cpp b/libs/ui/GrallocAllocator.cpp
new file mode 100644
index 0000000..2eb1988
--- /dev/null
+++ b/libs/ui/GrallocAllocator.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 "GrallocAllocator"
+
+#include <log/log.h>
+#include <ui/GrallocAllocator.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+// assume NO_RESOURCES when Status::isOk returns false
+constexpr Error kDefaultError = Error::NO_RESOURCES;
+
+Allocator::Allocator()
+{
+ mService = IAllocator::getService("gralloc");
+}
+
+std::string Allocator::dumpDebugInfo() const
+{
+ std::string info;
+
+ mService->dumpDebugInfo([&](const auto& tmpInfo) {
+ info = tmpInfo.c_str();
+ });
+
+ return info;
+}
+
+Error Allocator::createBufferDescriptor(
+ const IAllocator::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor& descriptor) const
+{
+ Error error = kDefaultError;
+ mService->createDescriptor(descriptorInfo,
+ [&](const auto& tmpError, const auto& tmpDescriptor) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ descriptor = tmpDescriptor;
+ });
+
+ return error;
+}
+
+void Allocator::destroyBufferDescriptor(BufferDescriptor descriptor) const
+{
+ mService->destroyDescriptor(descriptor);
+}
+
+Error Allocator::allocate(BufferDescriptor descriptor, Buffer& buffer) const
+{
+ hardware::hidl_vec<BufferDescriptor> descriptors;
+ descriptors.setToExternal(&descriptor, 1);
+
+ Error error = kDefaultError;
+ auto status = mService->allocate(descriptors,
+ [&](const auto& tmpError, const auto& tmpBuffers) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ buffer = tmpBuffers[0];
+ });
+
+ return error;
+}
+
+void Allocator::free(Buffer buffer) const
+{
+ mService->free(buffer);
+}
+
+Error Allocator::exportHandle(BufferDescriptor descriptor, Buffer buffer,
+ native_handle_t*& bufferHandle) const
+{
+ Error error = kDefaultError;
+ auto status = mService->exportHandle(descriptor, buffer,
+ [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ bufferHandle = native_handle_clone(tmpBufferHandle);
+ if (!bufferHandle) {
+ error = Error::NO_RESOURCES;
+ }
+ });
+
+ return error;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
new file mode 100644
index 0000000..d568b68
--- /dev/null
+++ b/libs/ui/GrallocMapper.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "GrallocMapper"
+
+#include <array>
+#include <string>
+
+#include <log/log.h>
+#include <ui/GrallocMapper.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+typedef const void*(*FetchInterface)(const char* name);
+
+static FetchInterface loadHalLib(const char* pkg_name)
+{
+ static const std::array<const char*, 3> sSearchDirs = {{
+ HAL_LIBRARY_PATH_ODM,
+ HAL_LIBRARY_PATH_VENDOR,
+ HAL_LIBRARY_PATH_SYSTEM,
+ }};
+ static const char sSymbolName[] = "HALLIB_FETCH_Interface";
+
+ void* handle = nullptr;
+ std::string path;
+ for (auto dir : sSearchDirs) {
+ path = dir;
+ path += pkg_name;
+ path += ".hallib.so";
+ handle = dlopen(path.c_str(), RTLD_LOCAL | RTLD_NOW);
+ if (handle) {
+ break;
+ }
+ }
+ if (!handle) {
+ return nullptr;
+ }
+
+ void* symbol = dlsym(handle, sSymbolName);
+ if (!symbol) {
+ ALOGE("%s is missing from %s", sSymbolName, path.c_str());
+ dlclose(handle);
+ return nullptr;
+ }
+
+ return reinterpret_cast<FetchInterface>(symbol);
+}
+
+Mapper::Mapper()
+ : mMapper(nullptr), mDevice(nullptr)
+{
+ static const char sHalLibName[] = "android.hardware.graphics.mapper";
+ static const char sSupportedInterface[] =
+ "android.hardware.graphics.mapper@2.0::IMapper";
+
+ FetchInterface fetchInterface = loadHalLib(sHalLibName);
+ if (!fetchInterface) {
+ return;
+ }
+
+ mMapper = static_cast<const IMapper*>(
+ fetchInterface(sSupportedInterface));
+ if (!mMapper) {
+ ALOGE("%s is not supported", sSupportedInterface);
+ return;
+ }
+
+ if (mMapper->createDevice(&mDevice) != Error::NONE) {
+ ALOGE("failed to create mapper device");
+ mMapper = nullptr;
+ }
+}
+
+Mapper::~Mapper()
+{
+ if (mMapper) {
+ mMapper->destroyDevice(mDevice);
+ }
+}
+
+void Mapper::release(buffer_handle_t handle) const
+{
+ auto error = mMapper->release(mDevice, handle);
+ ALOGE_IF(error != Error::NONE,
+ "release(%p) failed with %d", handle, error);
+}
+
+int Mapper::unlock(buffer_handle_t handle) const
+{
+ int releaseFence;
+ auto error = mMapper->unlock(mDevice, handle, &releaseFence);
+ if (error != Error::NONE) {
+ ALOGE("unlock(%p) failed with %d", handle, error);
+ releaseFence = -1;
+ }
+
+ return releaseFence;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 97b948d..6d72900 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -23,6 +23,7 @@
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <ui/GrallocMapper.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
@@ -108,8 +109,10 @@
{
if (mOwner == ownHandle) {
mBufferMapper.unregisterBuffer(handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
+ if (!mBufferMapper.getGrallocMapper().valid()) {
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle*>(handle));
+ }
} else if (mOwner == ownData) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index edfff4d..693c7cb 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -26,6 +26,9 @@
#include <ui/GraphicBufferAllocator.h>
#include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocAllocator.h>
+#include <ui/GrallocMapper.h>
+#include <ui/GraphicBufferMapper.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -37,8 +40,14 @@
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator()
- : mLoader(std::make_unique<Gralloc1::Loader>()),
- mDevice(mLoader->getDevice()) {}
+ : mAllocator(std::make_unique<Gralloc2::Allocator>()),
+ mMapper(GraphicBufferMapper::getInstance())
+{
+ if (!mAllocator->valid()) {
+ mLoader = std::make_unique<Gralloc1::Loader>();
+ mDevice = mLoader->getDevice();
+ }
+}
GraphicBufferAllocator::~GraphicBufferAllocator() {}
@@ -70,7 +79,14 @@
}
snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
result.append(buffer);
- std::string deviceDump = mDevice->dump();
+
+ std::string deviceDump;
+ if (mAllocator->valid()) {
+ deviceDump = mAllocator->dumpDebugInfo();
+ } else {
+ deviceDump = mDevice->dump();
+ }
+
result.append(deviceDump.c_str(), deviceDump.size());
}
@@ -81,6 +97,103 @@
ALOGD("%s", s.string());
}
+namespace {
+
+class HalBuffer {
+public:
+ HalBuffer(const Gralloc2::Allocator* allocator,
+ uint32_t width, uint32_t height,
+ PixelFormat format, 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.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);
+ return;
+ }
+
+ error = mAllocator->allocate(descriptor, mBuffer);
+ if (error == Gralloc2::Error::NOT_SHARED) {
+ error = Gralloc2::Error::NONE;
+ }
+
+ if (error != Gralloc2::Error::NONE) {
+ ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
+ width, height, format, usage, error);
+ mAllocator->destroyBufferDescriptor(descriptor);
+ return;
+ }
+
+ error = mAllocator->exportHandle(descriptor, mBuffer, mHandle);
+ if (error != Gralloc2::Error::NONE) {
+ ALOGE("Failed to export handle");
+ mAllocator->free(mBuffer);
+ mAllocator->destroyBufferDescriptor(descriptor);
+ return;
+ }
+
+ mAllocator->destroyBufferDescriptor(descriptor);
+
+ mBufferValid = true;
+ }
+
+ ~HalBuffer()
+ {
+ if (mBufferValid) {
+ if (mHandle) {
+ native_handle_close(mHandle);
+ native_handle_delete(mHandle);
+ }
+
+ mAllocator->free(mBuffer);
+ }
+ }
+
+ bool exportHandle(GraphicBufferMapper& mapper,
+ buffer_handle_t* handle, uint32_t* stride)
+ {
+ if (!mBufferValid) {
+ return false;
+ }
+
+ if (mapper.registerBuffer(mHandle)) {
+ return false;
+ }
+
+ *handle = mHandle;
+
+ auto error = mapper.getGrallocMapper().getStride(mHandle, *stride);
+ if (error != Gralloc2::Error::NONE) {
+ ALOGW("Failed to get stride from buffer: %d", error);
+ *stride = 0;
+ }
+
+ mHandle = nullptr;
+ mAllocator->free(mBuffer);
+ mBufferValid = false;
+
+ return true;
+ }
+
+private:
+ const Gralloc2::Allocator* mAllocator;
+
+ bool mBufferValid;
+ Gralloc2::Buffer mBuffer;
+ native_handle_t* mHandle;
+};
+
+} // 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)
@@ -95,40 +208,51 @@
// Filter out any usage bits that should not be passed to the gralloc module
usage &= GRALLOC_USAGE_ALLOC_MASK;
- 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;
- }
+ gralloc1_error_t error;
+ if (mAllocator->valid()) {
+ HalBuffer buffer(mAllocator.get(), width, height, format, usage);
+ if (!buffer.exportHandle(mMapper, handle, stride)) {
+ return NO_MEMORY;
+ }
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ auto descriptor = mDevice->createDescriptor();
+ 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;
+ }
- 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;
- }
+ 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;
+ }
- error = mDevice->getStride(*handle, stride);
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGW("Failed to get stride from buffer: %d", error);
+ error = mDevice->getStride(*handle, stride);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGW("Failed to get stride from buffer: %d", error);
+ }
}
if (error == NO_ERROR) {
@@ -153,7 +277,14 @@
{
ATRACE_CALL();
- auto error = mDevice->release(handle);
+ gralloc1_error_t error;
+ if (mAllocator->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper.unregisterBuffer(handle));
+ } else {
+ error = mDevice->release(handle);
+ }
+
if (error != GRALLOC1_ERROR_NONE) {
ALOGE("Failed to free buffer: %d", error);
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 481d43c..fb55bf1 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -33,6 +33,7 @@
#include <utils/Trace.h>
#include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocMapper.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/Rect.h>
@@ -44,8 +45,13 @@
ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
GraphicBufferMapper::GraphicBufferMapper()
- : mLoader(std::make_unique<Gralloc1::Loader>()),
- mDevice(mLoader->getDevice()) {}
+ : mMapper(std::make_unique<const Gralloc2::Mapper>())
+{
+ if (!mMapper->valid()) {
+ mLoader = std::make_unique<Gralloc1::Loader>();
+ mDevice = mLoader->getDevice();
+ }
+}
@@ -53,7 +59,13 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->retain(handle);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
+ } else {
+ error = mDevice->retain(handle);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
handle, error);
@@ -64,7 +76,14 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->retain(buffer);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper->retain(buffer->getNativeBuffer()->handle));
+ } else {
+ error = mDevice->retain(buffer);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
buffer->getNativeBuffer()->handle, error);
@@ -75,7 +94,14 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->release(handle);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->release(handle);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->release(handle);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
handle, error);
@@ -120,11 +146,20 @@
ATRACE_CALL();
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);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ const Gralloc2::Device::Rect& accessRect =
+ *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+ error = static_cast<gralloc1_error_t>(mMapper->lock(
+ handle, usage, usage, accessRect, fenceFd, *vaddr));
+ } else {
+ sp<Fence> fence = new Fence(fenceFd);
+ 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);
@@ -160,20 +195,29 @@
ATRACE_CALL();
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;
+ if (!mMapper->valid()) {
+ if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+ sp<Fence> fence = new Fence(fenceFd);
+ 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;
+ }
}
uint32_t numPlanes = 0;
- gralloc1_error_t error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper->getNumFlexPlanes(handle, numPlanes));
+ } else {
+ error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+ }
+
if (error != GRALLOC1_ERROR_NONE) {
ALOGV("Failed to retrieve number of flex planes: %d", error);
return error;
@@ -188,10 +232,21 @@
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 (mMapper->valid()) {
+ const Gralloc2::Device::Rect& accessRect =
+ *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+ Gralloc2::FlexLayout& layout =
+ *reinterpret_cast<Gralloc2::FlexLayout*>(&flexLayout);
+ error = static_cast<gralloc1_error_t>(mMapper->lock(
+ handle, usage, usage, accessRect, fenceFd, layout));
+ } else {
+ sp<Fence> fence = new Fence(fenceFd);
+ 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;
@@ -276,14 +331,20 @@
{
ATRACE_CALL();
- 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;
- }
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ *fenceFd = mMapper->unlock(handle);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ sp<Fence> fence = Fence::NO_FENCE;
+ error = mDevice->unlock(handle, &fence);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("unlock(%p) failed: %d", handle, error);
+ return error;
+ }
- *fenceFd = fence->dup();
+ *fenceFd = fence->dup();
+ }
return error;
}