Partilhar via


New WPF Features: Cached Composition

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

 

CacheComposition2.zip

Comments

  • Anonymous
    November 20, 2009
    I tried the cachemode with the webbrowsercontrol. Unfortunately it is not possible to use the bitmapcachebrush in another control's background.

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

  • Anonymous
    November 22, 2009
    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.

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

  • Anonymous
    December 27, 2009
    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.

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

  • Anonymous
    December 28, 2009
    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>