Graphics in Silverlight for Windows Phone
Microsoft Silverlight will reach end of support after October 2021. Learn more.
This topic describes differences in graphics support between Silverlight and Silverlight for Windows Phone. The main differences include the following:
The graphics threading architecture is different. This topic includes detailed information about the implementation differences and the performance considerations.
In Silverlight for Windows Phone, custom pixel shaders are not supported, so the PixelShader type is not supported.
Both Silverlight and Silverlight for Windows Phone enable the GPU for the evaluation of some properties for cached elements, but the properties that are evaluated are different. In addition to what Silverlight executes on the GPU, Silverlight for Windows Phone also executes perspective transforms on the GPU.
Hit testing events occur with different frequency and the performance is different on Windows Phone.
For additional information on improving performance on Windows Phone along with code examples, see Creating High Performance Silverlight Applications for Windows Phone.
Graphics Threading Architecture
The graphics threading architecture in Silverlight for Windows Phone is optimized for devices. The key differences are as follows:
Silverlight for Windows Phone supports a composition thread in addition to the UI thread. The composition thread offloads some work that the UI thread would normally handle, and thus improves performance.
On Silverlight for Windows Phone, animations that run on the composition thread are automatically cached and handled by the GPU on the device.
Silverlight for Windows Phone employs the composition thread to evaluate property values that can be isolated within the graphics architecture, and which do not require a new rasterization. During animations, property values are calculated every 33 ms, once for every tick, and these calculations can throttle the execution of other code. For this reason, Silverlight for Windows Phone evaluates specific property values on the composition thread, and then automatically passes the new value to the GPU so that it can draw and compose the scene. This process is called auto-caching.
By using the composition thread and the GPU of the device or the emulator, you can significantly improve the performance for some types of graphics processing. You can design and code improvements in your Silverlight applications by doing the following:
Designing applications to take advantage of the composition thread.
Limiting the application's use of the UI thread.
Using caching correctly to take advantage of the GPU.
The composition thread handles simple animations that are associated with specific properties. Simple animations include DoubleAnimation and the Silverlight easing functions supported on double animations that are associated with EasingFunction. The animations that use the composition thread are those that target a double value within the following properties:
For example, TranslateTransform.X is a double value within RenderTransform.
An application will not use the composition thread if an opacity mask or non-rectangular clip is set on the element or its parent. However, you can use opacity mask or non-rectangular clips on child elements with no performance impact.
Silverlight for Windows Phone supports the frame rate counter. On Windows Phone, the frame rate counter includes information about the composition thread. The format of this frame rate counter is as follows:
compositionThreadFrameRate uiThreadFrameRate videoMemoryUsed GPUEnabledSurfaces intermediateSurfaces
The UI thread handles input, user code, control code, layout, and other animations that are not associated with the composition thread. Some examples of user code that runs on the UI thread include all managed code, game loops, per-frame callback functions, and blocking on the network.
Devices running Windows Phone consume a larger percentage of the CPU for input than devices running Windows, and this can affect performance if the UI thread is overloaded. To avoid this performance impact, offload as much work as possible to the composition thread in your application design.
For any graphics animation or transitions, designers and developers should target the experience around the previously mentioned simple properties. This will produce smoother animations and transitions on the Windows Phone.
Avoid per frame callbacks and any programming that is heavily dependent on user code, because this will unevenly throttle the number of frames executed and rendered.
GPU Composition and Caching
Caching enables an application to treat static content in the visual subtree as if it were an image, that is, similar but not equivalent to a WriteableBitmap. Silverlight for Windows Phone uses the GPU for composition of the cached content. If the cached content is mostly static, that is, not frequently updated, you can optimize performance.
For information on GPU emulation on the Windows Phone Emulator, see Optimizing the Windows Phone Emulator.
Both Silverlight and Silverlight for Windows Phone enable the GPU for the evaluation of some properties for cached elements. For information on caching in Silverlight, see Silverlight Hardware Acceleration. Differences between caching on Silverlight and Silverlight on Windows Phone include:
Silverlight for Windows Phone executes perspective transforms on the GPU.
Only Silverlight on Windows Phone can execute rectangular clips on the GPU if the clip is rotated.
Animations running on the composition thread are auto-cached.
You do not need to set EnableGPUAcceleration, which is a plug-in property.
In some scenarios, caching is automatic. In other scenarios, you can manually specify caching to enable GPU access.
Animations associated with the properties specified previously that run on the composition thread use auto-caching, thereby accessing the GPU. You can achieve maximum performance by targeting the double values within the following properties, which include the following:
An application will not use the GPU if an opacity mask or non-rectangular clip is set on the UI element or its parent. You can use opacity mask or non-rectangular clips on child elements.
You can also use caching for these properties even when they are not running on the composition thread. For example, if you are using these properties in an animation that is not a DoubleAnimation, or if you are using these properties with per-frame callback functions, you can still enable caching. However, you must manually specify the use of caching. To enable caching and GPU access for these properties, set CacheMode to BitmapCache in the visual subtree of the application.
Verify the performance impact using EnableFrameRateCounter. Avoid setting BitmapCache arbitrarily, because caching involves a memory cost (the cost of storing the bitmap on the RAM and VRAM) and a processing cost (the cost of copying the bitmap between RAM and VRAM) for every frame.
You can also benefit from caching static content that is dynamically rendered. For example, you can benefit from caching static scenes or subtrees derived from UIElement that are moving around the screen. You can set CacheMode to BitmapCache on the element to enable caching and access to the GPU.
When you cache UI elements, group cached elements together following non-cached elements in the visual tree. This way, non-cached elements can be included in a single intermediate background texture, and this improves performance.