Commit d4079aff authored by Dan Stoza's avatar Dan Stoza
Browse files

Add requestor name to GraphicBuffer alloc metadata

Adds a requestor name (usually the BufferQueue consumer's name) to the
metadata that GraphicBufferAllocator stores on allocation so that
`dumpsys SurfaceFlinger` can attempt to attribute buffer usage to the
correct client.

Bug: 30776557
Change-Id: I6e0f346584c871bb3b9d5481f82b697b0475a916
parent 68671533
......@@ -35,7 +35,7 @@ public:
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t usage,
status_t* error);
std::string requestorName, status_t* error) override;
};
......
......@@ -21,14 +21,15 @@
#include <sys/types.h>
#include <binder/IInterface.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <utils/RefBase.h>
#include <string>
namespace android {
// ----------------------------------------------------------------------------
class GraphicBuffer;
class IGraphicBufferAlloc : public IInterface
{
public:
......@@ -37,7 +38,13 @@ public:
/* Create a new GraphicBuffer for the client to use.
*/
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) = 0;
PixelFormat format, uint32_t usage, std::string requestorName,
status_t* error) = 0;
sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) {
return createGraphicBuffer(w, h, format, usage, "<Unknown>", error);
}
};
// ----------------------------------------------------------------------------
......
......@@ -26,6 +26,7 @@
#include <utils/Flattenable.h>
#include <utils/RefBase.h>
#include <string>
struct ANativeWindowBuffer;
......@@ -73,7 +74,7 @@ public:
// creates w * h buffer
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
uint32_t inUsage);
uint32_t inUsage, std::string requestorName = "<Unknown>");
// create a buffer from an existing handle
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
......@@ -159,7 +160,7 @@ private:
const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
uint32_t inUsage);
uint32_t inUsage, std::string requestorName);
void free_handle();
......
......@@ -61,7 +61,7 @@ public:
status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
uint32_t usage, buffer_handle_t* handle, uint32_t* stride,
uint64_t graphicBufferId);
uint64_t graphicBufferId, std::string requestorName);
status_t free(buffer_handle_t handle);
......@@ -76,6 +76,7 @@ private:
PixelFormat format;
uint32_t usage;
size_t size;
std::string requestorName;
};
static Mutex sLock;
......
......@@ -496,7 +496,8 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
status_t error;
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
width, height, format, usage, &error));
width, height, format, usage,
{mConsumerName.string(), mConsumerName.size()}, &error));
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
......@@ -1262,7 +1263,8 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
for (size_t i = 0; i < newBufferCount; ++i) {
status_t result = NO_ERROR;
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
allocWidth, allocHeight, allocFormat, allocUsage, &result));
allocWidth, allocHeight, allocFormat, allocUsage,
{mConsumerName.string(), mConsumerName.size()}, &result));
if (result != NO_ERROR) {
BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
" %u, usage %u)", width, height, format, usage);
......
......@@ -345,7 +345,8 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() {
// continues to use it.
sp<GraphicBuffer> buffer = new GraphicBuffer(
kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
GraphicBuffer::USAGE_SW_WRITE_RARELY);
GraphicBuffer::USAGE_SW_WRITE_RARELY,
"[GLConsumer debug texture]");
uint32_t* bits;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
uint32_t stride = buffer->getStride();
......
......@@ -32,9 +32,10 @@ GraphicBufferAlloc::~GraphicBufferAlloc() {
}
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(
new GraphicBuffer(width, height, format, usage));
uint32_t height, PixelFormat format, uint32_t usage,
std::string requestorName, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(
width, height, format, usage, std::move(requestorName)));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
......
......@@ -46,13 +46,19 @@ public:
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t usage,
status_t* error) {
std::string requestorName, status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
data.writeUint32(width);
data.writeUint32(height);
data.writeInt32(static_cast<int32_t>(format));
data.writeUint32(usage);
if (requestorName.empty()) {
requestorName += "[PID ";
requestorName += std::to_string(getpid());
requestorName += ']';
}
data.writeUtf8AsUtf16(requestorName);
remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
sp<GraphicBuffer> graphicBuffer;
status_t result = reply.readInt32();
......@@ -101,9 +107,11 @@ status_t BnGraphicBufferAlloc::onTransact(
uint32_t height = data.readUint32();
PixelFormat format = static_cast<PixelFormat>(data.readInt32());
uint32_t usage = data.readUint32();
status_t error;
sp<GraphicBuffer> result =
createGraphicBuffer(width, height, format, usage, &error);
status_t error = NO_ERROR;
std::string requestorName;
data.readUtf8FromUtf16(&requestorName);
sp<GraphicBuffer> result = createGraphicBuffer(width, height,
format, usage, requestorName, &error);
reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
......
......@@ -54,7 +54,7 @@ GraphicBuffer::GraphicBuffer()
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inUsage)
PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
......@@ -64,7 +64,8 @@ GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
format =
usage = 0;
handle = NULL;
mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage);
mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage,
std::move(requestorName));
}
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
......@@ -151,7 +152,7 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight,
allocator.free(handle);
handle = 0;
}
return initSize(inWidth, inHeight, inFormat, inUsage);
return initSize(inWidth, inHeight, inFormat, inUsage, "[Reallocation]");
}
bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
......@@ -165,12 +166,12 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
}
status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inUsage)
PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
status_t err = allocator.allocate(inWidth, inHeight, inFormat, inUsage,
&handle, &outStride, mId);
&handle, &outStride, mId, std::move(requestorName));
if (err == NO_ERROR) {
width = static_cast<int>(inWidth);
height = static_cast<int>(inHeight);
......
......@@ -55,13 +55,15 @@ void GraphicBufferAllocator::dump(String8& result) const
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
if (rec.size) {
snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
list.keyAt(i), rec.size/1024.0f,
rec.width, rec.stride, rec.height, rec.format, rec.usage);
rec.width, rec.stride, rec.height, rec.format, rec.usage,
rec.requestorName.c_str());
} else {
snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
list.keyAt(i),
rec.width, rec.stride, rec.height, rec.format, rec.usage);
rec.width, rec.stride, rec.height, rec.format, rec.usage,
rec.requestorName.c_str());
}
result.append(buffer);
total += rec.size;
......@@ -81,7 +83,7 @@ void GraphicBufferAllocator::dumpToSystemLog()
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
PixelFormat format, uint32_t usage, buffer_handle_t* handle,
uint32_t* stride, uint64_t graphicBufferId)
uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
{
ATRACE_CALL();
......@@ -140,6 +142,7 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
rec.format = format;
rec.usage = usage;
rec.size = static_cast<size_t>(height * (*stride) * bpp);
rec.requestorName = std::move(requestorName);
list.add(*handle, rec);
}
......
......@@ -1920,6 +1920,10 @@ EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
CHECK_ERROR_CONDITION("Unable to write format");
err = data.writeUint32(usage);
CHECK_ERROR_CONDITION("Unable to write usage");
err = data.writeUtf8AsUtf16(
std::string("[eglCreateNativeClientBufferANDROID pid ") +
std::to_string(getpid()) + ']');
CHECK_ERROR_CONDITION("Unable to write requestor name");
err = allocator->transact(IBinder::FIRST_CALL_TRANSACTION, data,
&reply);
CHECK_ERROR_CONDITION(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment