diff options
author | 2016-09-22 17:13:08 +0800 | |
---|---|---|
committer | 2016-10-12 16:06:25 -0700 | |
commit | 9ba189dc5c03040d45dad2080a81115f48f099c3 (patch) | |
tree | b410329066c819c61a027cebe68ab442994bf458 | |
parent | eeefbe07cb462165ec97229ff0c9ac827735476a (diff) |
libui: add support for android.hardware.graphics
Add Gralloc2::Allocator and Gralloc2::Mapper as wrappers to
android.hardware.graphics.allocator@2.0 and
android.hardware.graphics.mapper@2.0 respectively. Prefer
Gralloc2::{Allocator,Mapper} in
GraphicBufferAllocator/GraphicBufferMapper.
The new path has these differences
- it does not support gralloc0
- it does not dup-and-close fence fds to and from HAL
(not sure why we did that)
- release implies native_handle_close and native_handle_delete
(same as in gralloc1?)
When all interesting targets have android.hardware.graphics
implementations, the old path will be removed. That is why the new path
is added in the least intrusive way, as in:
if (new-path-valid) {
new-path;
} else {
old-path;
}
despite the ugliness.
Test: booted to launcher, tested with YouTube and some games
Change-Id: Idabb6c62e73c96a59736b497c6d6d1366095e7e3
-rw-r--r-- | include/ui/GrallocAllocator.h | 66 | ||||
-rw-r--r-- | include/ui/GrallocMapper.h | 127 | ||||
-rw-r--r-- | include/ui/GraphicBufferAllocator.h | 8 | ||||
-rw-r--r-- | include/ui/GraphicBufferMapper.h | 11 | ||||
-rw-r--r-- | libs/ui/Android.bp | 9 | ||||
-rw-r--r-- | libs/ui/GrallocAllocator.cpp | 114 | ||||
-rw-r--r-- | libs/ui/GrallocMapper.cpp | 118 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 7 | ||||
-rw-r--r-- | libs/ui/GraphicBufferAllocator.cpp | 203 | ||||
-rw-r--r-- | libs/ui/GraphicBufferMapper.cpp | 123 |
10 files changed, 717 insertions, 69 deletions
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h new file mode 100644 index 0000000000..23b78ed827 --- /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 0000000000..5517449241 --- /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 28d0238339..9cc580696a 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 @@ private: 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 a25809c124..b6de1b2ed5 100644 --- a/include/ui/GraphicBufferMapper.h +++ b/include/ui/GraphicBufferMapper.h @@ -28,6 +28,10 @@ namespace android { // --------------------------------------------------------------------------- +namespace Gralloc2 { +class Mapper; +} + class Rect; class GraphicBufferMapper : public Singleton<GraphicBufferMapper> @@ -57,11 +61,18 @@ public: 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 0777468585..1dc40b3e9a 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -46,6 +46,8 @@ cc_library_shared { "FrameStats.cpp", "Gralloc1.cpp", "Gralloc1On0Adapter.cpp", + "GrallocAllocator.cpp", + "GrallocMapper.cpp", "GraphicBuffer.cpp", "GraphicBufferAllocator.cpp", "GraphicBufferMapper.cpp", @@ -56,10 +58,17 @@ cc_library_shared { "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 0000000000..2eb1988cc8 --- /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 0000000000..d568b68d7b --- /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 97b948d979..6d729006f7 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 @@ void GraphicBuffer::free_handle() { 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 edfff4d6a5..693c7cbfab 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 @@ KeyedVector<buffer_handle_t, 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 @@ void GraphicBufferAllocator::dump(String8& result) const } 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 @@ void GraphicBufferAllocator::dumpToSystemLog() 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 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, // 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 @@ status_t GraphicBufferAllocator::free(buffer_handle_t handle) { 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 481d43ce42..fb55bf1a25 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 @@ namespace android { 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 @@ status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) { 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 @@ status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer) { 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 @@ status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) { 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 @@ status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, 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 @@ status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, 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 @@ status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, 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 @@ status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) { 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; } |