DevCheck-lib/GpuInfo增强功能使用示例.md
2025-12-29 11:39:18 +08:00

13 KiB
Raw Blame History

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")
    }
}

注意事项

  1. 规格数据来源: GPU 规格信息基于公开的硬件数据库,对于未识别的 GPU 型号,规格字段将返回 null

  2. OpenGL ES 版本修复:

    • 修复了可能返回 null 的问题
    • 如果无法从 EGL 获取,会尝试从 Vulkan 推断
    • 最坏情况返回 "Unknown" 而不是 null
  3. 精确性:

    • 频率和带宽值是理论最大值,实际运行时可能更低
    • 不同设备批次可能有轻微差异
  4. 权限: 获取 GPU 信息不需要特殊权限

  5. 性能:

    • GPU 信息获取是轻量级操作
    • 建议在应用启动时获取一次并缓存
  6. 兼容性:

    • 支持 Android 5.0 (API 21) 及以上
    • Vulkan 信息需要 Android 7.0 (API 24) 及以上
  7. 国际化: 所有返回的文本信息已改为英文,中文保留在注释中

已修复的问题

getOpenGLVersion() 返回 null

问题: 在某些设备上,getOpenGLVersion() 可能返回 null

原因: EGL 上下文创建失败或 GL 字符串查询失败

解决方案:

  1. 添加了回退机制:从 Vulkan 版本推断 OpenGL ES 支持
  2. 确保总是返回非 null 值(至少返回 "Unknown"
  3. 增加了错误处理

扩展建议

如果需要添加更多 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
  • 入门级: 其他