setRendererBackend method

Future<void> setRendererBackend(
  1. RendererBackend backend
)

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