Chemins de dessin et accélération matérielle

Je crée un chemin assez important à mon avis et je me heurte à des problèmes de performance. Le chemin d'accès atteint actuellement 32 000 points de long, mais mon application devrait atteindre au moins 128 000 points. Je ne peux vraiment rien faire sur la taille du chemin, car les ensembles de données sont si grands et je dois pouvoir afficher tout le chemin à la fois et permettre le zoom.

J'utilise un Nexus 10 exécutant Android 4.2, qui possède une accélération matérielle activée par défaut pour les applications qui ne le désactivent pas explicitement.

  • Android: échec de l'exécution pour la tâche ': application: processDebugResources'
  • Comment envoyer un cookie avec HttpGet en Java
  • Est-il sécurisé de faire partie d'un bitmap Android sur lui-même avec un chevauchement?
  • Envoi et analyse des objets JSON
  • Bouton avec mise en page XML personnalisée
  • Android: Skip Gradle "testClasses" tâche pour un projet de dépendance
  • Le chemin d'accès est créé avec le code suivant (j'ai omis certaines configurations et autres éléments non pertinents):

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

    Ensuite, dessiné dans la méthode onDraw() :

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

    J'ai mesuré le temps nécessaire pour dessiner mon affichage en utilisant adb shell dumpsys gfxinfo avec et sans accélération matérielle, et à mon avis, l'accélération matérielle est beaucoup plus lente:

    Avec accélération matérielle:

    Entrez la description de l'image ici

    Sans accélération matérielle:

    Entrez la description de l'image ici

    La version accélérée du matériel prend environ 200 à 300 ms par image, la plus utilisée dans le processus. La version non accélérée prend environ 50 ms, avec 2/3 dans le stade Draw et 1/3 dans l'étape process.

    De toute évidence, même ma version plus rapide sans accélération matérielle est encore trop lente pour atteindre 60 images par seconde, ou même à peine utilisable lorsque je passe à des jeux de données plus importants.

    L'idée de rendre le chemin d'accès à un bitmap, puis de transformer le bitmap uniquement pour l'écran est également problématique dans mon cas. Je dois soutenir le zoom sur très loin sur le chemin, et pour permettre de zoomer sans que la qualité du chemin soit beaucoup plus grave, je devrais générer des bitmaps surdimensionnés du chemin d'accès (et j'aurais probablement des limites de mémoire et des limites de taille de texture). Et lorsque je me rapproche beaucoup, je devrais soit créer des images plus récentes de seulement certaines parties du chemin, soit passer à la façon de rendre directement le chemin, ce qui pourrait entraîner des retards supérieurs à ceux des résultats si la performance est similaire à ce que j'ai droit à présent.

    Ce que je me demande maintenant, c'est

    • Est-ce que le dessin des lignes / des chemins est quelque chose que le GPU est mauvais et qu'il ne faut pas essayer d'accélérer le matériel, ou est-ce que je risque de faire quelque chose de mal qui cause de mauvaises performances?
    • Y a-t-il quelque chose que je puisse faire pour dessiner des chemins énormes avec des performances acceptables?

  • L'échec de la liaison de communication Le dernier paquet envoyé au serveur était il ya 1 ms.
  • Comment ajouter des informations de profil dans le tiroir de navigation Android?
  • Transition des éléments partagés dans une vue dans un RecyclerView, possible?
  • Comment puis-je modifier le titre et l'icône de la barre d'action Android
  • Comment allumer le haut-parleur pour l'appel entrant par programme dans Android L?
  • Android: erreur de connexion Google Play Games Services (java.lang.IllegalStateException: GoogleApiClient doit être connecté.)
  • 3 Solutions collect form web for “Chemins de dessin et accélération matérielle”

    Est-ce que le dessin des lignes / des chemins est quelque chose que le GPU est mauvais et qu'il ne faut pas essayer d'accélérer le matériel, ou est-ce que je risque de faire quelque chose de mal qui cause de mauvaises performances?

    Les chemins sont toujours rendus à l'aide de la CPU. Lorsque l'application est accélérée par le matériel, cela signifie que le processeur dessine d'abord votre chemin à l'aide de la CPU dans un bitmap, puis téléchargez ce bitmap comme une texture pour le GPU et finalement dessinez la texture à l'écran.

    Les lignes sont entièrement accélérées par le matériel. Au lieu d'utiliser un Path je vous recommande d'utiliser Canvas.drawLines() dans ce cas.

    Y a-t-il quelque chose que je puisse faire pour dessiner des chemins énormes avec des performances acceptables?

    Vous devez utiliser Canvas.drawLines() ou rendre le chemin vous-même dans un Bitmap que vous gérez.

    Il semble que vous pourriez rencontrer un goulet d'étranglement général dans le GPU. Jetez un oeil sur les liens suivants:

    Comment rendre plus efficace l'itinéraire

    Traçage en toile Android en temps réel

    Passer de la toile à OpenGL

    Surtout le premier, ce qui vous suggère de créer un bitmap et de l'attirer à la place. Il semble que vous puissiez obtenir de meilleures performances si vous changez à OpenGL. Il pourrait y avoir une façon magique d'obtenir la méthode actuelle pour fonctionner, mais je ne suis pas au courant de cela en ce moment.

    Pourquoi vous voyez le comportement que vous faites est probablement parce que vous envoyez toutes les données au GPU entre chaque tirage. Vous devez le mettre en cache sur le GPU et utiliser la traduction à la place. Ne pas recréer les données et l'envoyer tout au GPU. Vous êtes probablement lié à l'E / O , ce qui signifie que le taux de transmission entre la CPU et le GPU est ce qui limite votre performance. Je ne peux pas être tout à fait sûr de cela en fonction des données que vous avez fournies, mais c'est la meilleure idée. Essayez différentes techniques de mise en cache, principalement le png-cache du lien n ° 1.

    Dessiner un chemin impliquera plus que de «dire» le GPU pour dessiner des lignes. Un chemin possède de nombreuses caractéristiques, par exemple, comment les extrémités des lignes sont traitées ou qu'une ligne est en pointillé, ce qui n'est pas accéléré par le GPU. Il y a probablement un autre hickup lorsque vous rencontrez de nombreuses lignes qui rendent la combinaison de l'accélération CPU et GPU plus lente. La solution proposée ci-dessus pour passer à canvas.drawLines au lieu de canvs.drawPath et essayer d'utiliser une méthode de Paint fantaisie pourrait aider.

    Si cela ne vous aide pas, essayez d'utiliser GLSurfaceView et créez directement des lignes dans cette zone. Cela impliquera certaines connaissances OpenGL ES, mais ne devrait pas être incroyablement difficile à faire et pourrait être beaucoup plus efficace.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.