Feb CTP Only: Optimizing Performance w/ StreamGeometry

If you haven't already heard, the Feb. CTP of WinFX was released this morning.  For me, this release is super-exciting because it includes lots of good work our performance team has been driving.  So if you haven’t got it yet, run over to the MSDN website and grab it now.

One of the brand-new performance features we’ve added in this release is StreamGeometry, courtesy of the great folks over on the 2D Graphics team.  StreamGeometry is all about being able to describe geometry segments (e.g., line’s, bezier’s, etc.) using the least amount of memory possible.  The functionality provided by StreamGeometry is nearly identical to PathGeometry’s/PathFigure’s/*Segment's, except that StreamGeometry’s can’t be modified after they are created. 

By forfeiting your ability to modify the geometry, you get a representation that uses much less memory.  It does this by internally representing each segment using a byte stream.  Conversely, PathGeometry supports a richer (and more expensive) API by representing geometry as an editable tree/graph of Freezable CLR objects.  Not only does this save memory, it can save significant CPU cycles that would be spent instantiating, constructing, and hooking up the PathGeometry. This is particularly true for larger Geometry's.

Here’s a short sample to get you started with StreamGeometry:

---<Xaml File>-----
<Window x:Class="WindowsApplication1.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Title="WindowsApplication1" Height="300" Width="300"
    Loaded="WindowLoaded"
    >
    <Grid>
       <Path x:Name="myPath" Stroke="Black" StrokeThickness="5"/>      
    </Grid>
</Window>
---</Xaml File>-----

---<Code File>-----
private void WindowLoaded(object sender, EventArgs e)
{
    StreamGeometry streamGeometry = new StreamGeometry();

    StreamGeometryContext context = streamGeometry.Open();

    context.BeginFigure(new Point(50, 0), true, true);

    context.LineTo(new Point(50, 0), true, true);
    context.LineTo(new Point(0, 50), true, true);
    context.LineTo(new Point(100, 50), true, true);
    context.LineTo(new Point(0, 100), true, true);
    context.LineTo(new Point(50, 0), true, true);

    context.Close();

    myPath.Data = streamGeometry;
}
---</Code File>-----