Blog

Android na nuvem para programadores e testers: Redroid com renderização por GPU

Corremos o Android 14 em Docker (Redroid) num servidor Linux com uma Intel UHD 770 partilhada e comparámos a renderização por GPU e por software: 58 fps em vez de 7 num shader 3D, 60 fps em vez de 19 num jogo 3D, e menos de 5% de CPU em vez de 95%.

Android na nuvem para programadores e testers: Redroid com renderização por GPU

Um dispositivo Android sempre ligado, acessível por ADB a partir do seu portátil ou da sua CI, e que pode repor em segundos: é isso que o Redroid lhe dá num servidor Linux. O Redroid («remote Android») corre um sistema Android completo num contentor Docker, sem máquina virtual dentro do servidor. É útil para testar a sua app num Android limpo, para correr testes de interface automatizados (Appium, uiautomator, Espresso) ou para manter uma app exclusiva de Android a funcionar 24/7.

A pergunta deste artigo é simples: o que muda a GPU? O Redroid pode desenhar o ecrã com a GPU do servidor (através do Mesa) ou apenas com o CPU (renderização por software). Corremos os mesmos testes no mesmo servidor nos dois modos.

SuperTuxKart (gratuito, do F-Droid) no Redroid, gravado com o scrcpy no mesmo servidor: renderização por GPU em cima (59 fps), renderização por software em baixo (16 fps). 5 segundos.

Resultados em resumo

  • As apps simples são fluidas nos dois modos: o deslocamento nas Definições do Android correu a 60 fps com 1 imagem lenta em cerca de 1.045 nos dois modos. Mas a renderização por software usou 4 vezes mais CPU (17,3% do servidor em vez de 4,2%).
  • Tudo o que é 3D precisa da GPU: um shader de raymarching correu a 58,4 fps na GPU contra 7,2 fps em software, e o jogo SuperTuxKart a 60 fps contra 19 fps.
  • A GPU liberta o CPU: com a GPU, o Android usou menos de 5% do CPU do servidor em todos os testes. Em modo software, o trabalho 3D ocupou 95 a 98% das 4 vCPU, sem deixar nada para os seus testes.
  • O arranque não é mais rápido com a GPU: o Android ficou pronto em cerca de 13 s em modo GPU e 7 s em modo software.
  • O iGPU Start chega para uma instância de Android; escolha o iGPU Power para correr várias em paralelo ou para testar apps e jogos 3D.

Configuração do teste

ElementoValor
ServidorDebian 13, Linux 7.3, Intel UHD 770 (GPU partilhada), 4 vCPU, 10 GB de RAM
AndroidRedroid, imagem oficial redroid/redroid:14.0.0-latest (Android 14, x86_64), Docker 29.9
Ecrã1080×1920 a 420 dpi, 60 Hz (os jogos passam para 1920×1080 na horizontal)
Renderização por GPUredroid_gpu_mode=host: Mesa 24.0.8, «Mesa Intel UHD Graphics 770», OpenGL ES 3.2
Renderização por softwareredroid_gpu_mode=guest: ANGLE sobre SwiftShader (CPU), OpenGL ES 3.1
AppsDefinições do Android, Shader Editor 2.36.3 e SuperTuxKart 1.4 (ambos de código aberto, do F-Droid)
Mediçõestaxa de imagens por camada segundo o SurfaceFlinger (dumpsys SurfaceFlinger --timestats), jank segundo o dumpsys gfxinfo, CPU de todo o servidor segundo /proc/stat
Visualizaçãoscrcpy 5.0.1 (release oficial), adb exec-out screencap para as capturas de ecrã

Cada medição durou 10 a 20 segundos. Os valores de CPU são uma parte de todo o servidor (4 vCPU = 100%).

1. Interface do dia a dia: fluida nos dois modos, mas não ao mesmo custo

Abrimos as Definições do Android e deslizámos para cima e para baixo 20 vezes com adb shell input swipe, e depois lemos o próprio relatório de imagens do Android com adb shell dumpsys gfxinfo com.android.settings:

Definições, 20 deslizesGPUSoftware
Imagens desenhadas1.0451.047
Imagens com jank1 (0,10%)1 (0,10%)
Tempo por imagem, percentil 50 / 90 / 9917 / 18 / 18 ms17 / 17 / 18 ms
CPU do servidor4,2%17,3%

Para uma app normal com listas, botões e texto, o CPU de um servidor moderno é rápido o suficiente para desenhar o ecrã sozinho. A diferença está no preço: a renderização por software deixou todo o servidor cerca de quatro vezes mais ocupado. Quando os seus testes correm várias instâncias ou gravam o ecrã, esse CPU faz falta noutro sítio.

2. 3D: onde a GPU faz a diferença

Usámos duas apps de código aberto do F-Droid: o Shader Editor, que desenha um shader GLSL em ecrã inteiro e mostra a sua taxa de imagens, e o SuperTuxKart, um jogo 3D de corridas de karts. No Shader Editor corremos o shader por omissão (muito leve) e uma cena de raymarching (esferas, sombras suaves, nevoeiro) que escrevemos para este teste.

Imagens por segundo (CPU do servidor)GPUSoftware
Shader Editor, shader por omissão60,0 fps (4,0%)60,1 fps (64,4%)
Shader Editor, shader de raymarching58,4 fps (1,8%)7,2 fps (98,1%)
Tutorial do SuperTuxKart, 1920×108060,0 fps (4,7%)19,2 fps (95,2%)
SuperTuxKart em corrida, gravado pelo scrcpy59,2 fps16,1 fps
Gráfico de barras: imagens por segundo no Redroid com renderização por GPU e por software, para um shader de raymarching, o SuperTuxKart e um shader simples
Imagens por segundo, GPU (verde) contra renderização por software (laranja). Mesmo o shader leve que chega aos 60 fps em modo software custa 64% do CPU do servidor.
Gráfico de barras: utilização de CPU do servidor no Redroid com renderização por GPU e por software, para quatro cargas de trabalho
Utilização de CPU de todo o servidor (4 vCPU) durante os mesmos testes: menos de 5% com a GPU, até 98% em modo software.

Com a GPU, as cenas 3D mantêm-se nos 60 fps do ecrã e o CPU fica quase parado. Em modo software as quatro vCPU ficam cheias e a taxa de imagens cai para 7 a 19 fps: um jogo deixa de ser jogável, e um teste de interface a correr ao mesmo tempo também ficaria mais lento. Enquanto um jogo corria, o contentor do Redroid usava cerca de 1,4 GB de RAM nos dois modos, e o Docker contava 10% de um núcleo com a GPU contra 381% (quase quatro núcleos) em modo software.

O shader de raymarching no Shader Editor sobre o Redroid: 56 fps com a GPU à esquerda, 7 fps em modo software à direita
O mesmo shader de raymarching no Shader Editor, capturado com adb exec-out screencap: GPU à esquerda (a app mostra 56 fps), software à direita (7 fps). A imagem é idêntica, só muda a velocidade.

3. Tempo de arranque

Cronometrámos desde o docker run até o Android indicar sys.boot_completed=1, três vezes por modo, com uma pasta de dados vazia de cada vez:

Arranque até «pronto»Execução 1Execução 2Execução 3
GPU12,7 s13,3 s12,8 s
Software7,0 s6,5 s7,0 s

O modo GPU arranca cerca de 6 segundos mais devagar, porque o driver gráfico é carregado e configurado no arranque. Para um job de CI que inicia um Android novo em cada execução, conte com cerca de 13 segundos antes de o adb poder instalar a sua app.

4. Ver e controlar o Android a partir do seu computador

O Redroid não tem ecrã próprio: usa-o como um telemóvel ligado por cabo USB, através do ADB.

  • Capturas de ecrã: adb exec-out screencap -p > screen.png, o método que usámos para as imagens acima.
  • Ecrã em direto, rato e teclado: o scrcpy (código aberto, da Genymobile) mostra o ecrã do Android numa janela e envia os seus cliques e teclas. Funciona através do ADB, por isso funciona com o Redroid. No servidor usámo-lo sem janela para gravar os vídeos deste artigo: scrcpy -s 127.0.0.1:5555 --no-window --no-audio --record=run.mp4 --time-limit=7.
  • Automatização da interface: o adb shell input (toques, deslizes, texto) controlou todos os testes deste artigo, e o adb shell uiautomator dump devolve a árvore de vistas do ecrã. O Appium (driver UiAutomator2), o Espresso e o Maestro ligam-se a um dispositivo ADB da mesma forma; não os corremos neste teste.

Nunca abra a porta ADB à Internet: o ADB do Redroid não tem palavra-passe e dá controlo total do sistema Android. Publicamo-lo apenas no endereço local do servidor (-p 127.0.0.1:5555:5555) e acedemos a ele através de um túnel SSH:

# no seu computador
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 a correr no Redroid com renderização por GPU em 1920×1080, captura de ecrã feita com o adb
O tutorial do SuperTuxKart no Redroid com renderização por GPU, em 1920×1080 e 60 fps.

5. O que saber antes de começar

  • É Android x86_64. As apps escritas em Java ou Kotlin correm tal como estão. As apps e jogos com código nativo compilado apenas para ARM (muitos jogos) precisam de uma camada de tradução: a imagem do Redroid anuncia suporte ARM (arm64-v8a) através de uma camada deste tipo, mas não testámos apps apenas para ARM, e estas serão mais lentas e podem falhar.
  • Sem Google Play Store. A imagem oficial não tem serviços Google. Instale os seus próprios APK com adb install, ou apps de código aberto do F-Droid, como fizemos. As apps que precisam dos serviços Google Play não funcionarão tal como estão.
  • Para testes e automatização, não para simular telemóveis. O Redroid indica às apps que é um dispositivo virtual. Destina-se a desenvolvimento, testes e a correr as suas próprias ferramentas, não a correr muitos «telemóveis» para várias contas, o que os termos da maioria das apps proíbem.
  • Sem câmara, GPS nem SIM. Os sensores estão ausentes ou são simulados; teste-os num dispositivo real.

6. Que plano escolher?

Com a GPU, uma instância de Android usou menos de 5% das nossas 4 vCPU e cerca de 1,4 GB de RAM, mesmo num jogo 3D. O iGPU Start (2 vCPU, 8 GB de RAM, 14,99 € s/ IVA por mês) chega para uma instância de Android com as suas ferramentas de teste ao lado. O iGPU Power (4 vCPU, 14 GB de RAM, o dobro da quota de GPU do Start, 29,99 € s/ IVA por mês) é a melhor escolha para correr várias instâncias de Android em paralelo (uma por job de teste), para testar apps e jogos 3D, ou para gravar o ecrã durante os testes. O iGPU Pro (6 vCPU, 14 GB, Perf 3, 44,99 €) acrescenta mais GPU e CPU para farms de teste maiores.

Sem GPU, o mesmo servidor teria de dedicar todo o seu CPU a desenhar assim que uma app usa 3D.

7. Configurar num servidor Linux GPU

Quer o servidor pronto a usar? Peça-o por e-mail ao encomendar (contact@linuxgpu.eu): podemos entregar-lhe o servidor com o Redroid já instalado e configurado para renderização por GPU. Só tem de se ligar com o ADB através de SSH e instalar a sua app.

Para fazer por si no Debian 13:

  1. Carregue o driver binder do Android (incluído no kernel do Debian) e mantenha-o no arranque:

    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. Instale o Docker e o ADB (apt install docker.io adb) e depois inicie o Redroid com renderização por GPU:

    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. Verifique que o Android usa a GPU: adb connect 127.0.0.1:5555 && adb shell dumpsys SurfaceFlinger | grep GLES deve mostrar «Mesa Intel(R) UHD Graphics 770». «SwiftShader» significa renderização por software.

  4. Ligue-se a partir do seu computador através do túnel SSH acima, instale o seu APK com adb install e inicie os seus testes.

Para repor o Android num estado limpo, remova o contentor e a sua pasta de dados e inicie-o de novo.

Para testes de browser no mesmo tipo de servidor, leia Selenium e Playwright com aceleração GPU: não precisa de uma GPU de 500 €/mês e Chrome com GPU num servidor Linux (headless, Playwright). Para perceber como um contentor usa a GPU de uma máquina virtual, veja Cloud GPU: VM ou contentor, GPU dedicada ou partilhada?.

Experimentar

Ver os planos: o iGPU Start custa 14,99 € e o iGPU Power 29,99 € s/ IVA por mês.