GpuService.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  17. #include "GpuService.h"
  18. #include <android-base/stringprintf.h>
  19. #include <binder/IPCThreadState.h>
  20. #include <binder/IResultReceiver.h>
  21. #include <binder/Parcel.h>
  22. #include <binder/PermissionCache.h>
  23. #include <cutils/properties.h>
  24. #include <private/android_filesystem_config.h>
  25. #include <utils/String8.h>
  26. #include <utils/Trace.h>
  27. #include <vkjson.h>
  28. #include "gpustats/GpuStats.h"
  29. namespace android {
  30. using base::StringAppendF;
  31. namespace {
  32. status_t cmdHelp(int out);
  33. status_t cmdVkjson(int out, int err);
  34. void dumpGameDriverInfo(std::string* result);
  35. } // namespace
  36. const String16 sDump("android.permission.DUMP");
  37. const char* const GpuService::SERVICE_NAME = "gpu";
  38. GpuService::GpuService() : mGpuStats(std::make_unique<GpuStats>()){};
  39. void GpuService::setGpuStats(const std::string& driverPackageName,
  40. const std::string& driverVersionName, uint64_t driverVersionCode,
  41. int64_t driverBuildTime, const std::string& appPackageName,
  42. const int32_t vulkanVersion, GraphicsEnv::Driver driver,
  43. bool isDriverLoaded, int64_t driverLoadingTime) {
  44. mGpuStats->insert(driverPackageName, driverVersionName, driverVersionCode, driverBuildTime,
  45. appPackageName, vulkanVersion, driver, isDriverLoaded, driverLoadingTime);
  46. }
  47. status_t GpuService::getGpuStatsGlobalInfo(std::vector<GpuStatsGlobalInfo>* outStats) const {
  48. mGpuStats->pullGlobalStats(outStats);
  49. return OK;
  50. }
  51. status_t GpuService::getGpuStatsAppInfo(std::vector<GpuStatsAppInfo>* outStats) const {
  52. mGpuStats->pullAppStats(outStats);
  53. return OK;
  54. }
  55. void GpuService::setTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode,
  56. const GraphicsEnv::Stats stats, const uint64_t value) {
  57. mGpuStats->insertTargetStats(appPackageName, driverVersionCode, stats, value);
  58. }
  59. status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
  60. ATRACE_CALL();
  61. ALOGV("shellCommand");
  62. for (size_t i = 0, n = args.size(); i < n; i++)
  63. ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).string());
  64. if (args.size() >= 1) {
  65. if (args[0] == String16("vkjson")) return cmdVkjson(out, err);
  66. if (args[0] == String16("help")) return cmdHelp(out);
  67. }
  68. // no command, or unrecognized command
  69. cmdHelp(err);
  70. return BAD_VALUE;
  71. }
  72. status_t GpuService::doDump(int fd, const Vector<String16>& args, bool /*asProto*/) {
  73. std::string result;
  74. IPCThreadState* ipc = IPCThreadState::self();
  75. const int pid = ipc->getCallingPid();
  76. const int uid = ipc->getCallingUid();
  77. if ((uid != AID_SHELL) && !PermissionCache::checkPermission(sDump, pid, uid)) {
  78. StringAppendF(&result, "Permission Denial: can't dump gpu from pid=%d, uid=%d\n", pid, uid);
  79. } else {
  80. bool dumpAll = true;
  81. size_t index = 0;
  82. size_t numArgs = args.size();
  83. if (numArgs) {
  84. if ((index < numArgs) && (args[index] == String16("--gpustats"))) {
  85. index++;
  86. mGpuStats->dump(args, &result);
  87. dumpAll = false;
  88. }
  89. }
  90. if (dumpAll) {
  91. dumpGameDriverInfo(&result);
  92. result.append("\n");
  93. mGpuStats->dump(Vector<String16>(), &result);
  94. result.append("\n");
  95. }
  96. }
  97. write(fd, result.c_str(), result.size());
  98. return NO_ERROR;
  99. }
  100. namespace {
  101. status_t cmdHelp(int out) {
  102. FILE* outs = fdopen(out, "w");
  103. if (!outs) {
  104. ALOGE("vkjson: failed to create out stream: %s (%d)", strerror(errno), errno);
  105. return BAD_VALUE;
  106. }
  107. fprintf(outs,
  108. "GPU Service commands:\n"
  109. " vkjson dump Vulkan properties as JSON\n");
  110. fclose(outs);
  111. return NO_ERROR;
  112. }
  113. void vkjsonPrint(FILE* out) {
  114. std::string json = VkJsonInstanceToJson(VkJsonGetInstance());
  115. fwrite(json.data(), 1, json.size(), out);
  116. fputc('\n', out);
  117. }
  118. status_t cmdVkjson(int out, int /*err*/) {
  119. FILE* outs = fdopen(out, "w");
  120. if (!outs) {
  121. int errnum = errno;
  122. ALOGE("vkjson: failed to create output stream: %s", strerror(errnum));
  123. return -errnum;
  124. }
  125. vkjsonPrint(outs);
  126. fclose(outs);
  127. return NO_ERROR;
  128. }
  129. void dumpGameDriverInfo(std::string* result) {
  130. if (!result) return;
  131. char stableGameDriver[PROPERTY_VALUE_MAX] = {};
  132. property_get("ro.gfx.driver.0", stableGameDriver, "unsupported");
  133. StringAppendF(result, "Stable Game Driver: %s\n", stableGameDriver);
  134. char preReleaseGameDriver[PROPERTY_VALUE_MAX] = {};
  135. property_get("ro.gfx.driver.1", preReleaseGameDriver, "unsupported");
  136. StringAppendF(result, "Pre-release Game Driver: %s\n", preReleaseGameDriver);
  137. }
  138. } // anonymous namespace
  139. } // namespace android