IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

SurfaceView - anti aliasing


Sujet :

Composants graphiques Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Par défaut SurfaceView - anti aliasing
    Bonjour,
    Je me suis amusé a créer une progressBar circulaire en créant une View et en dessinant dans la methode onDraw();
    Pour limiter la surcharge de code pour débuger facilement, je n'ai gardé que le cercle du background.

    Extrait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    paint.setAntiAlias(true);
    paint.setColor(progressBackgroundColor);
    paint.setStrokeWidth(sizeBar);
    paint.setStyle(Paint.Style.STROKE);
    canvas.drawCircle(getWidth() / 2, getHeight() / 2, (getHeight() / 2) - sizeBar, paint);

    Jusque la tout fonctionne à merveille;
    Mais je me disais que si j'utilisais une SurfaceView ce serait un peu mieux pour avoir un bon taux de rafraîchissement.
    J'ai implémenté quasiment le même code adapter à la surfaceView (En me basant sur ce tuto : http://www.mindfiresolutions.com/Usi...droid-1659.php)

    J'ai exactement le même code dans la méthode permettant de dessiner sur le canvas, mais bizarrement mes cercles sont très pixelisé au niveau des "bords" (Gauche / Droite / Haut / Bas ). Voir screen plus bas.

    Est ce qu'il y a quelque choses que je n'aurais pas compris ?
    La surfaceview est elle bien adapté à ce que je souhaite ?
    Il me semblait que les SurfaceView était le top pour dessiner ?
    Avez vous déjà rencontré un problème similaire ?



    Merci.

    ( en haut la View / en bas la SurfaceView )
    Nom : cercles.png
Affichages : 372
Taille : 30,3 Ko
    Je trouve que dans la view c'est déjà limite trop pixelisé.. mais la :/

  2. #2
    Membre émérite
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Par défaut
    Aucune personne qui passe par la n'a jamais utilisé de SurfaceView ?

    J'attend plus des réactions, avis ou piste (dans le meilleurs des cas), plus qu'une réelle réponse à mon problème.

  3. #3
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    SurfaceView n'est probablement pas le meilleur choix dans ton cas.

    La principale différence entre View et SurfaceView c'est que SurfacView peut être modifié par un autre Thread mais une View est accéléré materiellement ce qui n'est pas le cas d'une surface View.

    Concrètement ça veux dire qu'avec une View ton cercle va être dessiné par la carte graphique ce qui est beaucoup plus rapide .

    Un peu de lecture : http://developer.android.com/guide/t...-graphics.html
    http://source.android.com/devices/gr...hitecture.html
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre émérite
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Par défaut
    Merci pour ta réponse !

    Je ne suis pas spécialement doué en anglais, j'ai lu les 2 pages de doc, et je ne comprend vraiment pas pourquoi ca ne fonctionne pas ?
    Il se peut que je comprenne de travers ce qu'il se raconte.

    On a View

    If your application does not require a significant amount of processing or frame-rate speed (perhaps for a chess game, a snake game, or another slowly-animated application), then you should consider creating a custom View component and drawing with a Canvas in View.onDraw(). The most convenient aspect of doing so is that the Android framework will provide you with a pre-defined Canvas to which you will place your drawing calls.
    On a SurfaceView

    The SurfaceView is a special subclass of View that offers a dedicated drawing surface within the View hierarchy. The aim is to offer this drawing surface to an application's secondary thread, so that the application isn't required to wait until the system's View hierarchy is ready to draw. Instead, a secondary thread that has reference to a SurfaceView can draw to its own Canvas at its own pace.
    Ce que je comprend dans ces quelques phrases est tout le contraire de ce que tu me dis.
    La view serait bien lorsqu'il n'y a pas ou peu d'animation, et la surfaceview serait identique à une view mais peut être mise à jour beaucoup plus rapidement.

    Il me semble qu'il dise qu'une View peut être mise à jour par un autre thread avec la méthode postInvalidate().

    Du coup, je ne vois pas bien l’intérêt d'utiliser une SurfaceView qui est plus compliqué à mettre en place pour ne rien gagner avec ? A quoi cela peut il servir ?

    Je n'ai pas retrouvé l'info disant qu'une view était dessiné par la carte graphique contrairement à la surfaceview.


    Edit :
    Je souhaite reproduire une progressbar un peu comme dans fit, plutôt animé du coup, avec plusieurs bar de progression qui se chevauche et s'anime sur une action utilisateur.


    Il y a quelques années j'étais tombé sur le ce tutoriel :
    https://www.migniot.com/AndroidGaming.html

    J'avais à l'époque contacté la personne qui avait écrite le tutoriel avec en gros cette question :

    "Je ne comprend pas vraiment pourquoi on peut obtenir un meilleur fps avec une SurfaceView plutôt qu'une View, sachant qu'elle étend de celle ci ? "
    Voici sa réponse :
    Pour répondre du tac au tac, c'est la méthode la plus lente :
    La méthode onDraw est appelée à chaque fois que la vue a besoin de se redessiner, ce qui inclue
    - pendant sa modification normale, donc le cycle de votre jeu
    - a chaque fois qu'elle est cachée partiellement par une notification, par un clavier ...
    Pour faire bref et de mémoire, la méthode onDraw devrait par défaut avoir les optimisations suivantes :
    - déterminer la portion a redessiner - et ne pas tout redessiner par défaut
    - effectuer le moins de dessin possible
    ....
    En bref : parce que la SurfaceView ne subit pas le multithreading de la View

    Now the long story unshortened :
    Lorsqu'une vue doit etre mise a jour sous android, cette mise a jour est interruptible par un appel téléphonique, par une notification, par une synchronisation de compte, par le démontage logiciel de la carte SD pour se connecter au PC en mode USB Storage etc ...
    Cette mise à jour est donc optimisée pour l'utilisateur et pas pour la vitesse. Toujours en édulcorant elle se compose de multiples "Déverouillage de la memoire video + mise a jour de la petite partie nécessaire + reverouillage de la memoire video".

    Imaginez un flux RSS qui se met à jour :
    Cas 1: Le flux rss est recu rapidement, son titre et tous ses articles sont recus instantanement
    - Le label "Titre" se mettra a jour rapidement
    - Chaque element de la liste de news se mettra a jour rapidement
    Cas 2: Le flux rss est recu presque rapidement, la 1ere moitié en 100ms puis une attente, puis la deuxieme moitie
    - Le label "Titre" se mettra a jour rapidement
    - Les articles de la 1ere moitie de la liste sont ajoutés, ils doivent être affichés/redessinés à l'écran
    - Puis les articles de la deuxième moitié apparaissent
    Cas 3: Le réseau est lent est le flux est chargé à la vitesse de l'escargot rhumatisant
    - Vous aurez le temps de voir se rafraichir/apparaitre chaque article

    Transposez cela a l' "algorithme d'affichage" :
    Une vue est par définition lente
    - A chaque fois qu'elle doit se mettre à jour
    - Elle se demande si c'est bien le bon moment
    - Si oui elle essaie de limiter la zone a mettre à jour
    - Puis enfin elle se met à jour en bloquant le moins possible la memoire video (pour ne pas empecher quelque affichage de plus haute importance d'arriver, par exempl les notifications)
    - On appelle ce blocage un créneau Lock

    Maintenant prenons le cas de la SurfaceView :
    Meme si elle hérite de View, elle ne suit pas le même contrat au sein du noyau Android :
    Entre le moment ou lockCanvas() arrive et jusqu'a ce que unlockCanvas() arrive, personne ne peut toucher à cette partie de l'écran (ni notification, ni appel, ni tout-ce-que-l-os-sai-faire-en-parrallele. Comme le fait FlashPlayer sur les navigateurs, impossible de dessiner par dessus, c'est "avalé" par le flash qui "possède" sa zone 'écran).

    Bref, pas d'interruption pendant que vous utilisez SurfaceView, donc une vitesse de jeu beaucoup plus rapide.
    En espérant vous avoir éclairé .. et parlé en langage compréhensible

  5. #5
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par LeBzul
    Il me semble qu'il dise qu'une View peut être mise à jour par un autre thread avec la méthode postInvalidate().
    C'est le contraire , c'est la surfaceview , voir ta citation :
    The aim is to offer this drawing surface to an application's secondary thread,
    Le principe c'est qu'une View simple s'execute dans le thread UI , donc on doit attendre que toutes les vues aient été dessiné pour qu'un redraw s'effectue.

    Au contraire la surface view peut être executée par un thread différent du thread UI et donc indépendamment du thread UI.

    Citation Envoyé par LeBzul
    Je n'ai pas retrouvé l'info disant qu'une view était dessiné par la carte graphique contrairement à la surfaceview.
    http://source.android.com/devices/gr...re.html#canvas :
    as you can see from the charts on the Hardware Acceleration page, this was a bit of a bumpy ride. Note in particular that while the Canvas provided to a View's onDraw() method may be hardware-accelerated, the Canvas obtained when an app locks a Surface directly with lockCanvas() never is.
    Je suis pas un expert sur le sujet mais concrètement je dirais que :
    Si tu as beaucoup de traitement à faire dans ta vue et/ou des animation lourdes il faut préférer la surfaceview
    Sinon View.
    Il me semble qu'une surfaceview ne peut être transparente.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre émérite
    Avatar de LeBzul
    Homme Profil pro
    Inscrit en
    Décembre 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 381
    Par défaut
    Citation Envoyé par grunk Voir le message
    C'est le contraire , c'est la surfaceview , voir ta citation :
    Le principe c'est qu'une View simple s'execute dans le thread UI , donc on doit attendre que toutes les vues aient été dessiné pour qu'un redraw s'effectue.

    Au contraire la surface view peut être executée par un thread différent du thread UI et donc indépendamment du thread UI.
    Je faisais en faite référence à cette partie de la doc ("A View" http://developer.android.com/intl/zh...-graphics.html ):

    Note: In order to request an invalidate from a thread other than your main Activity's thread, you must call postInvalidate().

    Quoi qu'il en soit, j'ai trouvé la réponse à ma question, il me manquait cette ligne :

    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    Je suppose qu'une autre des différences entre une SurfaceView et une View et qu'il faut supprimer ses anciens dessins du canvas.

    Je suis super content du résultats, j'ai gagné énormément en rapidité d’exécution des animations... C'est le jour et la nuit !

    On peut mettre le background d'une surface en Transparent en faisant une manip pas super propre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SurfaceView sfvTrack = (SurfaceView)findViewById(R.id.sfvTrack);
    sfvTrack.setZOrderOnTop(true);    // necessary
    SurfaceHolder sfhTrackHolder = sfvTrack.getHolder();
    sfhTrackHolder.setFormat(PixelFormat.TRANSPARENT);

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [DirectX9] Anti-aliasing + gestion caméra
    Par SteelBox dans le forum DirectX
    Réponses: 6
    Dernier message: 21/07/2005, 00h56
  2. Anti aliasing qui ne fonctionne pas
    Par Deus Ex Makina dans le forum OpenGL
    Réponses: 3
    Dernier message: 27/04/2005, 09h57
  3. Filtres Anti-aliasing et TBitmap
    Par Sub0 dans le forum Langage
    Réponses: 24
    Dernier message: 15/04/2005, 21h12
  4. filtre anti-aliasing
    Par MO GV dans le forum MFC
    Réponses: 14
    Dernier message: 04/03/2005, 19h21
  5. Anti-aliasing
    Par Cazman dans le forum OpenGL
    Réponses: 16
    Dernier message: 27/04/2004, 08h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo