diff options
| -rw-r--r-- | include/ui/GraphicBuffer.h | 7 | ||||
| -rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 36 | ||||
| -rw-r--r-- | libs/ui/GraphicBuffer.cpp | 20 | 
3 files changed, 44 insertions, 19 deletions
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index a3e85a96aa..c446633bc4 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -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 diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index ebb0cc9b8a..099498041a 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -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); -            } +            currentBuffer = buffer; +            currentBuffer->setIndex(index);          } else {              err = err<0 ? err : status_t(NO_MEMORY);          } diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 519c277c60..436e064716 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -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;  }  |