Deus-Ex:HR - Les passes de rendus analysées


14 mars 2015

Un post très intéressant décrivant dans le détail les différentes passes de rendu utilisées par le dernier Deux-Ex. Il n'y a rien de compliqué mais l'implémentation, le détail et l'optimisation sont remarquables.

Rendu de formules mathematiques (MAJ)


2 mars 2015

Le paquet texgd n'étant pas aisément installable sur Debian, j'ai préféré chercher autre chose et ai choisi Tex2IM.

Toutes mes formules correspondent à des éléments IMG dont les URLs pointent vers la page tex2png.php à laquelle on passe comme paramètre la formule LaTeX que ce dernier doit générer. Ce script utilise directement Tex2IM et sauvegarde l'image dans un cache :

$Formula = str_replace(Array("\\\\", "'"), Array("\\", ""), rawurldecode($_SERVER["QUERY_STRING"]));
$PicName = md5($Formula).".png";
$CacheDir = "mathcache/";
$TmpPath = $CacheDir."tmp/";
//On ne crée l'image que si elle n'existe pas déjà dans le cache
if (!file_exists($CacheDir.$PicName))       {
    //###Il faut pouvoir passer les couleurs en paramètres : actuellement elles sont en dur dans tex2im...
    $TexGDCommand = "tex2im -o '$CacheDir$PicName' '$Formula'";
    $Ret = exec($TexGDCommand, $Output);
}
//On envoie un tag HTML contenant la référence de l'image générée.
$im = imagecreatefrompng($CacheDir.$PicName);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);

JS : Object.observe


22 décembre 2014

Une nouveauté des dernières versions des navigateurs (liste non établie) :

var Test = {
    name:"Nom", prenom:"prénom"
};
Object.observe(Test, function(changes)      {
    $("#observe").append(changes.type+" "+changes.name+" "+changes.oldValue+"<br/>\n");
});
Ceci va donc remplacer, à terme, mon manager qui observe la même chose mais de manière synchrone lui. Ici on est en asynchrone...

Admin : utilisation de HTTP sous Apache


6 octobre 2013
On veut créer des VirtualHost qui utilisent SSL. Un article très intéressant : http://www.symantec.com/connect/articles/apache-2-ssltls-step-step-part-1 http://www.symantec.com/connect/articles/apache-2-ssltls-step-step-part-2 http://www.symantec.com/connect/articles/apache-2-ssltls-step-step-part-3

iOS/Obj-C : utilisation de GCD


28 septembre 2013

Le but de GCD est de permettre de programmer en "multi-thread" de façon simple et en adéquation avec les capacités de l'appareil qui exécute le code (Un Mac Pro est un poil plus performant qu'un iPhone 3GS...).

J'écris multi-thread entre guillemets parce que GCD utilise le concept de Queue qui est une abstraction d'une thread : parfois c'est une thread, parfois c'en est plusieurs, parfois c'est la thread principale.

Ainsi, pour illustrer de manière concise une utilisation de GCD, imaginons la situation suivante : des petites tuiles d'une grosse image doivent être chargées de manière asynchrone et sans ralentir la thread principale de l'application. On va donc créer une Queue pour le décodage qui se chargera de mettre l'UI à jour avec ce qu'elle a décodée.

self.filesList = [self.archive filesList];
self.fileIdx = 0;
self->Queue_Test1 = dispatch_queue_create("tileLoadingQueue", DISPATCH_QUEUE_CONCURRENT);       //DISPATCH_QUEUE_CONCURRENT / DISPATCH_QUEUE_SERIAL
TestArchive*    Self = self;
double delayInSeconds = 0.02;       //Si on met un délai nul (0.0) la mémoire occupée par les NSData et UIImage (autorelease pour les deux) n'aura jamais l'occasion de se libérer !
//
self->Test1_block = [^{
    NSString*   FileName = [Self.filesList objectAtIndex:Self.fileIdx];
    //On charge et on décode l'image sur la thread auxiliaire
    NSData* ImageDatas = nil;
    if ((ImageDatas = [Self.archive extractFileByName:FileName]) != nil)        {
        UIImage* TargetImage = [UIImage imageWithData:ImageDatas];
        CGImageRef  TargetCGImage = [TargetImage CGImage];
        //On affecte l'image à son layer cible sur la thread UI
        dispatch_sync(dispatch_get_main_queue(), ^()        {
            Self.imageView.layer.contents = (id) TargetCGImage;
        });
        [self fpsStats];
    }
    //On planifie le chargement de l'image suivante (après un certain délai qui permet de libérer la mémoire allouée juste avant)
    Self.fileIdx++;
    if (Self.fileIdx < [Self.filesList count])      {
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
        dispatch_after(popTime, Self->Queue_Test1, Self->Test1_block);
    }
} copy];        //Le block est alloué sur la pile au départ. "copy" est la seule manière de le mettre dans la heap et qu'il ne soit pas désalloué.
//
dispatch_async(self->Queue_Test1, self->Test1_block);

On a donc utilisé beaucoup de fonctions de GCD :

  • dispatch_queue_create : pour créer la queue de décodage.
  • dispatch_async : pour démarrer l'exécution du processus complet de décodage.
  • dispatch_sync : pour affecter de façon SYNCHRONE l'image décodée à sa view dans l'interface utilisateur.
  • dispatch_get_main_queue : permet de cibler la queue principale, qui est celle utilisée par l'UI.
  • dispatch_after : pour continuer l'exécution du processus de décodage. Le délai permet de flusher la mémoire placer dans les pools autorelease.

1 2 3 4 5... 9 10 11 12..... 18 19 20