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

API, COM et SDKs Delphi Discussion :

[GDI] SetRect, performance en fonction du rectangle ?


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Par défaut [GDI] SetRect, performance en fonction du rectangle ?
    Bonjour,

    Dans le cadre d'un hook sur DirectX (proxy dll) je suis amené a utiliser SetRect un grand nombre de fois pour incruster du texte dans un jeu.

    Je suis partie d'un exemple trouvé sur le web mais aujourd"hui je me pose une question quant aux performances...

    Exemple d'affichage d'un texte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        SetRect(rec^, XKpaAVG, YKpaFront, Screen.Width, screen.height);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPAVGStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
    Ce qui me gêne c'est les "Screen.Width, screen.height"...
    Si ça n'a pas d'influence sur les perfs tout va bien, car dans ce cas écrire le code suivant reviendrait à diminuer les perfs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        SetRect(rec^, XKpaAVG, YKpaFront, XKpaAVG+50, YKpaFront+20);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPAVGStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
    Est-ce que quelqu'un sait si l'étendu du rectangle a un impact sur les perfs ?

    Merci

    Alekhine.

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    En regardant le source de GetWidth accesseur de Screen.Width, on voit que cela appele l'API GetSystemMetrics, donc forcément cela prend plus de temps que de faire Const+50, rien que le passage de paramètre par la pile ou registre consomme du temps ... maintenant, le dessin à l'écran c'est tellement plus lent, tu vas gagner 0.000001% de perf ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    En regardant le source de GetWidth accesseur de Screen.Width, on voit que cela appele l'API GetSystemMetrics, donc forcément cela prend plus de temps que de faire Const+50, rien que le passage de paramètre par la pile ou registre consomme du temps ... maintenant, le dessin à l'écran c'est tellement plus lent, tu vas gagner 0.000001% de perf ...

    Bonjour,

    hmmm ok merci.

    Par contre ce ne sont pas des constantes mais des variables (cardinal), donc il y a un calcul, et en fait la vrai question est de savoir si on consomme plus de ressources en définissant un grand rectangle pour n'en utiliser qu'une petite partie ou en définissant un rectangle adéquat pour y afficher ce texte.

    Enfin en tout cas c'est la question que je me pose.

    Je pense que je vais jouer du QueryPerformanceCounter(Start/Stop) en sortant un temps toutes les 1000 frames avec l'une et l'autre méthode de SetRect.

    Je passe plus de temps à vérifier le code qu'à le créer

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Ah, j'avais pas compris où ton problème de perf se situait, évidemment, plus la zone de travail à l'écran est grande, plus cela va prendre du temps ... pour le cas d'un DrawText, normalement cela relcalul le rect nécessaire pour le texte (voir l'API GetTextExtentPoint32) en se basant sur le rect passé en paramètre pour les options de WordWrap ou d'alignement par exemple, ... donc, j'aurais tendance à dire que si Windows n'est pas trop bête, il en fait le moins possible ...

    tu utilise DrawTextA, c'est l'API directement ?
    nil suppose le bureau ?

    par contre pour un FillRect, là, l'impact serait énorme ... et ça se verrait !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ah, j'avais pas compris où ton problème de perf se situait, évidemment, plus la zone de travail à l'écran est grande, plus cela va prendre du temps ... pour le cas d'un DrawText, normalement cela relcalul le rect nécessaire pour le texte (voir l'API GetTextExtentPoint32) en se basant sur le rect passé en paramètre pour les options de WordWrap ou d'alignement par exemple, ... donc, j'aurais tendance à dire que si Windows n'est pas trop bête, il en fait le moins possible ...

    tu utilise DrawTextA, c'est l'API directement ?
    nil suppose le bureau ?

    par contre pour un FillRect, là, l'impact serait énorme ... et ça se verrait !
    Ok donc ça mérite nettement d'être chronométré cette histoire, c'est pas que je veuille couper les cheveux en 4, mais si je sais qu'une façon d'écrire va plus vite il n'y a aucune raison pour que je ne l'exploite pas ^^

    J'utilise DrawTextA() de Direct3D puisque je hook DirectX "Present". Le "nil" c'est pour que Direct3D restitue la chaîne avec son propre objet sprite (source msdn).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    function  PresentCallback(const Self: IDirect3DDevice9; const SourceRect,
      DestRect: PRect; const DestWindowOverride: HWND; DirtyRegion: PRgnData): HResult; stdcall;
    Begin
    ...
    ...
     
        SetRect(rec^, XKpaAVG, YKpaFront, Screen.Width, screen.height);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPAVGStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
        SetRect(rec^, XKpaAVD, YKpaFront, Screen.Width, screen.height);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPAVDStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
        SetRect(rec^, XKpaARG, YKpaRear, Screen.Width, screen.height);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPARGStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
        SetRect(rec^, XKpaARD, YKpaRear, Screen.Width, screen.height);
        TemperatureFont.DrawTextA(nil, PAnsiChar(PPARDStr), -1, rec, DT_LEFT, D3DCOLOR_ARGB(255, 255, 216, 0));
     
    ... etc etc
     
      Result := PresentNext(self, SourceRect, DestRect, DestWindowOverride, DirtyRegion);
     
    END;

    ce qui fini par donner ça dans le jeu ( voir le morceau d'image en bas à gauche)

    Je m'interroge sur l'optimisation puisque je suis en plein dedans, à commencer par arrêter 3 SetRect/DrawTextA pour 3 températures qui se suivent (là c'est gros, mais je n'en suis qu'au début du code, c'est déjà un miracle que ça fonctionne lol), donc comme je réécrit tout au propre je cherche d'autres méthodes à appliquer dans la foulée pour améliorer les perfs.

    Alek.
    Images attachées Images attachées  

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Par défaut
    Bon j'ai fait mes mesures de temps d'exécution, il se trouve qu'un SetRect pour un grand ou un petit rectangle ne change pas grand chose en terme de perf.

    Par contre j'ai gagné en FPS dans le jeu...

    La conclusion dans mon cas de figure c'est qu'il faut se limiter à la zone nécessaire, même en donnant les coordonnées par variables+calculs, il y a un gain net en perf affichage.

    Alek.

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

Discussions similaires

  1. [Batch] Test de performance sur fonction en base de données depuis script windows (.bat)
    Par bernidupont dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 30/11/2014, 22h15
  2. Performances et fonctions custom ?
    Par brolon dans le forum SQL
    Réponses: 15
    Dernier message: 21/12/2010, 22h04
  3. Performance des fonction de chaine
    Par octal dans le forum Qt
    Réponses: 3
    Dernier message: 01/03/2010, 15h20
  4. GDI+ : Fonction Rectangle.Contains()
    Par Bef@ dans le forum C#
    Réponses: 2
    Dernier message: 27/01/2007, 14h23
  5. Réponses: 7
    Dernier message: 21/11/2005, 14h21

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