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

Commit 309d3bb2 authored by Jamie Gennis's avatar Jamie Gennis
Browse files

Move binder magic from the Surface class to GraphicBuffer.

- Register buffers with Gralloc when unflattening a GraphicBuffer (rather than
doing it in the Surface class).
- Add support for a GraphicBuffer that wraps an android_native_window_t*.

Change-Id: I029ac086111bbac800e5ca37eb505f558b718cd8
parent 0a49dee5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ public:
    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
            uint32_t stride, native_handle_t* handle, bool keepOwnership);

    // create a buffer from an existing android_native_buffer_t
    GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership);

    // return status
    status_t initCheck() const;

@@ -137,6 +140,10 @@ private:
    GraphicBufferMapper& mBufferMapper;
    ssize_t mInitCheck;
    int mIndex;

    // If we're wrapping another buffer then this reference will make sure it
    // doesn't get freed.
    sp<android_native_buffer_t> mWrappedBuffer;
};

}; // namespace android
+17 −19
Original line number Diff line number Diff line
@@ -454,15 +454,6 @@ void Surface::init()

Surface::~Surface()
{
    // this is a client-side operation, the surface is destroyed, unmap
    // its buffers in this process.
    size_t size = mBuffers.size();
    for (size_t i=0 ; i<size ; i++) {
        if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
        }
    }

    // clear all references and trigger an IPC now, to make sure things
    // happen without delay, since these resources are quite heavy.
    mBuffers.clear();
@@ -1021,7 +1012,20 @@ void Surface::setSwapRectangle(const Rect& r) {

int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
{
    return buffer->getIndex();
    int idx = buffer->getIndex();
    if (idx < 0) {
        // The buffer doesn't have an index set.  See if the handle the same as
        // one of the buffers for which we do know the index.  This can happen
        // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
        // was dequeued from an ANativeWindow.
        for (int i = 0; i < mBuffers.size(); i++) {
            if (buffer->handle == mBuffers[i]->handle) {
                idx = mBuffers[i]->getIndex();
                break;
            }
        }
    }
    return idx;
}

status_t Surface::getBufferLocked(int index,
@@ -1035,7 +1039,6 @@ status_t Surface::getBufferLocked(int index,
    // free the current buffer
    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
    if (currentBuffer != 0) {
        getBufferMapper().unregisterBuffer(currentBuffer->handle);
        currentBuffer.clear();
    }

@@ -1043,7 +1046,7 @@ status_t Surface::getBufferLocked(int index,
    LOGE_IF(buffer==0,
            "ISurface::getBuffer(%d, %08x) returned NULL",
            index, usage);
    if (buffer != 0) { // this should never happen by construction
    if (buffer != 0) { // this should always happen by construction
        LOGE_IF(buffer->handle == NULL, 
                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
                "returned a buffer with a null handle",
@@ -1051,13 +1054,8 @@ status_t Surface::getBufferLocked(int index,
        err = mSharedBufferClient->getStatus();
        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
        if (!err && buffer->handle != NULL) {
            err = getBufferMapper().registerBuffer(buffer->handle);
            LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
                    err, strerror(-err));
            if (err == NO_ERROR) {
            currentBuffer = buffer;
            currentBuffer->setIndex(index);
            }
        } else {
            err = err<0 ? err : status_t(NO_MEMORY);
        }
+20 −0
Original line number Diff line number Diff line
@@ -77,6 +77,19 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
    handle = inHandle;
}

GraphicBuffer::GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership)
    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
      mBufferMapper(GraphicBufferMapper::get()),
      mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer)
{
    width  = buffer->width;
    height = buffer->height;
    stride = buffer->stride;
    format = buffer->format;
    usage  = buffer->usage;
    handle = buffer->handle;
}

GraphicBuffer::~GraphicBuffer()
{
    if (handle) {
@@ -87,12 +100,14 @@ GraphicBuffer::~GraphicBuffer()
void GraphicBuffer::free_handle()
{
    if (mOwner == ownHandle) {
        mBufferMapper.unregisterBuffer(handle);
        native_handle_close(handle);
        native_handle_delete(const_cast<native_handle*>(handle));
    } else if (mOwner == ownData) {
        GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
        allocator.free(handle);
    }
    mWrappedBuffer = 0;
}

status_t GraphicBuffer::initCheck() const {
@@ -253,6 +268,11 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
    }

    mOwner = ownHandle;

    if (handle != 0) {
        mBufferMapper.registerBuffer(handle);
    }

    return NO_ERROR;
}