#undef LOG_TAG #define LOG_TAG "BufferQueueDebug" #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 //#define MTK_LOG_ENABLE 1 #include #include #include #include #include #include #include #include #include #include #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& gb, const sp& 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& 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