setRendererBackend method
Set the preferred renderer backend.
On Android, this automatically manages the native GPU texture surface when switching between CPU and hardware-accelerated modes.
Implementation
Future<void> setRendererBackend(RendererBackend backend) async {
if (defaultTargetPlatform == TargetPlatform.android) {
if (backend == RendererBackend.cpu) {
// Move engine to CPU mode before releasing the native GPU surface.
// This avoids a transition window where pending GPU work can touch
// an already-released ANativeWindow.
await setRendererMode(backend.index);
await releaseGpuTexture(graceful: true);
return;
}
try {
// For any GPU mode transition, drop the old surface first so no frame
// is rendered against an incompatible surface/backend pair.
await releaseGpuTexture(graceful: true);
if (backend == RendererBackend.vulkan) {
await setRendererMode(RendererBackend.vulkan.index);
await createGpuTexture(backend: 'vulkan');
} else {
// Bootstrap through explicit GLES so AUTO/GPU never inherit a stale
// Vulkan renderer after a mode transition.
await setRendererMode(RendererBackend.gles.index);
await createGpuTexture(backend: 'gles');
if (backend != RendererBackend.gles) {
await setRendererMode(backend.index);
}
}
// Ensure the newly attached GPU surface gets a fresh frame even when
// the grid was previously clean (not dirty).
if (isCreated) {
await refresh();
}
} catch (_) {
// A failed Android GPU transition must not leave the engine claiming a
// GPU backend without a valid native window/texture.
try {
await releaseGpuTexture(graceful: false);
} catch (_) {}
try {
await setRendererMode(RendererBackend.cpu.index);
if (isCreated) {
await refresh();
}
} catch (_) {}
rethrow;
}
return;
}
await setRendererMode(backend.index);
}