unplugged-system/frameworks/native/services/surfaceflinger/mediatek/Scheduler/VSyncHinter.cpp

93 lines
2.5 KiB
C++

#ifdef MTK_VSYNC_HINT_SUPPORT
#include "VSyncHinter.h"
#include <cinttypes>
#include <cstring>
#include <dlfcn.h>
#include <log/log.h>
#include <stdlib.h>
#include "vsync_hint/VsyncHintApi.h"
namespace android {
#undef LOG_TAG
#define LOG_TAG "VSyncHinter"
VSyncHinter& VSyncHinter::getInstance() {
static VSyncHinter gInstance;
return gInstance;
}
VSyncHinter::VSyncHinter() {
typedef VsyncHintApi* (*createVsyncHintPrototype)();
mVSyncHint = NULL;
mVSyncHintHandle = dlopen("libvsync_hint.so", RTLD_LAZY);
if (mVSyncHintHandle) {
createVsyncHintPrototype createPtr = reinterpret_cast<createVsyncHintPrototype>(dlsym(mVSyncHintHandle, "createVsyncHint"));
if (createPtr) {
mVSyncHint = createPtr();
if (!mVSyncHint) {
ALOGW("Failed to create VSyncHint");
}
} else {
ALOGW("Failed to get function: createVsyncHint");
}
} else {
ALOGW("Failed to load libvsync_hint.so");
}
mLastNotifyVsync = 0;
mLastPeriod = 0;
}
VSyncHinter::~VSyncHinter() {
if (mVSyncHint) {
delete mVSyncHint;
}
if (mVSyncHintHandle) {
dlclose(mVSyncHintHandle);
}
}
void VSyncHinter::fillVSyncInfo(VSyncInfo& info, const char* name) {
if (!strcmp(name, "sf")) {
info.mVSyncType = VsyncHintApi::VSYNC_TYPE_SF;
} else if (!strcmp(name, "app")) {
info.mVSyncType = VsyncHintApi::VSYNC_TYPE_APP;
} else {
info.mVSyncType = VsyncHintApi::VSYNC_TYPE_UNKNOWN;
}
}
void VSyncHinter::onDispSyncEvent(VSyncInfo& info, nsecs_t period) {
if (!mVSyncHint) {
return;
}
mVSyncHint->notifyVsync(info.mVSyncType, period);
}
void VSyncHinter::notifyVsyncPeriod(nsecs_t period) {
if (!mVSyncHint) {
return;
}
nsecs_t now = systemTime();
nsecs_t diff = now - mLastNotifyVsync;
float ratio = static_cast<float>(abs(mLastPeriod - period)) / static_cast<float>(mLastPeriod);
if (mLastNotifyVsync == 0 ||
mLastPeriod == 0 ||
diff > 300000000 || /* 300ms */
ratio > 0.01) { /* 1% */
mVSyncHint->notifyVsyncPeriod(period);
// ALOGI("notifyVsyncPeriod notify");
mLastNotifyVsync = now;
mLastPeriod = period;
}
//ALOGI("notifyVsyncPeriod mLastNotifyVsync=%" PRId64 ", mLastPeriod=%" PRId64 ", period=%" PRId64 ", diff=%" PRId64 ", ratio=%f",
// mLastNotifyVsync, mLastPeriod, period, diff, ratio);
}
} // namespace android
#endif