13 KiB
13 KiB
GpuInfo 增强功能使用示例
新增功能说明
GpuInfo 类已增强并修复以下功能:
- 修复了
getOpenGLVersion()可能返回空值的问题 - 新增 GPU 最大频率获取
- 新增 GPU 架构信息
- 新增 GPU 缓存大小
- 新增 GPU 内存带宽
- 新增计算单元和着色单元数量
- 所有返回文本已国际化为英文
核心数据类
GpuDetailedInfo
data class GpuDetailedInfo(
val maxFrequency: Int?, // 最大频率(MHz)
val architecture: String?, // 架构名称
val cacheSize: Int?, // 缓存大小(KB)
val bandwidth: Double?, // 内存带宽(GB/s)
val computeUnits: Int?, // 计算单元数量
val shadingUnits: Int? // 着色单元数量
)
支持的 GPU 型号
Qualcomm Adreno 系列
- Adreno 740, 730, 725, 720, 710, 702
- Adreno 690, 660, 650, 640, 630, 620
ARM Mali 系列
- Mali-G720, G715, G710, G610
- Mali-G78, G77, G76, G72, G71
- Mali-G68, G57, G52, G51
Apple GPU
- A17/M3, A16/M2, A15/M1
PowerVR 系列
- PowerVR GE8320
使用示例
1. 获取基本 GPU 信息
val gpuInfo = GpuInfo(context)
// 获取供应商
val vendor = gpuInfo.getVendorName()
println("GPU Vendor: $vendor")
// 获取型号
val renderer = gpuInfo.getRendererName()
println("GPU Model: $renderer")
// 获取设备类型
val deviceType = gpuInfo.getDeviceTypeDescription()
println("Device Type: $deviceType")
// 获取 OpenGL ES 版本(已修复)
val glVersion = gpuInfo.getOpenGLVersion()
println("OpenGL ES Version: $glVersion")
// 获取 Vulkan 版本
val vkVersion = gpuInfo.getVulkanApiVersion()
println("Vulkan Version: $vkVersion")
2. 获取 GPU 详细规格
val gpuInfo = GpuInfo(context)
// 获取完整的 GPU 详细信息
val detailedInfo = gpuInfo.getGpuDetailedInfo()
println("=== GPU Specifications ===")
println("Architecture: ${detailedInfo.architecture}")
println("Max Frequency: ${detailedInfo.maxFrequency} MHz")
println("Cache Size: ${detailedInfo.cacheSize} KB")
println("Memory Bandwidth: ${detailedInfo.bandwidth} GB/s")
println("Compute Units: ${detailedInfo.computeUnits}")
println("Shading Units: ${detailedInfo.shadingUnits}")
3. 获取单个规格属性
val gpuInfo = GpuInfo(context)
// 获取最大频率
val maxFreq = gpuInfo.getMaxFrequency()
println("Max Frequency: ${maxFreq ?: "Unknown"} MHz")
// 获取架构
val arch = gpuInfo.getArchitecture()
println("Architecture: ${arch ?: "Unknown"}")
// 获取缓存大小
val cache = gpuInfo.getCacheSize()
println("Cache: ${cache ?: "Unknown"} KB")
// 获取带宽
val bandwidth = gpuInfo.getBandwidth()
println("Bandwidth: ${bandwidth ?: "Unknown"} GB/s")
// 获取计算单元
val computeUnits = gpuInfo.getComputeUnits()
println("Compute Units: ${computeUnits ?: "Unknown"}")
// 获取着色单元
val shadingUnits = gpuInfo.getShadingUnits()
println("Shading Units: ${shadingUnits ?: "Unknown"}")
4. 获取完整的 GPU 摘要
val gpuInfo = GpuInfo(context)
// 获取格式化的完整摘要
val summary = gpuInfo.getGpuSummary()
println(summary)
输出示例:
=== GPU Basic Info ===
Vendor: Qualcomm
Model: Adreno (TM) 730
Type: Integrated GPU
=== GPU Specifications ===
Architecture: Adreno 730
Max Frequency: 818 MHz
Cache Size: 1536 KB
Memory Bandwidth: 44.8 GB/s
Compute Units: 6
Shading Units: 768
=== Vulkan Info ===
Supported: Yes
API Version: 1.3.0
Driver Version: 512
--- Vulkan Device ---
Device Name: Adreno (TM) 730
Device ID: 43051011
Vendor ID: 0x5143
Registered Vendor: Qualcomm
Device Type: Integrated GPU
API Version: 1.3.0
=== OpenGL ES Info ===
Vendor: Qualcomm
Renderer: Adreno (TM) 730
Version: OpenGL ES 3.2
Extension Count: 247
=== EGL Info ===
Vendor: Qualcomm
Version: 1.5
Client API: OpenGL_ES
Extension Count: 52
5. 计算 GPU 性能指标
val gpuInfo = GpuInfo(context)
val detailedInfo = gpuInfo.getGpuDetailedInfo()
// 计算理论峰值性能(GFLOPS)
// 公式:着色单元 * 频率 * 2 (FMA operations)
val theoreticalGFLOPS = detailedInfo.shadingUnits?.let { units ->
detailedInfo.maxFrequency?.let { freq ->
(units * freq * 2) / 1000.0
}
}
println("Theoretical Peak Performance: ${theoreticalGFLOPS?.let {
String.format("%.1f GFLOPS", it)
} ?: "Unknown"}")
// 计算带宽利用率(假设某个应用需要 10 GB/s)
val requiredBandwidth = 10.0
val bandwidthUtilization = detailedInfo.bandwidth?.let {
(requiredBandwidth / it * 100).coerceIn(0.0, 100.0)
}
println("Bandwidth Utilization: ${bandwidthUtilization?.let {
String.format("%.1f%%", it)
} ?: "Unknown"}")
6. 比较不同 GPU
fun compareGpus(gpu1Name: String, gpu2Name: String) {
val gpuInfo = GpuInfo(context)
// 模拟获取两个 GPU 的信息(实际使用中,这些可能来自数据库)
val spec1 = gpuInfo.getGpuSpecsByRenderer(gpu1Name.lowercase())
val spec2 = gpuInfo.getGpuSpecsByRenderer(gpu2Name.lowercase())
println("=== GPU Comparison ===")
println("GPU 1: $gpu1Name")
println(" Max Freq: ${spec1.maxFrequency} MHz")
println(" Bandwidth: ${spec1.bandwidth} GB/s")
println(" Compute Units: ${spec1.computeUnits}")
println("\nGPU 2: $gpu2Name")
println(" Max Freq: ${spec2.maxFrequency} MHz")
println(" Bandwidth: ${spec2.bandwidth} GB/s")
println(" Compute Units: ${spec2.computeUnits}")
// 简单性能比较
val perfScore1 = (spec1.maxFrequency ?: 0) * (spec1.computeUnits ?: 0)
val perfScore2 = (spec2.maxFrequency ?: 0) * (spec2.computeUnits ?: 0)
println("\nPerformance Score:")
println(" $gpu1Name: $perfScore1")
println(" $gpu2Name: $perfScore2")
if (perfScore1 > perfScore2) {
val diff = ((perfScore1 - perfScore2).toDouble() / perfScore2 * 100)
println(" $gpu1Name is ${String.format("%.1f%%", diff)} faster")
} else if (perfScore2 > perfScore1) {
val diff = ((perfScore2 - perfScore1).toDouble() / perfScore1 * 100)
println(" $gpu2Name is ${String.format("%.1f%%", diff)} faster")
}
}
// 使用示例
compareGpus("Adreno 730", "Mali-G78")
7. 在 Jetpack Compose 中显示
@Composable
fun GpuInfoCard() {
val context = LocalContext.current
val gpuInfo = remember { GpuInfo(context) }
val detailedInfo = remember { gpuInfo.getGpuDetailedInfo() }
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
elevation = CardDefaults.cardElevation(4.dp)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "GPU Information",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(16.dp))
// 基本信息
InfoRow("Vendor", gpuInfo.getVendorName() ?: "Unknown")
InfoRow("Model", gpuInfo.getRendererName() ?: "Unknown")
InfoRow("Type", gpuInfo.getDeviceTypeDescription() ?: "Unknown")
Divider(modifier = Modifier.padding(vertical = 8.dp))
// 详细规格
Text(
text = "Specifications",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
detailedInfo.architecture?.let {
InfoRow("Architecture", it)
}
detailedInfo.maxFrequency?.let {
InfoRow("Max Frequency", "$it MHz")
}
detailedInfo.cacheSize?.let {
InfoRow("Cache Size", "$it KB")
}
detailedInfo.bandwidth?.let {
InfoRow("Bandwidth", String.format("%.1f GB/s", it))
}
detailedInfo.computeUnits?.let {
InfoRow("Compute Units", it.toString())
}
detailedInfo.shadingUnits?.let {
InfoRow("Shading Units", it.toString())
}
Divider(modifier = Modifier.padding(vertical = 8.dp))
// API 信息
Text(
text = "API Support",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
InfoRow("OpenGL ES", gpuInfo.getOpenGLVersion() ?: "Unknown")
InfoRow("Vulkan", gpuInfo.getVulkanApiVersion() ?: "Not Supported")
InfoRow("EGL", gpuInfo.getEglVersion() ?: "Unknown")
}
}
}
@Composable
fun InfoRow(label: String, value: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = value,
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium
)
}
}
8. 检测 GPU 能力
fun checkGpuCapabilities(context: Context) {
val gpuInfo = GpuInfo(context)
val detailedInfo = gpuInfo.getGpuDetailedInfo()
println("=== GPU Capabilities Check ===")
// 检查是否适合游戏
val isGoodForGaming = (detailedInfo.maxFrequency ?: 0) > 600 &&
(detailedInfo.computeUnits ?: 0) >= 4 &&
(detailedInfo.bandwidth ?: 0.0) > 25.0
println("Suitable for Gaming: ${if (isGoodForGaming) "Yes" else "No"}")
// 检查是否支持高端图形
val supportsHighEndGraphics = gpuInfo.isVulkanSupported() &&
(detailedInfo.shadingUnits ?: 0) > 512
println("High-End Graphics Support: ${if (supportsHighEndGraphics) "Yes" else "No"}")
// 检查 AI/ML 能力
val goodForAI = (detailedInfo.computeUnits ?: 0) >= 6 &&
(detailedInfo.bandwidth ?: 0.0) > 40.0
println("Good for AI/ML: ${if (goodForAI) "Yes" else "No"}")
// 推荐图形质量设置
val recommendedQuality = when {
(detailedInfo.maxFrequency ?: 0) > 800 &&
(detailedInfo.computeUnits ?: 0) >= 6 -> "Ultra"
(detailedInfo.maxFrequency ?: 0) > 650 &&
(detailedInfo.computeUnits ?: 0) >= 4 -> "High"
(detailedInfo.maxFrequency ?: 0) > 500 -> "Medium"
else -> "Low"
}
println("Recommended Graphics Quality: $recommendedQuality")
}
9. OpenGL ES 版本检测增强
val gpuInfo = GpuInfo(context)
// 修复后的 getOpenGLVersion() 方法
val glVersion = gpuInfo.getOpenGLVersion()
when {
glVersion == null || glVersion == "Unknown" -> {
println("OpenGL ES: Not available or unknown")
}
glVersion.contains("3.2") -> {
println("OpenGL ES 3.2: Full support for modern graphics")
}
glVersion.contains("3.1") -> {
println("OpenGL ES 3.1: Good support for most features")
}
glVersion.contains("3.0") -> {
println("OpenGL ES 3.0: Basic modern graphics support")
}
glVersion.contains("2.0") -> {
println("OpenGL ES 2.0: Legacy support only")
}
else -> {
println("OpenGL ES: $glVersion")
}
}
注意事项
-
规格数据来源: GPU 规格信息基于公开的硬件数据库,对于未识别的 GPU 型号,规格字段将返回
null -
OpenGL ES 版本修复:
- 修复了可能返回
null的问题 - 如果无法从 EGL 获取,会尝试从 Vulkan 推断
- 最坏情况返回 "Unknown" 而不是
null
- 修复了可能返回
-
精确性:
- 频率和带宽值是理论最大值,实际运行时可能更低
- 不同设备批次可能有轻微差异
-
权限: 获取 GPU 信息不需要特殊权限
-
性能:
- GPU 信息获取是轻量级操作
- 建议在应用启动时获取一次并缓存
-
兼容性:
- 支持 Android 5.0 (API 21) 及以上
- Vulkan 信息需要 Android 7.0 (API 24) 及以上
-
国际化: 所有返回的文本信息已改为英文,中文保留在注释中
已修复的问题
getOpenGLVersion() 返回 null
问题: 在某些设备上,getOpenGLVersion() 可能返回 null
原因: EGL 上下文创建失败或 GL 字符串查询失败
解决方案:
- 添加了回退机制:从 Vulkan 版本推断 OpenGL ES 支持
- 确保总是返回非 null 值(至少返回 "Unknown")
- 增加了错误处理
扩展建议
如果需要添加更多 GPU 型号的支持,可以在 getGpuSpecsByRenderer() 方法中添加新的匹配规则:
"your_gpu_name" in renderer -> GpuDetailedInfo(
maxFrequency = 850, // MHz
architecture = "Architecture Name",
cacheSize = 1024, // KB
bandwidth = 38.4, // GB/s
computeUnits = 5,
shadingUnits = 640
)
性能分级参考
根据获取的 GPU 信息,可以进行性能分级:
- 旗舰级: 频率 > 800 MHz, 带宽 > 45 GB/s, 计算单元 >= 6
- 高端: 频率 > 650 MHz, 带宽 > 35 GB/s, 计算单元 >= 4
- 中端: 频率 > 500 MHz, 带宽 > 20 GB/s, 计算单元 >= 3
- 入门级: 其他