unplugged-vendor/frameworks/native/services/surfaceflinger/mediatek/BufferQueueDebug.cpp

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