Blog

Android in de cloud voor ontwikkelaars en testers: Redroid met GPU-rendering

We draaiden Android 14 in Docker (Redroid) op een Linux-server met een gedeelde Intel UHD 770 en vergeleken GPU- en softwarerendering: 58 fps in plaats van 7 bij een 3D-shader, 60 fps in plaats van 19 in een 3D-game, en minder dan 5% CPU in plaats van 95%.

Android in de cloud voor ontwikkelaars en testers: Redroid met GPU-rendering

Een Android-toestel dat altijd aan staat, bereikbaar met ADB vanaf je laptop of je CI, en dat je in een paar seconden kunt resetten: dat geeft Redroid je op een Linux-server. Redroid (“remote Android”) draait een volledig Android-systeem in een Docker-container, zonder virtuele machine binnen de server. Het is handig om je app te testen op een schone Android, om geautomatiseerde UI-tests te draaien (Appium, uiautomator, Espresso), of om een app die alleen voor Android bestaat 24/7 te laten draaien.

De vraag van dit artikel is eenvoudig: wat verandert de GPU? Redroid kan het scherm tekenen met de GPU van de server (via Mesa) of alleen met de CPU (softwarerendering). We draaiden dezelfde tests op dezelfde server in beide modi.

SuperTuxKart (gratis, van F-Droid) in Redroid, opgenomen met scrcpy op dezelfde server: GPU-rendering bovenaan (59 fps), softwarerendering onderaan (16 fps). 5 seconden.

De resultaten in het kort

  • Eenvoudige apps zijn in beide gevallen vloeiend: scrollen in de Instellingen van Android liep op 60 fps met 1 traag frame op ongeveer 1.045 in beide modi. Maar softwarerendering gebruikte 4 keer meer CPU (17,3% van de server in plaats van 4,2%).
  • Alles in 3D heeft de GPU nodig: een raymarching-shader draaide op 58,4 fps op de GPU tegen 7,2 fps in software, en de game SuperTuxKart op 60 fps tegen 19 fps.
  • De GPU ontlast de CPU: met de GPU gebruikte Android in elke test minder dan 5% van de CPU van de server. In softwaremodus nam 3D-werk 95 tot 98% van de 4 vCPU in beslag, en bleef er niets over voor je tests.
  • Opstarten gaat niet sneller met de GPU: Android was klaar na ongeveer 13 s in GPU-modus en 7 s in softwaremodus.
  • iGPU Start is genoeg voor één Android-instantie; kies iGPU Power om er meerdere tegelijk te draaien of om 3D-apps en games te testen.

Testopstelling

OnderdeelWaarde
ServerDebian 13, Linux 7.3, Intel UHD 770 (gedeelde GPU), 4 vCPU, 10 GB RAM
AndroidRedroid, officiële image redroid/redroid:14.0.0-latest (Android 14, x86_64), Docker 29.9
Scherm1080×1920 op 420 dpi, 60 Hz (games schakelen over naar 1920×1080 liggend)
GPU-renderingredroid_gpu_mode=host: Mesa 24.0.8, “Mesa Intel UHD Graphics 770”, OpenGL ES 3.2
Softwarerenderingredroid_gpu_mode=guest: ANGLE op SwiftShader (CPU), OpenGL ES 3.1
AppsInstellingen van Android, Shader Editor 2.36.3 en SuperTuxKart 1.4 (beide open source, van F-Droid)
Metingenframerate per laag uit SurfaceFlinger (dumpsys SurfaceFlinger --timestats), jank uit dumpsys gfxinfo, CPU van de hele server uit /proc/stat
Weergavescrcpy 5.0.1 (officiële release), adb exec-out screencap voor screenshots

Elke meting duurde 10 tot 20 seconden. CPU-cijfers zijn een aandeel van de hele server (4 vCPU = 100%).

1. Dagelijkse UI: vloeiend in beide modi, maar niet tegen dezelfde kosten

We openden de Instellingen van Android en scrolden 20 keer op en neer met adb shell input swipe, en lazen daarna het eigen framerapport van Android met adb shell dumpsys gfxinfo com.android.settings:

Instellingen, 20 swipesGPUSoftware
Getekende frames1.0451.047
Haperende frames (jank)1 (0,10%)1 (0,10%)
Frametijd, 50e / 90e / 99e percentiel17 / 18 / 18 ms17 / 17 / 18 ms
CPU van de server4,2%17,3%

Voor een normale app met lijsten, knoppen en tekst is de CPU van een moderne server snel genoeg om het scherm zelf te tekenen. Het verschil zit in de prijs: softwarerendering maakte de hele server ongeveer vier keer drukker. Als je tests meerdere instanties draaien of het scherm opnemen, ontbreekt die CPU elders.

2. 3D: daar maakt de GPU het verschil

We gebruikten twee opensource-apps van F-Droid: Shader Editor, die een GLSL-shader schermvullend tekent en de framerate toont, en SuperTuxKart, een 3D-kartracegame. In Shader Editor draaiden we de standaardshader (heel licht) en een raymarching-scène (bollen, zachte schaduwen, mist) die we voor deze test schreven.

Frames per seconde (CPU van de server)GPUSoftware
Shader Editor, standaardshader60,0 fps (4,0%)60,1 fps (64,4%)
Shader Editor, raymarching-shader58,4 fps (1,8%)7,2 fps (98,1%)
SuperTuxKart-tutorial, 1920×108060,0 fps (4,7%)19,2 fps (95,2%)
SuperTuxKart tijdens het rijden, opgenomen door scrcpy59,2 fps16,1 fps
Staafdiagram: frames per seconde in Redroid met GPU-rendering en met softwarerendering, voor een raymarching-shader, SuperTuxKart en een eenvoudige shader
Frames per seconde, GPU (groen) tegen softwarerendering (oranje). Zelfs de lichte shader die in softwaremodus 60 fps haalt, kost 64% van de CPU van de server.
Staafdiagram: CPU-gebruik van de server in Redroid met GPU-rendering en met softwarerendering, voor vier workloads
CPU-gebruik van de hele server (4 vCPU) tijdens dezelfde tests: minder dan 5% met de GPU, tot 98% in softwaremodus.

Met de GPU blijven de 3D-scènes op de 60 fps van het scherm en is de CPU vrijwel onbelast. In softwaremodus zijn de vier vCPU vol en zakt de framerate naar 7 tot 19 fps: een game is niet meer speelbaar, en een UI-test die tegelijk draait zou ook vertragen. Terwijl een game draaide, gebruikte de Redroid-container in beide modi ongeveer 1,4 GB RAM, en Docker telde 10% van één kern met de GPU tegen 381% (bijna vier kernen) in softwaremodus.

De raymarching-shader in Shader Editor op Redroid: 56 fps met de GPU links, 7 fps in softwaremodus rechts
Dezelfde raymarching-shader in Shader Editor, vastgelegd met adb exec-out screencap: GPU links (de app toont 56 fps), software rechts (7 fps). Het beeld is identiek, alleen de snelheid verschilt.

3. Opstarttijd

We maten de tijd van docker run tot Android sys.boot_completed=1 meldde, drie keer per modus, telkens met een lege datamap:

Opstarten tot “klaar”Run 1Run 2Run 3
GPU12,7 s13,3 s12,8 s
Software7,0 s6,5 s7,0 s

De GPU-modus start ongeveer 6 seconden trager, omdat de grafische driver bij het opstarten wordt geladen en ingesteld. Voor een CI-job die bij elke run een nieuwe Android start, reken je op ongeveer 13 seconden voordat adb je app kan installeren.

4. Android bekijken en bedienen vanaf je computer

Redroid heeft geen eigen scherm: je gebruikt het als een telefoon die met een USB-kabel is aangesloten, via ADB.

  • Screenshots: adb exec-out screencap -p > screen.png, de methode die we voor de afbeeldingen hierboven gebruikten.
  • Scherm en bediening: scrcpy (open source, van Genymobile) toont het Android-scherm in een venster en stuurt je klikken en toetsen door. Het werkt via ADB, dus het werkt met Redroid. Op de server gebruikten we het zonder venster om de video’s van dit artikel op te nemen: scrcpy -s 127.0.0.1:5555 --no-window --no-audio --record=run.mp4 --time-limit=7.
  • UI-automatisering: adb shell input (tikken, swipes, tekst) stuurde elke test van dit artikel aan, en adb shell uiautomator dump geeft de view-boom van het scherm terug. Appium (UiAutomator2-driver), Espresso en Maestro maken op dezelfde manier verbinding met een ADB-toestel; die hebben we in deze test niet gebruikt.

Open de ADB-poort nooit naar het internet: de ADB van Redroid heeft geen wachtwoord en geeft volledige controle over het Android-systeem. We publiceren hem alleen op het lokale adres van de server (-p 127.0.0.1:5555:5555) en bereiken hem via een SSH-tunnel:

# op je computer
ssh -N -L 5555:127.0.0.1:5555 you@<server> &
adb connect 127.0.0.1:5555
scrcpy -s 127.0.0.1:5555
SuperTuxKart draait in Redroid met GPU-rendering op 1920×1080, screenshot gemaakt met adb
De tutorial van SuperTuxKart in Redroid met GPU-rendering, op 1920×1080 en 60 fps.

5. Wat je moet weten voordat je begint

  • Dit is x86_64-Android. Apps die in Java of Kotlin zijn geschreven, draaien zoals ze zijn. Apps en games met native code die alleen voor ARM is gebouwd (veel games), hebben een vertaallaag nodig: de Redroid-image meldt ARM-ondersteuning (arm64-v8a) via zo’n laag, maar we hebben apps die alleen voor ARM bestaan niet getest, en die zullen trager zijn en kunnen mislukken.
  • Geen Google Play Store. De officiële image heeft geen Google-diensten. Installeer je eigen APK’s met adb install, of opensource-apps van F-Droid zoals wij deden. Apps die Google Play-services nodig hebben, werken niet zoals ze zijn.
  • Voor testen en automatisering, niet om telefoons na te bootsen. Redroid vertelt apps dat het een virtueel toestel is. Het is bedoeld voor ontwikkeling, testen en het draaien van je eigen tools, niet om veel “telefoons” voor meerdere accounts te draaien, wat de voorwaarden van de meeste apps verbieden.
  • Geen camera, GPS of simkaart. Sensoren ontbreken of worden gesimuleerd; test ze op een echt toestel.

6. Welk abonnement?

Met de GPU gebruikte één Android-instantie minder dan 5% van onze 4 vCPU en ongeveer 1,4 GB RAM, zelfs in een 3D-game. iGPU Start (2 vCPU, 8 GB RAM, € 14,99 per maand excl. btw) is genoeg voor één Android-instantie met je testtools ernaast. iGPU Power (4 vCPU, 14 GB RAM, twee keer het GPU-aandeel van Start, € 29,99 per maand excl. btw) is de betere keuze om meerdere Android-instanties tegelijk te draaien (één per testjob), om 3D-apps en games te testen, of om het scherm op te nemen tijdens tests. iGPU Pro (6 vCPU, 14 GB, Perf 3, € 44,99) voegt meer GPU en CPU toe voor grotere testfarms.

Zonder GPU zou dezelfde server zijn hele CPU aan tekenen moeten besteden zodra een app 3D gebruikt.

7. Zo zet je het op een Linux GPU-server

Liever meteen klaar voor gebruik? Vraag het per e-mail bij je bestelling (contact@linuxgpu.eu): we kunnen de server leveren met Redroid al geïnstalleerd en ingesteld voor GPU-rendering. Jij maakt alleen nog verbinding met ADB via SSH en installeert je app.

Zelf doen op Debian 13:

  1. Laad de binder-driver van Android (onderdeel van de Debian-kernel) en laad hem ook bij het opstarten:

    echo "options binder_linux devices=binder,hwbinder,vndbinder" > /etc/modprobe.d/binder.conf
    echo binder_linux > /etc/modules-load.d/binder.conf
    modprobe binder_linux
  2. Installeer Docker en ADB (apt install docker.io adb), en start daarna Redroid met GPU-rendering:

    docker run -d --name redroid --privileged \
      -v ~/redroid-data:/data -p 127.0.0.1:5555:5555 \
      redroid/redroid:14.0.0-latest \
      androidboot.redroid_gpu_mode=host \
      androidboot.redroid_gpu_node=/dev/dri/renderD128 \
      androidboot.redroid_width=1080 androidboot.redroid_height=1920 \
      androidboot.redroid_dpi=420 androidboot.redroid_fps=60
  3. Controleer of Android de GPU gebruikt: adb connect 127.0.0.1:5555 && adb shell dumpsys SurfaceFlinger | grep GLES moet “Mesa Intel(R) UHD Graphics 770” tonen. “SwiftShader” betekent softwarerendering.

  4. Maak vanaf je computer verbinding via de SSH-tunnel hierboven, installeer je APK met adb install, en start je tests.

Om Android terug te zetten naar een schone staat, verwijder je de container en zijn datamap en start je hem opnieuw.

Voor browsertests op hetzelfde soort server, lees GPU-versnelde Selenium & Playwright: geen GPU van € 500/maand nodig en Chrome met de GPU op een Linux-server (headless, Playwright). Om te begrijpen hoe een container de GPU van een virtuele machine gebruikt, zie GPU-cloud: VM of container, dedicated of gedeelde GPU? Wat prijsvergelijkers niet laten zien.

Probeer het

Bekijk de abonnementen: iGPU Start kost € 14,99 en iGPU Power € 29,99 per maand excl. btw.