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
This commit is contained in:
Jamie Gennis 2010-10-07 13:46:55 -07:00
parent 0a49dee588
commit 309d3bb2f9
3 changed files with 44 additions and 19 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}