Lester's WPF\SL Blog

Simple, Easy & Beautiful

New WPF Features: Cached Composition

New WPF Features: Cached Composition

Rate This
  • Comments 7

This is part of a series on New WPF Features 

One of the big improvements in 4.0 is the Cached Composition feature in graphics. This feature enables caching a live UIElement as a bitmap, which enables quick rendering of the element as a bitmap. The UIElement is user interactive and hence will respond to keyboard input, mouse clicks,… Also, transforms, effects,.. which operate on top will not cause the cache to regenerated resulting in better performance. Previously, it was common to use RenderTargetBitmap for this purpose. However, this would be at the cost of interactivity.

Lets jump into usage. You have the BitmapCache and the BitmapCacheBrush classes. The former is useful in rendering a complex UIElement while the latter facilitates better reuse of a cached element.

Usage of BitmapCache is shown below. RenderAtScale is helpful for zoom scenarios since it a cache which is multiple of the original bitmap size. Note that changing the UIElement subtree or these properties (EnableClearType\RenderAtScale) will cause the cache to be regenerated.

<Canvas.CacheMode>

    <BitmapCache EnableClearType="False" RenderAtScale="2"/>

</Canvas.CacheMode>

 

<Canvas CacheMode="BitmapCache"/>

 

BitmapCacheBrush is useful when you need to paint the same content on multiple elements. A sample usage is below.

<Grid.Resources>

    <Image x:Key="cachedImage" Source="Xaml.jpg" >

        <Image.CacheMode>

            <BitmapCache EnableClearType="False" RenderAtScale="1" SnapsToDevicePixels="False"  />

        </Image.CacheMode>

    </Image>

    <BitmapCacheBrush x:Key="cachedImageBrush" Target="{StaticResource cachedImage}" />

</Grid.Resources>

<Button Background="{StaticResource cachedImageBrush}" Content="Tile1" Grid.Column="1"/>

<Button Background="{StaticResource cachedImageBrush}" Content="Tile2" Grid.Column="2"/>

...

 

 Got a couple of apps in place to show the usage. The one on the left shows the zoom in action while the second app applies the cacheMode on Viewport2dVisual3D.

 The code is attached. Have fun

 

Share this post

 

Attachment: CacheComposition2.zip
  • I tried the cachemode with the webbrowsercontrol. Unfortunately it is not possible to use the bitmapcachebrush in another control's background.

  • One of the snippets in the post show how the bitmapcachebrush is used as a background for another control (button)

  • I want to cache the browsercontrol and use its content in e.g. canvas by using the bitmapcachebrush. Maybe it doesn't work, since the browser control is a hosted control. I want to do something similar as the htmlbrush in Silverlight.

  • this is discussed on the following link http://social.msdn.microsoft.com/forums/en-US/wpf/thread/9e89a10d-8d39-4f36-945b-f8777a6ef422

  • Hi! Thank you for the article.

    I tried using BitmapCache when moving/resizing Controls with some geometric figures but that gave no boost in performance. I also tried your apps and I can't see any difference either. Checking the "Enable Cache Composition" keeps my CPU constantly busy at about 30%. Setting it off doesn't change anything. Why? I thought, this function gave a considerable performance boost.

  • L0tR, the samples attached should show improved performance. Please send me a mail using the email link and we can discuss this offline.

  • I ran your app several times more and now saw the difference. Excuse me, something must have been wrong with my system...or with my eyes :)

    Could you tell me, if I have such code, where should I insert "CacheMode = "BitmapCache""?

     <Canvas>

           <ContentControl Width="130"

                       MinWidth="50"

                       Height="130"

                       MinHeight="50"

                       Canvas.Top="150"

                       Canvas.Left="470"

                       Template="{StaticResource DesignerItemTemplate}"> //Just some Template

         <Ellipse  Fill="Red"/>

           </ContentControl>

       <ContentControl Width="130"

                       MinWidth="50"

                       Height="130"

                       MinHeight="50"

                       Canvas.Top="150"

                       Canvas.Left="150"

                       Template="{StaticResource DesignerItemTemplate}">

         <Path Fill="Blue"

               Data="M 0,5 5,0 10,5 5,10 Z"

               Stretch="Fill"/>

           </ContentControl>

     </Canvas>

Page 1 of 1 (7 items)