diff --git a/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt b/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt index 3d0142d4..0123153c 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/MainActivity.kt @@ -386,8 +386,6 @@ class MainActivity : FlutterActivity() { } private fun shouldDisableImpeller(): Boolean { - // Android TV devices — weaker GPUs, less Impeller testing - if (isAndroidTvDevice()) return true if (DeviceQuirks.isEWaste) return true // NVIDIA Tegra (Shield TV) if (Build.MANUFACTURER.equals("NVIDIA", ignoreCase = true)) return true @@ -397,9 +395,21 @@ class MainActivity : FlutterActivity() { ) { return true } + if (isAndroidTvDevice()) return !tvSupportsImpeller() return false } + // Impeller froze API 30 Fire TV hardware (#749) and Flutter's Vulkan → GLES + // fallback still miscompiles gradients/SVGs, so only TV devices on Android 12+ + // with a Vulkan 1.1 driver leave the Skia path. + private fun tvSupportsImpeller(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return false + // Fire OS reports modern API levels on GPUs whose drivers can't back it up + if (Build.MANUFACTURER.equals("Amazon", ignoreCase = true)) return false + val vulkan11 = 0x401000 // FEATURE_VULKAN_HARDWARE_VERSION encodes 1.1.0 as 0x401000 + return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, vulkan11) + } + override fun getRenderMode(): RenderMode { // Keep Flutter in the normal View hierarchy so video/subtitle SurfaceViews // remain the only native composition layers. This restores the pre-1.35.0 diff --git a/lib/main.dart b/lib/main.dart index 4f1c8753..2c1347a5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -213,7 +213,11 @@ Future _bootstrapApp() async { final commitSuffix = gitCommit.isNotEmpty ? ' (${gitCommit.substring(0, 7)})' : ''; String renderer = ''; if (Platform.isAndroid) { - renderer = ' [${await const MethodChannel('com.plezy/theme').invokeMethod('getRenderer')}]'; + final rendererName = await const MethodChannel('com.plezy/theme').invokeMethod('getRenderer'); + renderer = ' [$rendererName]'; + // Tag crash reports with the active renderer while Impeller rolls back + // out to Android TV, so device-specific regressions are attributable. + unawaited(Sentry.configureScope((scope) => scope.setTag('renderer', rendererName ?? 'unknown'))); } appLogger.i( 'Plezy v${packageInfo.version}+${packageInfo.buildNumber}$commitSuffix$renderer'