Este artigo é uma tradução rápida do original…
Após dois anos e meio desenvolvendo rich ui’s usando QGraphicsView e tentando todo tipo de flags exóticas ou abordagens diferentes para conseguir melhores resultados de performance com Symbian, estou publicando aquelas que podem ser úteis para programadores de jogos.
Com a ajuda do Ademar escolhemos um bom caso de uso. Um “bouncing game”.
O Jogo
O Jogo é bem simples: Algumas bolinhas correndo pela tela; Se você pressionar alguma delas ela vai explodir. Se uma bolinha explodida tocar em uma bola normal, esta explode também. Mas no fim das contas a lógica do jogo não é muito importante agora, mas sim as caracterÃsticas do jogo vistas pela visão de um desenvolvedor. São elas:
- Background estático.
- Bolinhas podem ser implementadas como QGraphicsItem.
- Bolinhas vermelhas estão sempre em movimento.
- Não acontece colisão entre as bolinhas não explodidas.
- A lista de elementos pode crescer.
- Os elementos estão espalhados aleatoriamente pela tela.
As flags
As flags que comentarei neste post são:
Os resultados
* Os testes foram executados em um Nokia 5800, RM-356 rodando firmware V51.0.006 com Qt 4.6.3.
** O eixo Y dos testes é o FPS. Quanto maior, melhor.
Testes com 10 elementos
Primeiro de tudo, tentei as 4 formas de update da Viewport usando 10 elementos na tela. O MinimalViewportUpdate e o SmartViewportUpdate renderam a maior taxa de FPS (34 e 33.5). A documentação da biblioteca mostra que NoIndex é a melhor opção para cenas dinâmicas. Bem, a diferença é bem pequena, mas é verdade.
Neste caso, para os próximos testes, usarei sempre NoIndex.
E quanto às flags?
Dado os melhores resultado dos últimos testes (SmartViewportUpdate and BoundingRectViewportUpdate) foi feito outro teste com as duas flags de optimização QGraphicsView::DontSavePainterState e QGraphicsView::DontAdjustForAntialiasing. A conclusão foi que estas flags de optimização rendem uma pequena melhora no desempenho, mas somente se você puder controlar precisamente a maneira como seus elementos são desenhados. Caso contrário você pode enfrentar problemas de renderização.
20 elementos
30 elementos
40 elementos
Lições aprendidas
É importante selecionar corretamente a maneira como serão feitos dos updates da Viewport. Isso pode fazer a diferença.
Se existem muitos elementos dinâmicos, e se eles estão espalhados por toda a tela, é mais barato pintar toda a tela (ou pelo menos o bounding rect) do que tentar determinar a área afetada pelo movimento e só pintar estes espaços.
Para ser honesto eu estava esperando um resultado melhor do FullViewportUpdate, mas acredito que obterÃamos melhores resultados (do que o BoundingRect) se fosse utilizado um background não estático.
Mas… E se..?
Q:O que aconteceria se fosse utilizado somente um único graphicsItem para pintar todas a bolinhas? O que aconteceria se uma bolinha não fosse um Ãtem, mas apenas um objeto com um método de renderização?
R: Fiquei um pouco surpreso com o resultado, mas o desempenho do Qt (especialmente os states do QPainter) melhorou muito desde a versão 4.6 e o resultado deste teste obteve resultados piores do que usando vários QGraphicsItems. Esta abordagem obtém melhor rendimento que a abordagem padrão apenas se o número de elementos é maior que 60.
Depois de escrever os testes, o que acontece com o código?
Usando os conhecimentos adquirido pelos testes e com a ajuda de uma das designers do INdT – Nara – estou liberando uma versão de um jogo baseado na engine dos testes. Não está totalmente concluÃdo, faltam alguns elementos, mas já está jogável. =)
Por enquanto segue apenas o demo, e em breve a versão completa na Ovi Store mais perto de você!