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
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index a3e85a9..c446633 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -72,6 +72,9 @@
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 @@
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 ebb0cc9..0994980 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -454,15 +454,6 @@
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 @@
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 @@
// free the current buffer
sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
if (currentBuffer != 0) {
- getBufferMapper().unregisterBuffer(currentBuffer->handle);
currentBuffer.clear();
}
@@ -1043,7 +1046,7 @@
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 @@
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 519c277..436e064 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -77,6 +77,19 @@
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 @@
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 @@
}
mOwner = ownHandle;
+
+ if (handle != 0) {
+ mBufferMapper.registerBuffer(handle);
+ }
+
return NO_ERROR;
}