wpfperformancexamldrawingbrush

DrawingBrush always rendered on CPU (not GPU)?


I'm struggling with some WPF performance issues. The Ants profiler and dotTrace both show that all the time is deep in the WPF internals. I have a number of DrawingBrush objects presently in use. The old WpfPerf.exe shows that my DrawingBrush objects are being rendered on the CPU instead of the GPU. Is there something I can do to change that? Below is an example of one. Why does it render CPU-side?

<DataTemplate DataType="mapViewModel:ObstacleVM" x:Key="ObstacleShapeTemplate">
    <Path Stroke="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeOutlineBrush}" StrokeThickness="{Binding WorldAndScreen.MetersPerPixel, Converter={StaticResource Multiplier}, ConverterParameter=1}" StrokeLineJoin="Bevel" StrokeEndLineCap="Square" StrokeStartLineCap="Flat">
        <Path.Fill>
            <DrawingBrush Stretch="Uniform" ViewportUnits="Absolute" TileMode="Tile">
                <DrawingBrush.Transform>
                    <ScaleTransform ScaleY="{Binding WorldAndScreen.MetersPerPixel, Converter={StaticResource Multiplier}, ConverterParameter=5}" />
                </DrawingBrush.Transform>
                <DrawingBrush.Drawing>
                    <DrawingGroup>
                        <DrawingGroup.Children>
                            <GeometryDrawing Brush="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeFillBrush}">
                                <GeometryDrawing.Geometry>
                                    <GeometryGroup FillRule="Nonzero">
                                        <PathGeometry>
                                            <PathFigure StartPoint="0,0">
                                                <LineSegment Point="1,0" />
                                                <LineSegment Point="1,1" />
                                                <LineSegment Point="0,1" />
                                            </PathFigure>
                                        </PathGeometry>
                                    </GeometryGroup>
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>
                            <GeometryDrawing Brush="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeOutlineBrush}">
                                <GeometryDrawing.Geometry>
                                    <GeometryGroup FillRule="Nonzero">
                                        <PathGeometry>
                                            <PathFigure StartPoint="0,0">
                                                <LineSegment Point="0,.33" />
                                                <LineSegment Point="1,.33" />
                                                <LineSegment Point="1,0" />
                                            </PathFigure>
                                        </PathGeometry>
                                    </GeometryGroup>
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>
                        </DrawingGroup.Children>
                    </DrawingGroup>
                </DrawingBrush.Drawing>
            </DrawingBrush>
        </Path.Fill>
        <Path.Data>
            <PathGeometry FillRule="Nonzero" Figures="{Binding Figures, FallbackValue={StaticResource DefaultFigures}}" />
        </Path.Data>
    </Path>
</DataTemplate>

Solution

  • After reading around further, I found some sources suggesting the use of VisualBrish instead. Indeed, I tried this and it seems to fix it (again, according to WpfPerf.exe).

    <DataTemplate DataType="mapViewModel:ObstacleVM" x:Key="ObstacleShapeTemplate">
        <Path Stroke="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeOutlineBrush}" StrokeThickness="{Binding WorldAndScreen.MetersPerPixel, Converter={StaticResource Multiplier}, ConverterParameter=1}" StrokeLineJoin="Bevel" StrokeEndLineCap="Square" StrokeStartLineCap="Flat">
            <Path.Fill>
                <VisualBrush Stretch="Uniform" ViewportUnits="Absolute" TileMode="Tile">
                    <VisualBrush.Transform>
                        <ScaleTransform ScaleY="{Binding WorldAndScreen.MetersPerPixel, Converter={StaticResource Multiplier}, ConverterParameter=5}" />
                    </VisualBrush.Transform>
                    <VisualBrush.Visual>
                        <Image Stretch="None">
                            <Image.Source>
                                <DrawingImage>
                                    <DrawingImage.Drawing>
                                        <DrawingGroup>
                                            <DrawingGroup.Children>
                                                <GeometryDrawing Brush="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeFillBrush}">
                                                    <GeometryDrawing.Geometry>
                                                        <GeometryGroup FillRule="Nonzero">
                                                            <PathGeometry>
                                                                <PathFigure StartPoint="0,0">
                                                                    <LineSegment Point="1,0" />
                                                                    <LineSegment Point="1,1" />
                                                                    <LineSegment Point="0,1" />
                                                                </PathFigure>
                                                            </PathGeometry>
                                                        </GeometryGroup>
                                                    </GeometryDrawing.Geometry>
                                                </GeometryDrawing>
                                                <GeometryDrawing Brush="{DynamicResource Mobius.UI.Resources.Colors.ObstacleShapeOutlineBrush}">
                                                    <GeometryDrawing.Geometry>
                                                        <GeometryGroup FillRule="Nonzero">
                                                            <PathGeometry>
                                                                <PathFigure StartPoint="0,0">
                                                                    <LineSegment Point="0,.33" />
                                                                    <LineSegment Point="1,.33" />
                                                                    <LineSegment Point="1,0" />
                                                                </PathFigure>
                                                            </PathGeometry>
                                                        </GeometryGroup>
                                                    </GeometryDrawing.Geometry>
                                                </GeometryDrawing>
                                            </DrawingGroup.Children>
                                        </DrawingGroup>
                                    </DrawingImage.Drawing>
                                </DrawingImage>
                            </Image.Source>
                        </Image>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Path.Fill>
            <Path.Data>
                <PathGeometry FillRule="Nonzero" Figures="{Binding Figures, FallbackValue={StaticResource DefaultFigures}}" />
            </Path.Data>
        </Path>
    </DataTemplate>