Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b42f171a authored by Chia-I Wu's avatar Chia-I Wu
Browse files

libui: clean up GraphicBuffer interface

Other than transferring the ownership, some callers want to control
whether to register or to clone the handle when creating a
GraphicBuffer from a handle.  Add a new constructor with
HandleWrapMethod for finer controls, to replace the one that has
only a boolean, keepOwnership.

The motivation is to enable users to construct GraphicBuffer without
fighting with GraphicBufferMapper::registerBuffer first.  More
generally, GraphicBufferMapper::{registerBuffer,unregisterBuffer} is
tricky to use correctly.  They should really be considered private
by most.

While at it, deprecate constructors that do not distinguish
producer/consumer usage.  It turns out GraphicBuffer is used by some
proprietary libraries.  I have to maintain the ABI and cannot remove
the deprecated constructors.

Bug: 36355756
Test: boots
Change-Id: Ieea618d8495f06a6233299d076fb821127cd6bf8
parent 0e7305cb
Loading
Loading
Loading
Loading
+62 −14
Original line number Original line Diff line number Diff line
@@ -72,27 +72,66 @@ public:
        USAGE_CURSOR            = GRALLOC_USAGE_CURSOR,
        USAGE_CURSOR            = GRALLOC_USAGE_CURSOR,
    };
    };


    // Create a GraphicBuffer to be unflatten'ed into or be reallocated.
    GraphicBuffer();
    GraphicBuffer();


    // creates w * h buffer
    // Create a GraphicBuffer by allocating and managing a buffer internally.
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
    // This function is privileged.  See reallocate for details.
            uint32_t inUsage, std::string requestorName = "<Unknown>");

    // creates w * h buffer with a layer count using gralloc1
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
            uint32_t inLayerCount, uint64_t inProducerUsage,
            uint32_t inLayerCount, uint64_t inProducerUsage,
            uint64_t inConsumerUsage, std::string requestorName = "<Unknown>");
            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,
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
            uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride,
            uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride,
            native_handle_t* inHandle, bool keepOwnership);
            native_handle_t* inHandle, bool keepOwnership);

    // create a buffer from an existing handle using gralloc1
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
            uint32_t inLayerCount, uint32_t inProducerUsage,
            uint32_t inUsage, std::string requestorName = "<Unknown>");
            uint32_t inConsumerUsage, uint32_t inStride,
            native_handle_t* inHandle, bool keepOwnership);


    // create a buffer from an existing ANativeWindowBuffer
    // create a buffer from an existing ANativeWindowBuffer
    GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
    GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
@@ -114,6 +153,9 @@ public:
        mGenerationNumber = generation;
        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,
    status_t reallocate(uint32_t inWidth, uint32_t inHeight,
            PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage);
            PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage);


@@ -175,9 +217,15 @@ private:
    GraphicBuffer& operator = (const GraphicBuffer& rhs);
    GraphicBuffer& operator = (const GraphicBuffer& rhs);
    const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
    const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;


    status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
    status_t initWithSize(uint32_t inWidth, uint32_t inHeight,
            uint32_t inLayerCount, uint64_t inProducerUsage,
            PixelFormat inFormat, uint32_t inLayerCount,
            uint64_t inConsumerUsage, std::string requestorName);
            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();
    void free_handle();


+71 −52
Original line number Original line Diff line number Diff line
@@ -52,73 +52,33 @@ GraphicBuffer::GraphicBuffer()
    handle = NULL;
    handle = NULL;
}
}


// deprecated
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
        PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
    : GraphicBuffer(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
            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,
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage,
        uint64_t consumerUsage, std::string requestorName)
        uint64_t consumerUsage, std::string requestorName)
    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
    : GraphicBuffer()
      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
{
    width  =
    mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
    height =
    stride =
    format =
    usage  = 0;
    layerCount = 0;
    handle = NULL;
    mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
            producerUsage, consumerUsage, std::move(requestorName));
            producerUsage, consumerUsage, std::move(requestorName));
}
}


// deprecated
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
        uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
        uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
    : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE,
      mBufferMapper(GraphicBufferMapper::get()),
            inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
            inStride)
{
    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)
{
{
    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)
GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
      mBufferMapper(GraphicBufferMapper::get()),
      mBufferMapper(GraphicBufferMapper::get()),
@@ -134,6 +94,17 @@ GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
    handle = buffer->handle;
    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()
GraphicBuffer::~GraphicBuffer()
{
{
    if (handle) {
    if (handle) {
@@ -192,8 +163,8 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight,
        allocator.free(handle);
        allocator.free(handle);
        handle = 0;
        handle = 0;
    }
    }
    return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
    return initWithSize(inWidth, inHeight, inFormat, inLayerCount,
            "[Reallocation]");
            inUsage, inUsage, "[Reallocation]");
}
}


bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
@@ -207,7 +178,7 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
    return false;
    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,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage,
        uint64_t inConsumerUsage, std::string requestorName)
        uint64_t inConsumerUsage, std::string requestorName)
{
{
@@ -227,6 +198,54 @@ status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
    return err;
    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)
status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr)
{
{
    const Rect lockBounds(width, height);
    const Rect lockBounds(width, height);
+6 −9
Original line number Original line Diff line number Diff line
#include <private/dvr/ion_buffer.h>
#include <private/dvr/ion_buffer.h>
#include <ui/GraphicBufferMapper.h>


#include <log/log.h>
#include <log/log.h>
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#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",
  ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d",
           width, height, format, usage);
           width, height, format, usage);


  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
  buffer_ = new GraphicBuffer(width, height, format, usage);
  buffer_ = new GraphicBuffer(width, height, format, usage);
  if (mapper.registerBuffer(buffer_.get()) != OK) {
  if (buffer_->initCheck() != OK) {
    ALOGE("IonBuffer::Aloc: Failed to register buffer");
    ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
  }
  }
  return 0;
  return 0;
}
}
@@ -96,11 +94,10 @@ int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride,
      "usage=%d",
      "usage=%d",
      handle, width, height, stride, format, usage);
      handle, width, height, stride, format, usage);
  FreeHandle();
  FreeHandle();
  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
  buffer_ = new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE,
  buffer_ = new GraphicBuffer(width, height, format, 1, usage,
          width, height, format, 1, usage, stride);
                              stride, (native_handle_t*)handle, true);
  if (buffer_->initCheck() != OK) {
  if (mapper.registerBuffer(buffer_.get()) != OK) {
    ALOGE("IonBuffer::Import: Failed to import buffer");
    ALOGE("IonBuffer::Import: Failed to register cloned buffer");
    return -EINVAL;
    return -EINVAL;
  }
  }
  return 0;
  return 0;
+3 −3
Original line number Original line Diff line number Diff line
@@ -34,9 +34,9 @@ sp<GraphicBuffer> GetBufferFromHandle(native_handle_t* handle) {
  // capability. Otherwise assume a count of 1.
  // capability. Otherwise assume a count of 1.
  mapper.getLayerCount(handle, &layer_count);
  mapper.getLayerCount(handle, &layer_count);


  sp<GraphicBuffer> buffer = new GraphicBuffer(
  sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
      width, height, format, layer_count, producer_usage, consumer_usage,
      GraphicBuffer::TAKE_HANDLE, width, height, format, layer_count,
      stride, handle, true);
      producer_usage, consumer_usage, stride);


  return buffer;
  return buffer;
}
}
+4 −5
Original line number Original line Diff line number Diff line
@@ -69,11 +69,10 @@ sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
  mapper.getLayerCount(handle, &layer_count);
  mapper.getLayerCount(handle, &layer_count);


  // NOTE: Can't re-use |handle| since we don't own it.
  // NOTE: Can't re-use |handle| since we don't own it.
  sp<GraphicBuffer> buffer = new GraphicBuffer(
  sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
      width, height, format, layer_count, producer_usage, consumer_usage,
      GraphicBuffer::CLONE_HANDLE, width, height, format, layer_count,
      stride, native_handle_clone(handle), true);
      producer_usage, consumer_usage, stride);
  // Need to register the cloned buffer otherwise it can't be used later on.
  if (buffer->initCheck() != OK) {
  if (mapper.registerBuffer(buffer.get()) != OK) {
    ALOGE("Failed to register cloned buffer");
    ALOGE("Failed to register cloned buffer");
    return nullptr;
    return nullptr;
  }
  }