diff options
-rw-r--r-- | include/ui/GraphicBuffer.h | 76 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 123 | ||||
-rw-r--r-- | libs/vr/libbufferhub/ion_buffer.cpp | 15 | ||||
-rw-r--r-- | services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp | 6 | ||||
-rw-r--r-- | services/vr/vr_window_manager/composer/impl/vr_hwc.cpp | 9 |
5 files changed, 146 insertions, 83 deletions
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 040d1e7bac..33ec4bbac9 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -72,27 +72,66 @@ public: USAGE_CURSOR = GRALLOC_USAGE_CURSOR, }; + // Create a GraphicBuffer to be unflatten'ed into or be reallocated. GraphicBuffer(); - // creates w * h buffer - GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, - uint32_t inUsage, std::string requestorName = "<Unknown>"); - - // creates w * h buffer with a layer count using gralloc1 + // Create a GraphicBuffer by allocating and managing a buffer internally. + // This function is privileged. See reallocate for details. GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage, uint64_t inConsumerUsage, std::string requestorName = "<Unknown>"); - // create a buffer from an existing handle + // Create a GraphicBuffer from an existing handle. + enum HandleWrapMethod : uint8_t { + // Wrap and use the handle directly. It assumes the handle has been + // registered and never fails. The handle must have a longer lifetime + // than this wrapping GraphicBuffer. + // + // This can be used when, for example, you want to wrap a handle that + // is already managed by another GraphicBuffer. + WRAP_HANDLE, + + // Take ownership of the handle and use it directly. It assumes the + // handle has been registered and never fails. + // + // This can be used to manage an already registered handle with + // GraphicBuffer. + TAKE_HANDLE, + + // Take onwership of an unregistered handle and use it directly. It + // can fail when the buffer does not register. There is no ownership + // transfer on failures. + // + // This can be used to, for example, create a GraphicBuffer from a + // handle returned by Parcel::readNativeHandle. + TAKE_UNREGISTERED_HANDLE, + + // Make a clone of the handle and use the cloned handle. It can fail + // when cloning fails or when the buffer does not register. There is + // never ownership transfer. + // + // This can be used to create a GraphicBuffer from a handle that + // cannot be used directly, such as one from hidl_handle. + CLONE_HANDLE, + }; + GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method, + uint32_t width, uint32_t height, + PixelFormat format, uint32_t layerCount, + uint64_t producerUsage, uint64_t consumerUsage, uint32_t stride); + + // These functions are deprecated because they do not distinguish producer + // and consumer usages. + GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method, + uint32_t width, uint32_t height, + PixelFormat format, uint32_t layerCount, + uint32_t usage, uint32_t stride) + : GraphicBuffer(handle, method, width, height, format, layerCount, + usage, usage, stride) {} GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle, bool keepOwnership); - - // create a buffer from an existing handle using gralloc1 GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, - uint32_t inLayerCount, uint32_t inProducerUsage, - uint32_t inConsumerUsage, uint32_t inStride, - native_handle_t* inHandle, bool keepOwnership); + uint32_t inUsage, std::string requestorName = "<Unknown>"); // create a buffer from an existing ANativeWindowBuffer GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership); @@ -114,6 +153,9 @@ public: mGenerationNumber = generation; } + // This function is privileged. It requires access to the allocator + // device or service, which usually involves adding suitable selinux + // rules. status_t reallocate(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage); @@ -175,9 +217,15 @@ private: GraphicBuffer& operator = (const GraphicBuffer& rhs); const GraphicBuffer& operator = (const GraphicBuffer& rhs) const; - status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, - uint32_t inLayerCount, uint64_t inProducerUsage, - uint64_t inConsumerUsage, std::string requestorName); + status_t initWithSize(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inLayerCount, + uint64_t inProducerUsage, uint64_t inConsumerUsage, + std::string requestorName); + + status_t initWithHandle(const native_handle_t* handle, + HandleWrapMethod method, uint32_t width, uint32_t height, + PixelFormat format, uint32_t layerCount, + uint64_t producerUsage, uint64_t consumerUsage, uint32_t stride); void free_handle(); diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 6e8473018a..4fae2337d4 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -52,73 +52,33 @@ GraphicBuffer::GraphicBuffer() handle = NULL; } +// deprecated GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inUsage, std::string requestorName) - : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) + : GraphicBuffer(inWidth, inHeight, inFormat, 1, inUsage, inUsage, + requestorName) { - width = - height = - stride = - format = - usage = 0; - layerCount = 0; - handle = NULL; - mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage, - std::move(requestorName)); } GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage, uint64_t consumerUsage, std::string requestorName) - : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) + : GraphicBuffer() { - width = - height = - stride = - format = - usage = 0; - layerCount = 0; - handle = NULL; - mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount, + mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, producerUsage, consumerUsage, std::move(requestorName)); } +// deprecated GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) - : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), - mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) -{ - width = static_cast<int>(inWidth); - height = static_cast<int>(inHeight); - stride = static_cast<int>(inStride); - format = inFormat; - layerCount = inLayerCount; - usage = static_cast<int>(inUsage); - handle = inHandle; -} - -GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inLayerCount, uint32_t inProducerUsage, - uint32_t inConsumerUsage, uint32_t inStride, - native_handle_t* inHandle, bool keepOwnership) - : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), - mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) + : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE, + inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage, + inStride) { - width = static_cast<int>(inWidth); - height = static_cast<int>(inHeight); - stride = static_cast<int>(inStride); - format = inFormat; - layerCount = inLayerCount; - usage = android_convertGralloc1To0Usage(inProducerUsage, inConsumerUsage); - handle = inHandle; } - GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), mBufferMapper(GraphicBufferMapper::get()), @@ -134,6 +94,17 @@ GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) handle = buffer->handle; } +GraphicBuffer::GraphicBuffer(const native_handle_t* handle, + HandleWrapMethod method, uint32_t width, uint32_t height, + PixelFormat format, uint32_t layerCount, + uint64_t producerUsage, uint64_t consumerUsage, + uint32_t stride) + : GraphicBuffer() +{ + mInitCheck = initWithHandle(handle, method, width, height, format, + layerCount, producerUsage, consumerUsage, stride); +} + GraphicBuffer::~GraphicBuffer() { if (handle) { @@ -192,8 +163,8 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, allocator.free(handle); handle = 0; } - return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage, - "[Reallocation]"); + return initWithSize(inWidth, inHeight, inFormat, inLayerCount, + inUsage, inUsage, "[Reallocation]"); } bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, @@ -207,7 +178,7 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, return false; } -status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight, +status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage, uint64_t inConsumerUsage, std::string requestorName) { @@ -227,6 +198,54 @@ status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight, return err; } +status_t GraphicBuffer::initWithHandle(const native_handle_t* handle, + HandleWrapMethod method, uint32_t width, uint32_t height, + PixelFormat format, uint32_t layerCount, + uint64_t producerUsage, uint64_t consumerUsage, + uint32_t stride) +{ + native_handle_t* clone = nullptr; + + if (method == CLONE_HANDLE) { + clone = native_handle_clone(handle); + if (!clone) { + return NO_MEMORY; + } + + handle = clone; + method = TAKE_UNREGISTERED_HANDLE; + } + + ANativeWindowBuffer::width = static_cast<int>(width); + ANativeWindowBuffer::height = static_cast<int>(height); + ANativeWindowBuffer::stride = static_cast<int>(stride); + ANativeWindowBuffer::format = format; + ANativeWindowBuffer::usage = + android_convertGralloc1To0Usage(producerUsage, consumerUsage); + + ANativeWindowBuffer::layerCount = layerCount; + ANativeWindowBuffer::handle = handle; + + mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle; + + if (method == TAKE_UNREGISTERED_HANDLE) { + status_t err = mBufferMapper.registerBuffer(this); + if (err != NO_ERROR) { + // clean up cloned handle + if (clone) { + native_handle_close(clone); + native_handle_delete(clone); + } + + initWithHandle(nullptr, WRAP_HANDLE, 0, 0, 0, 0, 0, 0, 0); + + return err; + } + } + + return NO_ERROR; +} + status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr) { const Rect lockBounds(width, height); diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp index 3fb3f3c6ff..e5a56c1a4b 100644 --- a/libs/vr/libbufferhub/ion_buffer.cpp +++ b/libs/vr/libbufferhub/ion_buffer.cpp @@ -1,5 +1,4 @@ #include <private/dvr/ion_buffer.h> -#include <ui/GraphicBufferMapper.h> #include <log/log.h> #define ATRACE_TAG ATRACE_TAG_GRAPHICS @@ -70,10 +69,9 @@ int IonBuffer::Alloc(int width, int height, int format, int usage) { ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d", width, height, format, usage); - GraphicBufferMapper& mapper = GraphicBufferMapper::get(); buffer_ = new GraphicBuffer(width, height, format, usage); - if (mapper.registerBuffer(buffer_.get()) != OK) { - ALOGE("IonBuffer::Aloc: Failed to register buffer"); + if (buffer_->initCheck() != OK) { + ALOGE("IonBuffer::Aloc: Failed to allocate buffer"); } return 0; } @@ -96,11 +94,10 @@ int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride, "usage=%d", handle, width, height, stride, format, usage); FreeHandle(); - GraphicBufferMapper& mapper = GraphicBufferMapper::get(); - buffer_ = new GraphicBuffer(width, height, format, 1, usage, - stride, (native_handle_t*)handle, true); - if (mapper.registerBuffer(buffer_.get()) != OK) { - ALOGE("IonBuffer::Import: Failed to register cloned buffer"); + buffer_ = new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, + width, height, format, 1, usage, stride); + if (buffer_->initCheck() != OK) { + ALOGE("IonBuffer::Import: Failed to import buffer"); return -EINVAL; } return 0; diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp index 34e2b7ec36..999d71efb3 100644 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp +++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp @@ -34,9 +34,9 @@ sp<GraphicBuffer> GetBufferFromHandle(native_handle_t* handle) { // capability. Otherwise assume a count of 1. mapper.getLayerCount(handle, &layer_count); - sp<GraphicBuffer> buffer = new GraphicBuffer( - width, height, format, layer_count, producer_usage, consumer_usage, - stride, handle, true); + sp<GraphicBuffer> buffer = new GraphicBuffer(handle, + GraphicBuffer::TAKE_HANDLE, width, height, format, layer_count, + producer_usage, consumer_usage, stride); return buffer; } diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp index 3393ade01d..d142729d23 100644 --- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp +++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp @@ -69,11 +69,10 @@ sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) { mapper.getLayerCount(handle, &layer_count); // NOTE: Can't re-use |handle| since we don't own it. - sp<GraphicBuffer> buffer = new GraphicBuffer( - width, height, format, layer_count, producer_usage, consumer_usage, - stride, native_handle_clone(handle), true); - // Need to register the cloned buffer otherwise it can't be used later on. - if (mapper.registerBuffer(buffer.get()) != OK) { + sp<GraphicBuffer> buffer = new GraphicBuffer(handle, + GraphicBuffer::CLONE_HANDLE, width, height, format, layer_count, + producer_usage, consumer_usage, stride); + if (buffer->initCheck() != OK) { ALOGE("Failed to register cloned buffer"); return nullptr; } |