Add unique ID to GraphicBuffer

Adds a globally-unique ID (PID + sequence number) to every
GraphicBuffer, which will remain the same while crossing Binder,
even if the underlying handles change.

Change-Id: Ib11330a4c5e99621b82204e0adb31b9a88658426
This commit is contained in:
Dan Stoza 2014-03-28 15:10:52 -07:00
parent f0eaf25e92
commit b1363d37fc
2 changed files with 32 additions and 16 deletions

View File

@ -88,7 +88,8 @@ public:
uint32_t getUsage() const { return usage; } uint32_t getUsage() const { return usage; }
PixelFormat getPixelFormat() const { return format; } PixelFormat getPixelFormat() const { return format; }
Rect getBounds() const { return Rect(width, height); } Rect getBounds() const { return Rect(width, height); }
uint64_t getId() const { return mId; }
status_t reallocate(uint32_t w, uint32_t h, PixelFormat f, uint32_t usage); status_t reallocate(uint32_t w, uint32_t h, PixelFormat f, uint32_t usage);
status_t lock(uint32_t usage, void** vaddr); status_t lock(uint32_t usage, void** vaddr);
@ -146,6 +147,8 @@ private:
// If we're wrapping another buffer then this reference will make sure it // If we're wrapping another buffer then this reference will make sure it
// doesn't get freed. // doesn't get freed.
sp<ANativeWindowBuffer> mWrappedBuffer; sp<ANativeWindowBuffer> mWrappedBuffer;
uint64_t mId;
}; };
}; // namespace android }; // namespace android

View File

@ -34,9 +34,17 @@ namespace android {
// Buffer and implementation of ANativeWindowBuffer // Buffer and implementation of ANativeWindowBuffer
// =========================================================================== // ===========================================================================
static uint64_t getUniqueId() {
static volatile int32_t nextId = 0;
uint64_t id = static_cast<uint64_t>(getpid()) << 32;
id |= static_cast<uint32_t>(android_atomic_inc(&nextId));
return id;
}
GraphicBuffer::GraphicBuffer() GraphicBuffer::GraphicBuffer()
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR) { mInitCheck(NO_ERROR), mId(getUniqueId())
{
width = width =
height = height =
stride = stride =
@ -48,7 +56,7 @@ GraphicBuffer::GraphicBuffer()
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
PixelFormat reqFormat, uint32_t reqUsage) PixelFormat reqFormat, uint32_t reqUsage)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR) mInitCheck(NO_ERROR), mId(getUniqueId())
{ {
width = width =
height = height =
@ -64,7 +72,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone), : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
mBufferMapper(GraphicBufferMapper::get()), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR) mInitCheck(NO_ERROR), mId(getUniqueId())
{ {
width = w; width = w;
height = h; height = h;
@ -77,7 +85,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
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()),
mInitCheck(NO_ERROR), mWrappedBuffer(buffer) mInitCheck(NO_ERROR), mWrappedBuffer(buffer), mId(getUniqueId())
{ {
width = buffer->width; width = buffer->width;
height = buffer->height; height = buffer->height;
@ -201,7 +209,7 @@ status_t GraphicBuffer::unlock()
} }
size_t GraphicBuffer::getFlattenedSize() const { size_t GraphicBuffer::getFlattenedSize() const {
return (8 + (handle ? handle->numInts : 0))*sizeof(int); return (10 + (handle ? handle->numInts : 0))*sizeof(int);
} }
size_t GraphicBuffer::getFdCount() const { size_t GraphicBuffer::getFdCount() const {
@ -215,22 +223,24 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t&
size_t fdCountNeeded = GraphicBuffer::getFdCount(); size_t fdCountNeeded = GraphicBuffer::getFdCount();
if (count < fdCountNeeded) return NO_MEMORY; if (count < fdCountNeeded) return NO_MEMORY;
int* buf = static_cast<int*>(buffer); int32_t* buf = static_cast<int32_t*>(buffer);
buf[0] = 'GBFR'; buf[0] = 'GBFR';
buf[1] = width; buf[1] = width;
buf[2] = height; buf[2] = height;
buf[3] = stride; buf[3] = stride;
buf[4] = format; buf[4] = format;
buf[5] = usage; buf[5] = usage;
buf[6] = 0; buf[6] = static_cast<int32_t>(mId >> 32);
buf[7] = 0; buf[7] = static_cast<int32_t>(mId & 0xFFFFFFFFull);
buf[8] = 0;
buf[9] = 0;
if (handle) { if (handle) {
buf[6] = handle->numFds; buf[8] = handle->numFds;
buf[7] = handle->numInts; buf[9] = handle->numInts;
native_handle_t const* const h = handle; native_handle_t const* const h = handle;
memcpy(fds, h->data, h->numFds*sizeof(int)); memcpy(fds, h->data, h->numFds*sizeof(int));
memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int)); memcpy(&buf[10], h->data + h->numFds, h->numInts*sizeof(int));
} }
buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded); buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
@ -250,10 +260,10 @@ status_t GraphicBuffer::unflatten(
int const* buf = static_cast<int const*>(buffer); int const* buf = static_cast<int const*>(buffer);
if (buf[0] != 'GBFR') return BAD_TYPE; if (buf[0] != 'GBFR') return BAD_TYPE;
const size_t numFds = buf[6]; const size_t numFds = buf[8];
const size_t numInts = buf[7]; const size_t numInts = buf[9];
const size_t sizeNeeded = (8 + numInts) * sizeof(int); const size_t sizeNeeded = (10 + numInts) * sizeof(int);
if (size < sizeNeeded) return NO_MEMORY; if (size < sizeNeeded) return NO_MEMORY;
size_t fdCountNeeded = 0; size_t fdCountNeeded = 0;
@ -272,13 +282,16 @@ status_t GraphicBuffer::unflatten(
usage = buf[5]; usage = buf[5];
native_handle* h = native_handle_create(numFds, numInts); native_handle* h = native_handle_create(numFds, numInts);
memcpy(h->data, fds, numFds*sizeof(int)); memcpy(h->data, fds, numFds*sizeof(int));
memcpy(h->data + numFds, &buf[8], numInts*sizeof(int)); memcpy(h->data + numFds, &buf[10], numInts*sizeof(int));
handle = h; handle = h;
} else { } else {
width = height = stride = format = usage = 0; width = height = stride = format = usage = 0;
handle = NULL; handle = NULL;
} }
mId = static_cast<uint64_t>(buf[6]) << 32;
mId |= static_cast<uint32_t>(buf[7]);
mOwner = ownHandle; mOwner = ownHandle;
if (handle != 0) { if (handle != 0) {