235 lines
7.2 KiB
C++
235 lines
7.2 KiB
C++
#undef LOG_TAG
|
|
#define LOG_TAG "BufferQueueDebug"
|
|
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
|
//#define LOG_NDEBUG 0
|
|
//#define MTK_LOG_ENABLE 1
|
|
#include <cmath>
|
|
#include <dlfcn.h>
|
|
|
|
#include <cutils/properties.h>
|
|
#include <log/log.h>
|
|
#include <binder/IPCThreadState.h>
|
|
#include <gui/BufferItem.h>
|
|
#include <gui/IGraphicBufferConsumer.h>
|
|
#include <gui/IConsumerListener.h>
|
|
#include <mediatek/BufferQueueDebug.h>
|
|
#include <mediatek/BufferDumpAPILoader.h>
|
|
|
|
#define IONDBG_LENGDTH 48
|
|
#define IONDBG_PREFIX_LENGDTH 17
|
|
|
|
#undef BQ_LOGV
|
|
#undef BQ_LOGD
|
|
#undef BQ_LOGI
|
|
#undef BQ_LOGW
|
|
#undef BQ_LOGE
|
|
#define BQ_LOGI(x, ...) ALOGI("[%s](this:%p,id:%d,api:%d,p:%d,c:%d) " x, mConsumerName.c_str(), \
|
|
this, mId, mConnectedApi, mProducerPid, mConsumerPid, ##__VA_ARGS__)
|
|
#define BQ_LOGE(x, ...) ALOGE("[%s](this:%p,id:%d,api:%d,p:%d,c:%d) " x, mConsumerName.c_str(), \
|
|
this, mId, mConnectedApi, mProducerPid, mConsumerPid, ##__VA_ARGS__)
|
|
#define BQP_LOGI(x, ...) LOG_PRI(ANDROID_LOG_INFO,"BufferQueueProducer", \
|
|
"[%s](this:%p,id:%d,api:%d,p:%d,c:%d) " x, mConsumerName.c_str(), this, mId, \
|
|
mConnectedApi, mProducerPid, mConsumerPid, ##__VA_ARGS__)
|
|
#define BQP_LOGE(x, ...) LOG_PRI(ANDROID_LOG_ERROR, "BufferQueueProducer", \
|
|
"[%s](this:%p,id:%d,api:%d,p:%d,c:%d) " x, mConsumerName.c_str(), this, mId, \
|
|
mConnectedApi, mProducerPid, mConsumerPid, ##__VA_ARGS__)
|
|
#define BQP_LOGV(x, ...)
|
|
|
|
#define BQC_LOGI(x, ...) LOG_PRI(ANDROID_LOG_INFO, "BufferQueueConsumer", \
|
|
"[%s](this:%p,id:%d,api:%d,p:%d,c:%d) " x, mConsumerName.c_str(), this, mId, \
|
|
mConnectedApi, mProducerPid, mConsumerPid, ##__VA_ARGS__)
|
|
#define BQC_LOGV(x, ...)
|
|
|
|
namespace android {
|
|
// -----------------------------------------------------------------------------
|
|
|
|
BufferQueueDebug::BufferQueueDebug() :
|
|
mId(-1),
|
|
mConnectedApi(0),
|
|
mPid(-1),
|
|
mProducerPid(-1),
|
|
mConsumerPid(-1),
|
|
mLine(false),
|
|
mLineCnt(0),
|
|
mDump(NULL) {}
|
|
|
|
BufferQueueDebug::~BufferQueueDebug() {
|
|
if (mDump) {
|
|
delete mDump;
|
|
}
|
|
}
|
|
|
|
// BufferQueueCore part
|
|
// -----------------------------------------------------------------------------
|
|
void BufferQueueDebug::onConstructor(const std::string& consumerName) {
|
|
mPid = getpid();
|
|
mConsumerName = consumerName;
|
|
if (sscanf(mConsumerName.c_str(), "unnamed-%*d-%d", &mId) != 1) {
|
|
BQ_LOGE("id info cannot be read from '%s'", mConsumerName.c_str());
|
|
}
|
|
|
|
if (NO_ERROR == getProcessName(mPid, mConsumerProcName)) {
|
|
BQ_LOGI("BufferQueue core=(%d:%s)", mPid, mConsumerProcName.c_str());
|
|
} else {
|
|
BQ_LOGI("BufferQueue core=(%d:\?\?\?)", mPid);
|
|
}
|
|
|
|
mDump = GuiDebugModuleLoader::getInstance().CreateBQDumpInstance();
|
|
if (mDump) {
|
|
mDump->setName(mConsumerName);
|
|
} else {
|
|
BQ_LOGE("CreateBQDumpInstance fail");
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onDestructor() {
|
|
BQ_LOGI("%s()", __FUNCTION__);
|
|
}
|
|
|
|
void BufferQueueDebug::onDump(String8 &result, const String8& prefix) const {
|
|
//BQ_LOGI("%s()", __FUNCTION__);
|
|
if (mDump) {
|
|
mDump->dump(result, prefix.string());
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onFreeBufferLocked(const int slot) {
|
|
//BQ_LOGI("%s()", __FUNCTION__);
|
|
if (mDump) {
|
|
mDump->onFreeBuffer(slot);
|
|
}
|
|
}
|
|
|
|
// BufferQueueConsumer part
|
|
// -----------------------------------------------------------------------------
|
|
void BufferQueueDebug::onSetConsumerName(const std::string& consumerName) {
|
|
//BQ_LOGI("%s()", __FUNCTION__);
|
|
mConsumerName = consumerName;
|
|
if (mConsumerName.length() > IONDBG_LENGDTH - 1) {
|
|
std::string shortened;
|
|
unsigned int diff_length = IONDBG_LENGDTH - IONDBG_PREFIX_LENGDTH - 2;
|
|
shortened.append(consumerName, IONDBG_PREFIX_LENGDTH);
|
|
shortened.append("_");
|
|
shortened.append(consumerName, mConsumerName.length() - diff_length, diff_length);
|
|
mMiniConusmerName = shortened;
|
|
} else {
|
|
mMiniConusmerName = mConsumerName;
|
|
}
|
|
|
|
// update dump info
|
|
if (mDump) {
|
|
mDump->setName(mConsumerName);
|
|
}
|
|
|
|
toggleDrawDebugLine();
|
|
}
|
|
|
|
void BufferQueueDebug::onAcquire(
|
|
const int buf,
|
|
const sp<GraphicBuffer>& gb,
|
|
const sp<Fence>& fence,
|
|
const int64_t& timestamp,
|
|
const uint32_t& transform,
|
|
const BufferItem* const buffer) {
|
|
//BQ_LOGI("%s(), id = %d", __FUNCTION__, buf);
|
|
if (!mDump) {
|
|
return;
|
|
}
|
|
// also inform acquireBuffer to mDump
|
|
uint64_t frameNumber = buffer ? buffer->mFrameNumber : 0;
|
|
mDump->onAcquireBuffer(buf, gb, fence, timestamp, transform, frameNumber);
|
|
|
|
// draw white debug line
|
|
if (mLine) {
|
|
if (fence.get()) {
|
|
fence->waitForever("BufferQueueDebug::acquireBuffer");
|
|
}
|
|
|
|
mDump->drawDebugLineToGraphicBuffer(gb, mLineCnt, 0xFF);
|
|
mLineCnt++;
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onRelease(const int buf) {
|
|
//BQ_LOGI("%s(), id = %d", __FUNCTION__, buf);
|
|
if (mDump) {
|
|
mDump->onReleaseBuffer(buf);
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onConsumerConnect() {
|
|
// check if local or remote connection by the consumer listener
|
|
// (in most cases, consumer side is a local connection)
|
|
mConsumerPid = getpid();
|
|
|
|
String8 name;
|
|
if (NO_ERROR == getProcessName(mConsumerPid, mConsumerProcName)) {
|
|
BQC_LOGV("connect(C): consumer=(%d:%s)",
|
|
mConsumerPid, mConsumerProcName.c_str());
|
|
} else {
|
|
BQC_LOGV("connect(C): consumer=(%d:\?\?\?)", mConsumerPid);
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onConsumerDisconnectHead() {
|
|
mConsumerPid = -1;
|
|
}
|
|
|
|
void BufferQueueDebug::onConsumerDisconnectTail() {
|
|
BQC_LOGV("disconnect(C)");
|
|
if (mDump) {
|
|
mDump->onConsumerDisconnect();
|
|
}
|
|
}
|
|
|
|
// BufferQueueProducer part
|
|
// -----------------------------------------------------------------------------
|
|
void BufferQueueDebug::setIonInfo(const sp<GraphicBuffer>& gb) {
|
|
if (gb->handle != NULL) {
|
|
if (mDump)
|
|
mDump->onSetIonInfo(gb, mProducerPid, mId, IONDBG_LENGDTH, mMiniConusmerName);
|
|
} else {
|
|
BQP_LOGE("handle of graphic buffer is NULL when producer set ION info");
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::checkFps() {
|
|
if (mDump) {
|
|
std::string result;
|
|
if (mDump->onCheckFps(&result))
|
|
BQP_LOGI("%s", result.c_str());
|
|
}
|
|
}
|
|
|
|
void BufferQueueDebug::onProducerConnect(const int api) {
|
|
mProducerPid = IPCThreadState::self()->getCallingPid();
|
|
mConnectedApi = api;
|
|
if (NO_ERROR == getProcessName(mProducerPid, mProducerProcName)) {
|
|
BQP_LOGV("connect(P): api=%d producer=(%d:%s) ", mConnectedApi,
|
|
mProducerPid, mProducerProcName.c_str());
|
|
} else {
|
|
BQP_LOGV("connect(P): api=%d producer=(%d:\?\?\?)", mConnectedApi,
|
|
mProducerPid);
|
|
}
|
|
|
|
toggleDrawDebugLine();
|
|
}
|
|
|
|
void BufferQueueDebug::onProducerDisconnect() {
|
|
BQP_LOGV("disconnect(P): api=%d producer=(%d:%s) ", mConnectedApi,
|
|
mProducerPid, mProducerProcName.c_str());
|
|
mProducerPid = -1;
|
|
}
|
|
|
|
void BufferQueueDebug::toggleDrawDebugLine() {
|
|
char value[PROPERTY_VALUE_MAX];
|
|
property_get("vendor.debug.bq.line", value, "GOD'S IN HIS HEAVEN, ALL'S RIGHT WITH THE WORLD.");
|
|
mLine = mConsumerName.find(value) != std::string::npos;
|
|
mLineCnt = 0;
|
|
if (mLine) {
|
|
BQ_LOGI("switch on debug line");
|
|
}
|
|
}
|
|
|
|
}; // namespace android
|