1 /* 2 * Copyright 2019 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 17 #include "GpuStatsPuller.h" 18 19 #include <binder/IServiceManager.h> 20 #include <graphicsenv/GpuStatsInfo.h> 21 #include <graphicsenv/IGpuService.h> 22 23 #include "logd/LogEvent.h" 24 25 #include "stats_log_util.h" 26 #include "statslog.h" 27 28 namespace android { 29 namespace os { 30 namespace statsd { 31 32 using android::util::ProtoReader; 33 34 GpuStatsPuller::GpuStatsPuller(const int tagId) : StatsPuller(tagId) { 35 } 36 37 static sp<IGpuService> getGpuService() { 38 const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu")); 39 if (!binder) { 40 ALOGE("Failed to get gpu service"); 41 return nullptr; 42 } 43 44 return interface_cast<IGpuService>(binder); 45 } 46 47 static bool pullGpuStatsGlobalInfo(const sp<IGpuService>& gpuService, 48 std::vector<std::shared_ptr<LogEvent>>* data) { 49 std::vector<GpuStatsGlobalInfo> stats; 50 status_t status = gpuService->getGpuStatsGlobalInfo(&stats); 51 if (status != OK) { 52 return false; 53 } 54 55 data->clear(); 56 data->reserve(stats.size()); 57 for (const auto& info : stats) { 58 std::shared_ptr<LogEvent> event = make_shared<LogEvent>( 59 android::util::GPU_STATS_GLOBAL_INFO, getWallClockNs(), getElapsedRealtimeNs()); 60 if (!event->write(info.driverPackageName)) return false; 61 if (!event->write(info.driverVersionName)) return false; 62 if (!event->write((int64_t)info.driverVersionCode)) return false; 63 if (!event->write(info.driverBuildTime)) return false; 64 if (!event->write((int64_t)info.glLoadingCount)) return false; 65 if (!event->write((int64_t)info.glLoadingFailureCount)) return false; 66 if (!event->write((int64_t)info.vkLoadingCount)) return false; 67 if (!event->write((int64_t)info.vkLoadingFailureCount)) return false; 68 if (!event->write(info.vulkanVersion)) return false; 69 if (!event->write(info.cpuVulkanVersion)) return false; 70 if (!event->write(info.glesVersion)) return false; 71 if (!event->write((int64_t)info.angleLoadingCount)) return false; 72 if (!event->write((int64_t)info.angleLoadingFailureCount)) return false; 73 event->init(); 74 data->emplace_back(event); 75 } 76 77 return true; 78 } 79 80 static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService, 81 std::vector<std::shared_ptr<LogEvent>>* data) { 82 std::vector<GpuStatsAppInfo> stats; 83 status_t status = gpuService->getGpuStatsAppInfo(&stats); 84 if (status != OK) { 85 return false; 86 } 87 88 data->clear(); 89 data->reserve(stats.size()); 90 for (const auto& info : stats) { 91 std::shared_ptr<LogEvent> event = make_shared<LogEvent>( 92 android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs()); 93 if (!event->write(info.appPackageName)) return false; 94 if (!event->write((int64_t)info.driverVersionCode)) return false; 95 if (!event->write(int64VectorToProtoByteString(info.glDriverLoadingTime))) return false; 96 if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false; 97 if (!event->write(int64VectorToProtoByteString(info.angleDriverLoadingTime))) return false; 98 if (!event->write(info.cpuVulkanInUse)) return false; 99 event->init(); 100 data->emplace_back(event); 101 } 102 103 return true; 104 } 105 106 bool GpuStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) { 107 const sp<IGpuService> gpuService = getGpuService(); 108 if (!gpuService) { 109 return false; 110 } 111 112 switch (mTagId) { 113 case android::util::GPU_STATS_GLOBAL_INFO: 114 return pullGpuStatsGlobalInfo(gpuService, data); 115 case android::util::GPU_STATS_APP_INFO: 116 return pullGpuStatsAppInfo(gpuService, data); 117 default: 118 break; 119 } 120 121 return false; 122 } 123 124 static std::string protoOutputStreamToByteString(ProtoOutputStream& proto) { 125 if (!proto.size()) return ""; 126 127 std::string byteString; 128 sp<ProtoReader> reader = proto.data(); 129 while (reader->readBuffer() != nullptr) { 130 const size_t toRead = reader->currentToRead(); 131 byteString.append((char*)reader->readBuffer(), toRead); 132 reader->move(toRead); 133 } 134 135 if (byteString.size() != proto.size()) return ""; 136 137 return byteString; 138 } 139 140 std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) { 141 if (value.empty()) return ""; 142 143 ProtoOutputStream proto; 144 for (const auto& ele : value) { 145 proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED | 146 1 /* field id */, 147 (long long)ele); 148 } 149 150 return protoOutputStreamToByteString(proto); 151 } 152 153 } // namespace statsd 154 } // namespace os 155 } // namespace android 156