MIX09 - Silverlight 3 : une version définitivement majeure!

Je vous avais promis de rentrer plus dans le détail sur Silverlight 3, nous allons donc le faire dans ce billet. Accrochez vos ceintures, vous ne devriez pas être déçu! Je vais vous présenter tout cela à travers un résumé d’une session que j’ai suivi animée par Joe Stegman. Celle-ci est d’ailleurs dors et déjà en ligne ici: https://videos.visitmix.com/MIX09/T14F

Support de nouveaux codecs

Le H264 est donc désormais intégré dans la runtime de Silverlight 3.

Joe nous indique un élément intéressant pour choisir entre H264 et VC1 par exemple. A l’heure actuelle, seul VC1 est supporté à travers Windows Media Server. Le streaming dans Silverlight reste donc l’apanage de VC1.

L’accélération matérielle via le GPU

Forcément la nouvelle fonctionnalité la plus tape à l’œil, Silverlight 3 est désormais capable de tirer partie de la puissance des GPU modernes de nos cartes graphiques.

L’activation de l’accélération matérielle se fait à travers le positionnement d’un booléen nommé EnableGPUAcceleration au niveau de la balise asp:Silverlight dans le cas d’un hosting dans une page ASP.NET par exemple. Ce dernier est d’ailleurs non présent par défaut. Pour quelles raisons? Par ce qu’il n’y aura pas toujours forcément un intérêt de solliciter le GPU pour certaines applications. Cela va donc dépendre des scénarios.

L’un des scénarios les plus intéressants où cela fait sens est la mise à l’échelle d’une vidéo (stretching). Imaginez avoir une vidéo en 640x480 par exemple qu’il faut rendre en plein écran sur un portable moderne de 1920x1200 comme le mien. Cette opération peut être très couteuse en CPU (surtout si en plus il faut décompresser le h264). Dans ces cas là, on peut déléguer l’opération de mise à l’échelle au GPU ce qui libère totalement les ressources CPU.

Vous disposez également de la possibilité de bénéficier de l’accélération matérielle sur la composition d’éléments. Un nouveau cache Hardware a été introduit dans le flux de rendu de Silverlight 3 de manière à augmenter les performances globales.

A part cela, voici quelques points supplémentaires à noter sur l’accélération matérielle:

- Elle fonctionne à la fois sur PC et sur MAC. Sur PC, nous avons utilisé DirectX pour la mettre en place et sur MAC, OpenGL
- Elle fonctionne en plein écran et dans le navigateur sur PC et pour l’instant uniquement en plein écran sur MAC.

Perspective 3D

Avec le support du GPU, on a forcément envie de mettre un peu de 3D dans tout cela. Le support de la 3D ne sera forcément pas aussi puissante que celle de WPF mais déjà suffisamment intéressante pour rendre nos applications RIA encore plus attrayantes et y apporter de nouveaux scénarios d’usage.

L’idée du “Perspective 3D” est simplement de mettre des objets 2D dans un espace 3D à travers des projections. L’implémentation dans Silverlight 3 est vraiment ultra simple d’approche. Pas besoin d’être un expert de la 3D pour faire de la 3D. Regardez ce morceau de XAML:

<Button Content="Button">

          <Button.Projection>

            <PlaneProjection RotationY="-40" />

          </Button.Projection>

</Button>

On indique donc simplement que l’on souhaite effectuer une rotation dans l’espace sur l’axe Y de –40. Vous êtes désormais dans un univers 3D donc avec le triplet X, Y, Z à votre disposition.

487px3D_coordinate_system_svg[1]

Voici un exemple de résultat pour manipuler les 3 axes:

 3368127759

A noter que l’on découvre ici une autre nouveauté de Silverlight 3 dans cette image: le binding entre éléments. Ainsi les 3 sliders du haut sont liés aux propriétés RotationX, RotationY et Rotation Z de l’image affichée.

Ces transformations s’appliquent à tous les éléments de manière simple.

Quels sont les scénarios d’usage? Cela peut-être pratique pour attirer l’attention sur une partie de l’interface ou au cas contraire rendre un élément moins visible en le plaçant en arrière plan d’une scène. J’ai également vu une démo où l’on mettait en place le fameux “Cover Flow” d’Apple en quelques minutes.

Toute la documentation à ce sujet ici: https://msdn.microsoft.com/en-us/library/dd470131(VS.96).aspx 

Des animations plus naturelles

Afin de rendre les animations plus naturelles, c’est à dire moins linéaires, un nouveau moteur est présent. Vous pouvez donc désormais avoir des animations de type “élastique” ou “balle rebondissante”.

ElasticEase with graphs of different easingmodes.

Plus d’infos dans la documentation : https://msdn.microsoft.com/en-us/library/cc189019(VS.96).aspx section “Easing Functions”

Pixel Shaders

Par ailleurs, Silverlight 3 peut désormais utiliser des Pixel Shaders (en version 2.0) pour appliquer des traitements sur chacun des pixels de l’image avant qu’ils soient rendus à l’écran. 2 types d’approches:

1 – utiliser les effets tout faits comme les “Drop Shaddows” (effet d’ombre porté) ou Blur (effet de flou)
2 – fabriquer ses propres effets en important un byte code compilé.

Les effets par défaut

Pour faire le flou gaussien, il suffit de spécifier la propriété Effect de l’objet puis de choisir l’effet BlurEffect avec le niveau de Radius à appliquer. Voici un exemple de XAML pour un bouton:

 <Button Content="David Myope" FontSize="24" Width="170" Height="100">    <Button.Effect>        <BlurEffect x:Name="maMyopie" Radius="10"/>    </Button.Effect></Button>

 

Et voici le résultat:

3370090776 

Ensuite on pourrait s'amuser à faire du binding entre élément entre un slider et l'effet de myopie (la valeur du Radius). Pour cela, il suffit d'utiliser ce bout de XAML:

<Slider 
   Value="{Binding ElementName=maMyopie,Path=Radius,Mode=TwoWay}"
   Margin="10"
   Minimum="0"
   Maximum="20"
   MinWidth="250" />

Cela nous donne au final, cette petite application rigolote vous permettant me découvrir en train de lire un écran sans lunette de manière plus ou proche de mon écran :

<UserControl x:Class="BlurButtonSlider.MainPage"
   xmlns=https://schemas.microsoft.com/winfx/2006/xaml/presentation
   xmlns:x=https://schemas.microsoft.com/winfx/2006/xaml
   Width="400" Height="160">
    <Grid 
       x:Name="LayoutRoot"
       Background="White">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid HorizontalAlignment="Center" 
             VerticalAlignment="Center">
            <Grid.Projection>
                <PlaneProjection x:Name="projection" />
            </Grid.Projection>
            <Button Content="David Myope" FontSize="24" Width="170" Height="100">
               <Button.Effect>
                    <BlurEffect x:Name="maMyopie" Radius="10"/>
                </Button.Effect>
            </Button>
        </Grid>
        <StackPanel Grid.Row="1">
            <StackPanel 
               Orientation="Horizontal">
                <TextBlock 
                   Text="Niveau de Myopie"
                   VerticalAlignment="Center" 
                   Margin="5"/>
                <Slider 
   Value="{Binding ElementName=maMyopie,Path=Radius,Mode=TwoWay}"
   Margin="10"
   Minimum="0"
   Maximum="20"
   MinWidth="250" />
            </StackPanel>
        </StackPanel>
    </Grid>

</UserControl>

Slider à 0, j'ai le nez collé à l'écran:

3369304223

Slider à 15, je suis à 40 cm de l'écran (oui je suis très myope je sais):

 3370127890

Les effets personnalisés avec les Shaders

Pour générer le byte code des Pixel Shaders, on peut soit utiliser un outil du SDK de DirectX ou utiliser WPF. Ensuite, il n’y a plus qu’à importer le shader compilé dans le projet Silverlight 3 pour pouvoir l’appliquer à n’importe quel élément. Voici une idée du type de résultat:

3368127719 3368127759

A gauche, nous avons une effet d’inversion vidéo et à droite un effet particulier de vaguelettes sur la même image.

Vous pouvez donc récupérer des Shaders de WPF comme ceux disponibles ici : https://www.codeplex.com/wpffx pour les utiliser désormais dans Silverlight!

A noter: les “custom effects” de Silverlight 3 sont rendus par le CPU et non pas le GPU comme dans WPF.

Toute la documentation sur les Pixel Shaders se trouve ici : https://msdn.microsoft.com/en-us/library/system.windows.media.effects(VS.96).aspx

SaveFileDialog

Jusqu’à présent, on ne pouvait communiquer que dans un sens: de la machine client vers Silverlight en laissant l’utilisateur choisir un fichier à passer au runtime Silverlight. On peut désormais récupérer du contenu depuis la runtime Silverlight pour l’écrire sur le disque à travers l’utilisation de cette nouvelle boîte de dialogue.

3369023654

Attention cependant, la sécurité est toujours bien respectée. On peut en effet juste ouvrir le fichier choisi par l’utilisateur et l’on obtient uniquement un stream en retour. On ne sait jamais où se trouve le fichier (path). On se contente d’écrire dans le stream et c’est tout. Silverlight 3 encapsule le reste pour éviter les problèmes de sécurité liés à l’accès direct aux ressources de la machine hôte.

Du coup, une démo sympa nous était proposée. Lorsque l’on clique sur un bouton “Save”, on peut imaginer flouter l’écran en arrière plan avec l’utilisation d’un Pixel Shader livré en standard (BlurEffect vu plus haut). Cela montre donc bien graphiquement que nous avons changé d’état et qu’il faut travailler sur la fenêtre modale en 1er plan. Celle-ci nous demandant le nom du fichier sur le disque dans lequel on souhaite écrire. Au passage, le fichier généré était un fichier .CSV rouvert ensuite dans Excel.

Bitmap/Pixel APIs et support du RAW Audio/Video

On peut désormais adresser chaque pixel d’une image. En Silverlight 2, on ne pouvait passer que par des types PNG ou JPG sans pouvoir travailler directement sur l’image native. Quel est l’intérêt de cette nouveauté? 2 exemples:

1 – Imaginez que vous souhaitiez effectuer une opération sur une photo pour supprimer les yeux rouges, il vous faut bien travailler sur l’image native plutôt que la version compressée en JPG ou PNG
2 – Des personnes comme notre ami Julien Frelat sont intéressées par ces fonctionnalités pour pouvoir réaliser par exemple des jeux n’utilisant pas les notions vectorielles de Silverlight comme QuakeLight en générant dynamiquement des images.

Même genre d’idées pour le support des flux audio et vidéo en mode RAW (.Wav par exemple). Jusqu’à présent, on était limité à la lecture de fichiers compressés (MP3, WMA). En permettant la lecture de flux natifs, on permettra la génération de sons dynamiques dans Silverlight ou la mise à place de codec personnalisés.

Local Messaging / Local Connection

On peut désormais faire communiquer 2 instances de la runtime Silverlight à travers des messages sérialisés en string. Quel est l’intérêt allez-vous me dire? Cela permet d’avoir plus facilement une page Web composée d’un mélange de HTML et Silverlight 3. En effet, imaginez un carré en haut à gauche de votre page, du HTML au centre et un autre carré en bas à droite de la page. En Silverlight 2, on ne pouvait pas synchroniser l’état des 2 applications. Avec Silverlight 3, vous pouvez désormais faire communiquer 2 applications vivant au sein de la même page ou même… de 2 navigateurs différents!

2 démonstrations amusantes nous ont en effet été faites:

1 – 4 instances de browser étaient lancées avec donc 4 applications Silverlight 3 instanciées. On voyait alors des balles de couleurs différentes passer d’un navigateur à l’autre. Ok, ça ne servait à rien mais ça m’a rappelée la session Coding4fun de Mitsu. :)
2 – Ils ont repris une application de jeu d’échec existante en Silverlight 2. Cette application s’occupait à l’origine de faire combattre le moteur d’exécution JavaScript contre celui de C# de Silverlight à travers une partie d’échec donc. Et bah ils ont ajouté la communication cross-navigateurs avec Silverlight 3 de manière à faire un combat de Browsers ! :) Le but du jeu était d’utiliser le moteur d’exécution JavaScript de FireFox contre celui de Chrome afin de voir lequel des 2 gagnerait.

3370169446

Coté implémentation, la communication se fait à l’aide de named pipes et de shared memory.

Out of Browser

Surement la fonctionnalité qui fait le plus de bruit avec l’accélération 3D. Tout d’abord, cette fonctionnalité est incluse de facto dans Silverlight 3. Cela indique donc que vous pouvez faire tourner votre application en dehors du navigateur sans installer une librairie supplémentaire comme chez Adobe AIR par exemple et sans toucher à la logique de votre code.

Par ailleurs, l’application peut ensuite s’installer soit du PC soit sur MAC et ajoute un raccourci soit sur le bureau, soit dans le menu démarrer soit dans les 2.

Comment installer l’application sur son poste ? Rien de plus simple, bouton droit sur l’application Silverlight 3 et on demande à installer l’application localement. Pour que cette option soit disponible, il faut juste avoir modifié le manifest de l’application Silverlight. Par exemple, voici un tel manifest:

<Deployment xmlns="https://schemas.microsoft.com/client/2007/deployment"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" >
    <Deployment.Parts>
    </Deployment.Parts>

<Deployment.ApplicationIdentity>
        <ApplicationIdentity 
            ShortName="Mon Appli SL3"
            Title="Mon Application SL3 Out of Browser">
            <ApplicationIdentity.Blurb>Ma première application Out of Browser</ApplicationIdentity.Blurb>
        </ApplicationIdentity>
    </Deployment.ApplicationIdentity>
</Deployment>

Une fois en place, on a bien la possibilité d'ajouter en faisant bouton droit sur l'application:

 3370090744

Voici ensuite la fenêtre proposée à l’utilisateur:

3369266495

Et l’application est désormais disponible en dehors du navigateur:

3370090772

On peut également demander une installation de l’application par code via cette ligne :

Application.Current.Detach();

Bien sûr, l’utilisateur est forcément sollicité pour savoir s’il accepte ou non d’installer l’application sur son poste.

Toute la documentation à ce sujet ici: https://msdn.microsoft.com/en-us/library/dd550721(VS.96).aspx

Une fois l’application installée, elle tourne dans un environnement cloisonné identique à celui du navigateur (sandbox).

Vu que nous rentrons dans un scénario de online/offline, un nouveau jeu d’APIs fait son apparition pour aider le développeur à gérer cette situation. Ces APIs nous permettent ainsi de savoir si l’on est connecté ou non. On peut même être notifié du changement d’état en cours de route. Pour savoir si l’on est connecté ou non, voici le booléen à tester:

Application.Current.RunningOffline

Pour terminer, la mise à jour de l’application Silverlight 3 sur le poste client se fait de manière automatique à la prochaine connexion. Vous n’avez rien à faire pour cela, c’est la plateforme qui le gère pour vous!

Voilà, je n’ai pas présenté l’ensemble des nouveautés de Silverlight 3 car croyez moi, elles sont nombreuses (nouveaux contrôles, Deep Linking, Search Engine Optimisation, etc.). Par contre, si vous lisez l’Anglais, je vous conseille fortement de :

1 – Lire ce super post: https://timheuer.com/blog/archive/2009/03/18/silverlight-3-whats-new-a-guide.aspx
2 -Retrouvez toutes ces nouveautés en vidéo ici: https://silverlight.net/learn/videocat.aspx?cat=12#sl3 !

David