The PerfGenius SDK enables developers to directly communicate with hardware by using APIs by automatically reporting system state changes and setting the display frame rate and key threads. By using these APIs, you can keep your finger on the pulse of system state and change related parameters in time, receiving timely and accurate hardware responses. This solves problems such as frame freezing and frame loss in certain scenes and avoids performance waste in light-load scenes, optimizing the performance and power consumption of the phone system.
To use PerfGenius, you need to:

What You Will Create

This codelab will show how to use the sample code to call PerfGenius SDK APIs. The sample code will realize the following hardware capabilities:

What You Will Learn

Hardware Requirements

Software Requirements

Required Knowledge

To integrate the PerfGenius SDK, you must complete the following preparations:

  1. Register as a developer.
  2. Create an app in AppGallery Connect.

For details, please refer to PerfGenius in Accelerate Kit Development Guide.

  1. Create an Android Studio project.
  2. Modify the configuration items.
  3. Configure obfuscation scripts.

This section provides instructions for calling the PerfGenius SDK APIs for automatically reporting system state, and setting the display frame rate and key threads.

  1. Create the PerfGeniusApi_Main() function as the entry function in src/main/cpp/source/Main.cpp.
    // sample code entry void PerfGeniusApi_Main() { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "start Main()"); // open the so source and init socket connection, then call the APIs OpenSoResource(); // get the delete pointer deleteFunc(); }
  2. Obtain the handle to libPerfgeniusApi.so by using dlopen, pass the obtained handle to the GetPerfGeniusApiHandle() call in dlsym() to create a globally unique instance of the PerfGeniusApi class, and pass the pointer to the instance to subsequent API calls in src/main/cpp/source/Main.cpp.
    /** * get acckit pointer by dlopen() * */ void *libAccKit; typedef PerfGeniusApi *(*BuildPerfGeniusApi)(); typedef void (*DeletePerfGeniusApi)(); BuildPerfGeniusApi buildFunc; DeletePerfGeniusApi deleteFunc; PerfGeniusApi *kit; void OpenSoResource(JNIEnv *env) { libAccKit = dlopen("libPerfgeniusApi.so", RTLD_LAZY); if (!libAccKit) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "dlopen libPerfgeniusApi.so fail, close the handle"); return; } buildFunc = reinterpret_cast<BuildPerfGeniusApi>(dlsym(libAccKit, "GetPerfGeniusApiHandle")); deleteFunc = reinterpret_cast<DeletePerfGeniusApi>(dlsym(libAccKit, "DeletePerfGeniusApiHandle")); if (buildFunc == nullptr || deleteFunc == nullptr) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "dlsym GetPerfGeniusApiHandle|DeletePerfGeniusApiHandle fail, close the handle"); dlclose(libAccKit); return; } kit = buildFunc(); if (kit == nullptr) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "init kit return null. maybe socket error or selinux error.\n"); dlclose(libAccKit); return; } // Call the method you want, but you need to get a JNI environment pointer first. auto ret = InitSocket(kit, env); if (ret) { deleteFunc(); dlclose(libAccKit); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "init kit socket fail.\n"); return; } }
  3. Call the environment initialization function, the system event callback function, and other necessary API functions in src/main/cpp/source/Main.cpp.
    // init socket and others. int InitSocket(PerfGeniusApi *kit, JNIEnv *env) { auto ret = kit->Init(env); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "Init return: %d\n", ret); return ret; } // get the version of PerfGenius server. int GetVersionInfo(PerfGeniusApi *kit) { string outStr; auto ret = kit->GetApiVersion(outStr); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "GetApiVersion return: %s\n", outStr.c_str()); return ret; } // set system FPS, higher or lower. int SetFps(PerfGeniusApi *kit, int fps) { auto ret = kit->SetFrameRate(fps); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "SetFrameRate return %d\n", ret); return ret; } // reset the system FPS. int ResetFps(PerfGeniusApi *kit) { auto ret = kit->ResetFrameRate(); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "ResetFrameRate return %d\n", ret); return ret; } // get current FPS. int GetCurrentFps(PerfGeniusApi *kit) { auto ret = kit->GetCurrentFrameRate(); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "GetCurrentFrameRate return %d: ", ret); return ret; } // get supported FPS list. int GetFpsList(PerfGeniusApi *kit) { vector<int> fpsList; auto ret = kit->GetSupportedFrameRate(fpsList); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "get fps list return %d: ", ret); for (const auto &fps : fpsList) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", " %d", fps); } __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "\n"); return ret; } // set using scene, app, game etc. int SetUsingScence(PerfGeniusApi *kit, const char *sceneDescription) { string scene = sceneDescription; auto ret = kit->SetScene(scene); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "SetScene return %d: ", ret); return ret; } // get performance level of the system int GetPerformanceLevelMethod(PerfGeniusApi *kit) { auto ret = kit->GetPerformanceLevel(); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "GetPerformanceLevel return %d: ", ret); return ret; } // add threads to reduce the pressure in heavy-load scenes. int AddKeyThreadsMethod(PerfGeniusApi *kit) { vector<int32_t> tids; // add tids tids.push_back(10); auto ret = kit->AddKeyThreads(tids); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "AddKeyThreads return %d: ", ret); return ret; } // remove key threads int RemoveKeyThreadsMethod(PerfGeniusApi *kit) { vector<int32_t> tids; // add tids tids.push_back(10); auto ret = kit->RemoveKeyThreads(tids); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "RemoveKeyThreads return %d: ", ret); return ret; } // register system event call back listener int RegisterSystemEventMethod(PerfGeniusApi *kit) { string testStr = "user test str"; auto ret = kit->RegisterSystemEventCallback([&testStr](int currLevel) { printf("level changed %d, %s\n", currLevel, testStr.c_str()); }); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "RegisterSystemEventCallback return %d: ", ret); return ret; } // unregister system event int UnRegisterSystemEventMethod(PerfGeniusApi *kit) { auto ret = kit->UnRegisterSystemEventCallback(); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "UnRegisterSystemEventCallback return %d: ", ret); return ret; } // register performance tracer listener int RegisterPerformanceTracerMethod(PerfGeniusApi *kit, int rate) { auto ret = kit->RegisterPerformanceTracer(rate, [](vector<uint32_t> &data) { if (data.empty()) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "performance tracer died\n"); return; } if (data.size() % 4 != 0) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "performance tracer callback invalid data len %d\n", static_cast<int>(data.size())); return; } for (int i = 0; i < data.size(); i += 4) { __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", " %u, %u, %u %u\n", data[i], data[i + 1], data[i + 2], data[i + 3]); } }); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "RegisterPerformanceTracer return %d: ", ret); return ret; } // unregister performance tracer int UnRegisterPerformanceTracerMethod(PerfGeniusApi *kit) { auto ret = kit->UnRegisterPerformanceTracer(); __android_log_print(ANDROID_LOG_DEBUG, "perfgeniusdemo", "UnRegisterPerformanceTracer return %d: ", ret); return ret; }

Well done. You have successfully completed this codelab and learned how to:

For more information, please click the following links:


Code copied