Dessinant des chemins d'accès et l'accélération matérielle

Je dessine un assez grand chemin, à mon avis, et je suis en cours d'exécution dans certains problèmes de performances. Le chemin est actuellement de 32 000 points de longtemps, mais mon application doit échelle d'au moins de 128 000 points. Je ne peux pas vraiment faire quelque chose au sujet de la taille de la trajectoire, comme les ensembles de données sont ce qu'ils sont grands et j'ai besoin d'être en mesure d'afficher le chemin d'accès complet à la fois et permettent de zoomer.

Je suis sur un Nexus 10 sous Android 4.2, qui a l'accélération matérielle activée par défaut pour les applications qui ne sont pas explicitement le désactiver.

Le chemin est créé avec le code suivant (j'ai omis certains d'installation et d'autres parties non pertinentes):

dataPath.moveTo(0, offset - (float) data[leftLimit]/ scalingFactor);
        for (int i = leftLimit; i < rightLimit; ++i) {
            x = (i - leftLimit) * dx;
            y = offset - (float) data[i]/ scalingFactor;
            dataPath.lineTo(x, y);
        }

Et ensuite tirer dans le onDraw() méthode:

canvas.drawColor(Color.WHITE);
canvas.drawPath(dataPath, linePaint);

J'ai mesuré le temps qu'il faut pour attirer mon point de vue à l'aide de adb shell dumpsys gfxinfo avec et sans accélération matérielle, et à ma grande surprise, l'accélération matérielle est beaucoup plus lente:

Avec l'accélération matérielle:

Dessinant des chemins d'accès et l'accélération matérielle

Sans l'accélération matérielle:

Dessinant des chemins d'accès et l'accélération matérielle

L'accélération matérielle version prend environ 200-300 ms par image, pour la plupart passé dans l'étape de Processus. Le non-accéléré version dure environ 50 ms, avec 2/3 dans le Tirage au sort de scène et 1/3 dans l'étape de processus.

Évidemment, même ma version plus rapide sans l'accélération matérielle est encore trop lente pour atteindre les 60 fps, ou même d'être à peine utilisable quand je bouge de plus grands ensembles de données.

L'idée de rendre le chemin d'accès à une image et ensuite seulement de les transformer en une image bitmap à l'écran est également problématique dans mon cas. J'ai besoin de soutien zoom très loin sur le chemin, et pour activer le zoom avant sans le chemin d'accès de la qualité de l'obtention de beaucoup plus mauvais que j'aurais à rendre surdimensionné bitmaps du chemin (et serait susceptible d'exécuter dans les limites de la mémoire et de la taille de la texture des limites). Et lorsque le zoom au loin, j'aurais pour créer de la plus récente des images d'une partie seulement du chemin d'accès, ou de passer à juste rendu le chemin d'accès directement, ce qui risquait d'entraîner des retards de plus que le framerate si la performance est encore semblable à ce que j'ai droit maintenant.

Ce que je me pose maintenant est

  • Est le dessin des lignes de chemins de quelque chose de juste le GPU est mauvaise et que l'on ne devrait pas essayer de matériel d'accélérer, ou suis-je susceptible de faire quelque chose de mal qui provoque la mauvaise performance?
  • Est-ce que je peux faire pour attirer de tels chemins avec des performances acceptables?
  • Comment OpenGL s'inscrivent dans ce exactement?
  • L'accélération matérielle utilise OpenGL, autant que je le comprends. Mais je n'étais pas sûr de la balise à utiliser, il.
  • Comment êtes-vous ce dessin? Si vous parcelle de 1 point à la fois pour le GPU, alors vous obtiendrez probablement un moins bon rendement, mais si vous le lot de tout à ceux que vous devriez voir une augmentation, au moins en théorie.
  • J'ai ajouté le code qui dessine le chemin, je suis de la création du chemin d'accès complet et le tracer d'un seul coup.
  • Si vous êtes un zoom, il n'y a vraiment aucun point dans le dessin 128k points? Très probablement, ils seront impossibles à distinguer. Je recommande si vous effectuez un zoom avant, vous pouvez sauter ou moyenne certains de ces points.
  • J'y ai pensé, mais c'est assez compliqué. Je ne peux pas juste dans la moyenne des points, que pouvait cacher le montant de bruit dans les données, ce qui conduirait à un mauvais affichage des données. Je vais probablement avoir à aller dans cette direction à la fin, j'espérais que le pouvoir de l'actuel Gpu serait assez et j'ai pu mettre en œuvre une solution simple.
  • hehe bon essayer, c'est de savoir comment vous faites les mauvais code 🙂
  • Il peut être utile de vérifier Douglas-Pecker algorithme: en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
  • En plus de la R*-arbres (ou quelque chose de similaire) peut efficacement répondre à la question: "Quels sont les Points à l'intérieur de ce rect"
  • dans ce cas, ce type de cartes peut vous aider: en.wikipedia.org/wiki/Candlestick_chart. Cela peut ne pas être applicables dans votre cas, mais peut-être que vous avez l'idée et est venu avec quelque chose d'autre.