Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.


Go Back   Vista Forums > Misc Newsgroups > Avalon

RB

Vista - DrawingContext.Close() is very slow for many Geometries drawn

 
 
05-11-2006   #1
Nothi


 
 

DrawingContext.Close() is very slow for many Geometries drawn

Hi all!

I'm trying to build a viewing - engine for Vector Graphics using WPF. As far
as I understand, one should use the "Visual" - Layer to Draw primitives. So
I'm doing the following:

DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();

dc.PushTransform(new TranslateTransform(mOffsetX, mOffsetY));
dc.PushTransform(new ScaleTransform(mScale, mScale, 200, 200));

// now here i insert a LOT of PathGeometries (more than 10.000) by doing:
PathGeometry pg = new PathGeometry();
// fill Path - Geometry..... (with PathFigure)
dc.DrawGeometry(b, p, pg);

To finish the drawing - process, I need to write:
dc.Close();

My Problem is that "dc.Close();" takes about 90% of the overall time (about
10 seconds for 10.000 Geometries).
What am i doing wrong? Any Ideas?
Is there any other (faster way) to "fill" the WPF DRawing engine?

Thanx,
Nothi



My System SpecsSystem Spec
05-15-2006   #2
Adam Smith [MS]


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

A few things I might recommend:

Sssuming that you're not tweaking the definition the geometry each frame,
consider using StreamGeometry (available in Feb CTP) to build your
Geometries rather than PathGeometry. PathGeometry expose a nice
object-based view on Geometry, including databinding/animation support, but
it is heavier than it would need to be to represent just a geometric area.
StreamGeometry operates very similarly to DrawingVisual w/DrawingContext -
you call Open on the StreamGeometry and get back a context on which you can
call BeginFigure, LineTo, etc. This should speed things up (and reduce
working set) independent of what other optimizations you may make.

Also - How often are you updating the contents of your scene? Are you
attempting to alter these geometries every frame, or is this just once at
startup? If you do update them often, do you need to replace *all* of them,
or is it just a few? If you're just updating a few of them, you may wish to
consider dividing your set of geometries across a number of different
DrawingVisuals and then only updating the few Visuals which changed
frame-over-frame. If your updates involve transforming geometries but not
changing their definitions, you might consider retaining a reference to the
Transform you push and just updating its values rather than replacing the
contents of the entire Visual.

Let us know how this works, and we'll see what "next steps" we can take,
-Adam Smith [MS]


"Nothi" <Nothi@discussions.microsoft.com> wrote in message
news:8449AC8F-2B0F-4FAC-B6E2-3755DA6F8E47@microsoft.com...
> Hi all!
>
> I'm trying to build a viewing - engine for Vector Graphics using WPF. As
> far
> as I understand, one should use the "Visual" - Layer to Draw primitives.
> So
> I'm doing the following:
>
> DrawingVisual dv = new DrawingVisual();
> DrawingContext dc = dv.RenderOpen();
>
> dc.PushTransform(new TranslateTransform(mOffsetX, mOffsetY));
> dc.PushTransform(new ScaleTransform(mScale, mScale, 200, 200));
>
> // now here i insert a LOT of PathGeometries (more than 10.000) by doing:
> PathGeometry pg = new PathGeometry();
> // fill Path - Geometry..... (with PathFigure)
> dc.DrawGeometry(b, p, pg);
>
> To finish the drawing - process, I need to write:
> dc.Close();
>
> My Problem is that "dc.Close();" takes about 90% of the overall time
> (about
> 10 seconds for 10.000 Geometries).
> What am i doing wrong? Any Ideas?
> Is there any other (faster way) to "fill" the WPF DRawing engine?
>
> Thanx,
> Nothi
>
>



My System SpecsSystem Spec
05-16-2006   #3
Nothi


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

Hi Adam!

Thank you for your valuable suggestions!

I changed the code to use StreamGeometry and StreamGeometryContext. This did
speed things up for some degree.
I'm just not sure wether I use the right approach yet. Compared to a Managed
GDI+ - Version the WPF - Code is still a magnitude slower.

Here is my current approach:
I created a custom GraphicsHost - Class:
internal class LayerHost : FrameworkElement ...
This class has a private VisualCollection I use to store my graphics and
overrides VisualChildrenCount as well as GetVisualChild(int index).

The graphic data is loaded from a file and drawn into a DrawingVisual like
this:
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
.....
// draw and add every geometry
StreamGeometry sg = new StreamGeometry();
StreamGeometryContext sc = sg.Open();
..... (Stuff like BeginFigure and LineTo()
// Close Context and Draw StreamGeometry
sc.Close();
sg.Freeze(); //speeds things up a bit
dc.DrawGeometry(b, p, sg); // b, p being brush and pen
// all geometries done, close DrawingContext and add DrawingVisual to
private Collection
dc.Close();
mVC.Add(dv);

The above code is performed only ONCE (on loading time) for - if I got it
right - WPF uses retained graphics.

I need to scale and translate my graphics as the user "zooms" and "pans"
using the mouse.
So I tried to do the following (Code in OnMouseWheel of DisplayWindow):
ScaleTransform st = new ScaleTransform(newScale, newScale, 200.0, 200.0);
// Set the transformation for my LayerHost
lh.LayoutTransform = st;

This automatically invokes a redraw and rescale of my graphics.

Am I using the right approach?

Thanx,
Nothi


"Adam Smith [MS]" wrote:

> A few things I might recommend:
>
> Sssuming that you're not tweaking the definition the geometry each frame,
> consider using StreamGeometry (available in Feb CTP) to build your
> Geometries rather than PathGeometry. PathGeometry expose a nice
> object-based view on Geometry, including databinding/animation support, but
> it is heavier than it would need to be to represent just a geometric area.
> StreamGeometry operates very similarly to DrawingVisual w/DrawingContext -
> you call Open on the StreamGeometry and get back a context on which you can
> call BeginFigure, LineTo, etc. This should speed things up (and reduce
> working set) independent of what other optimizations you may make.
>
> Also - How often are you updating the contents of your scene? Are you
> attempting to alter these geometries every frame, or is this just once at
> startup? If you do update them often, do you need to replace *all* of them,
> or is it just a few? If you're just updating a few of them, you may wish to
> consider dividing your set of geometries across a number of different
> DrawingVisuals and then only updating the few Visuals which changed
> frame-over-frame. If your updates involve transforming geometries but not
> changing their definitions, you might consider retaining a reference to the
> Transform you push and just updating its values rather than replacing the
> contents of the entire Visual.
>
> Let us know how this works, and we'll see what "next steps" we can take,
> -Adam Smith [MS]
>
>
> "Nothi" <Nothi@discussions.microsoft.com> wrote in message
> news:8449AC8F-2B0F-4FAC-B6E2-3755DA6F8E47@microsoft.com...
> > Hi all!
> >
> > I'm trying to build a viewing - engine for Vector Graphics using WPF. As
> > far
> > as I understand, one should use the "Visual" - Layer to Draw primitives.
> > So
> > I'm doing the following:
> >
> > DrawingVisual dv = new DrawingVisual();
> > DrawingContext dc = dv.RenderOpen();
> >
> > dc.PushTransform(new TranslateTransform(mOffsetX, mOffsetY));
> > dc.PushTransform(new ScaleTransform(mScale, mScale, 200, 200));
> >
> > // now here i insert a LOT of PathGeometries (more than 10.000) by doing:
> > PathGeometry pg = new PathGeometry();
> > // fill Path - Geometry..... (with PathFigure)
> > dc.DrawGeometry(b, p, pg);
> >
> > To finish the drawing - process, I need to write:
> > dc.Close();
> >
> > My Problem is that "dc.Close();" takes about 90% of the overall time
> > (about
> > 10 seconds for 10.000 Geometries).
> > What am i doing wrong? Any Ideas?
> > Is there any other (faster way) to "fill" the WPF DRawing engine?
> >
> > Thanx,
> > Nothi
> >
> >

>
>
>

My System SpecsSystem Spec
05-21-2006   #4
Rana


 
 

Preserve Transform references to boost performance

Hi Nothi,

To increase performance of transformations during user input from
devices such as the mouse you may with to preserve a reference to
LayerHost.LayoutTransform and modify properties on the transform
instead of re-assigning a new instance of the transform. I've found
this doubled the framerate in my particular scenario.

// LayoutHost Initialization
ScaleTransform m_ScaleTransform = ScaleTransform.Identity;

TranslateTransform m_TranslateTransform = TranslateTransform.Identity;

TransformGroup transformGroup = new TransformGroup();

transformGroup.Children.Add(m_ScaleTransform);

transformGroup.Children.Add(m_TranslateTransform);

layerHost.LayoutTransform = transformGroup;


// Mouse Event Handler
m_ScaleTransform.CenterX= 200;

m_ScaleTransform.CenterY= 200;

m_ScaleTransform.ScaleX= newScaleX;

m_ScaleTransform.ScaleY= newScaleY;


HTH,

Rana

My System SpecsSystem Spec
05-26-2006   #5
Fred Vandervelde


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

Hi Nothi:

I suspect you and I are attempting to do many of the same things. I've
built a partially complete rendering engine for a proprietary CAD format,
and will soon be starting a project during which I'll be completing it for
an eventual commercial application.

I'm also somewhat unsure about the optimal rendering path - perhaps we could
benefit through sharing some code/pseudo code with each other and MS folks
in this group.

I'll see if I can't post the framework for what I'm currently doing soon.

Fred

"Nothi" <Nothi@discussions.microsoft.com> wrote in message
news:8449AC8F-2B0F-4FAC-B6E2-3755DA6F8E47@microsoft.com...
> Hi all!
>
> I'm trying to build a viewing - engine for Vector Graphics using WPF. As
> far
> as I understand, one should use the "Visual" - Layer to Draw primitives.
> So
> I'm doing the following:
>
> DrawingVisual dv = new DrawingVisual();
> DrawingContext dc = dv.RenderOpen();
>
> dc.PushTransform(new TranslateTransform(mOffsetX, mOffsetY));
> dc.PushTransform(new ScaleTransform(mScale, mScale, 200, 200));
>
> // now here i insert a LOT of PathGeometries (more than 10.000) by doing:
> PathGeometry pg = new PathGeometry();
> // fill Path - Geometry..... (with PathFigure)
> dc.DrawGeometry(b, p, pg);
>
> To finish the drawing - process, I need to write:
> dc.Close();
>
> My Problem is that "dc.Close();" takes about 90% of the overall time
> (about
> 10 seconds for 10.000 Geometries).
> What am i doing wrong? Any Ideas?
> Is there any other (faster way) to "fill" the WPF DRawing engine?
>
> Thanx,
> Nothi
>
>



My System SpecsSystem Spec
05-30-2006   #6
Nothi


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

Hi Fred!

You are right, I am also trying to build a rendering engine, for GIS - data
in my case.
I tried some approaches for my prototype (DirectX, WPF, GDI+, ...). It seems
to me that WPF wasn't really designed to render huge amounts of data. It's
more into GUI - Design. Compared to GDI+ WPF is still slower. I don't know if
this is by design or just because we are seeing a beta.

Right now I'm trying to switch to Vista Beta 2, maybe the new driver model
can reveal the power of WPF.

WHat are your experiences with this performance?

cheers,
Nothi


"Fred Vandervelde" wrote:

> Hi Nothi:
>
> I suspect you and I are attempting to do many of the same things. I've
> built a partially complete rendering engine for a proprietary CAD format,
> and will soon be starting a project during which I'll be completing it for
> an eventual commercial application.
>
> I'm also somewhat unsure about the optimal rendering path - perhaps we could
> benefit through sharing some code/pseudo code with each other and MS folks
> in this group.
>
> I'll see if I can't post the framework for what I'm currently doing soon.
>
> Fred
>
> "Nothi" <Nothi@discussions.microsoft.com> wrote in message
> news:8449AC8F-2B0F-4FAC-B6E2-3755DA6F8E47@microsoft.com...
> > Hi all!
> >
> > I'm trying to build a viewing - engine for Vector Graphics using WPF. As
> > far
> > as I understand, one should use the "Visual" - Layer to Draw primitives.
> > So
> > I'm doing the following:
> >
> > DrawingVisual dv = new DrawingVisual();
> > DrawingContext dc = dv.RenderOpen();
> >
> > dc.PushTransform(new TranslateTransform(mOffsetX, mOffsetY));
> > dc.PushTransform(new ScaleTransform(mScale, mScale, 200, 200));
> >
> > // now here i insert a LOT of PathGeometries (more than 10.000) by doing:
> > PathGeometry pg = new PathGeometry();
> > // fill Path - Geometry..... (with PathFigure)
> > dc.DrawGeometry(b, p, pg);
> >
> > To finish the drawing - process, I need to write:
> > dc.Close();
> >
> > My Problem is that "dc.Close();" takes about 90% of the overall time
> > (about
> > 10 seconds for 10.000 Geometries).
> > What am i doing wrong? Any Ideas?
> > Is there any other (faster way) to "fill" the WPF DRawing engine?
> >
> > Thanx,
> > Nothi
> >
> >

>
>
>

My System SpecsSystem Spec
06-05-2006   #7
Fred Vandervelde


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

Hi Nothi,

Thus far I have been working with the CTP builds on Windows XP, and I am
most interested in the XP performance, so I'll likely continue to do so. I
have everything moved over to Beta 2 at the time of writing.

As far as my experience goes, I have actually been somewhat impressed by the
speed I observed when I initially wrote my renderer, especially considering
the graphic quality that WPF maintains.

However, I know that I will be taxing the engine much more as I get further
into development, and I'm looking for the optimal rendering path.

I've attached a screenshot of my test application to give you a feel for
what I'm doing. (really low quality though).

The white area on the right is a Canvas.

The Canvas has as it's only child a custom VisualHost class based on
FrameworkElement.

My VisualHost class provides overrides for VisualChildrenCount and
GetVisualChild, that both reference a VisualCollection.

My "Load" process adds custom objects based on DrawingVisual to the
VisualCollection. Each of these custom DrawingVisual objects
overrides Render(), in which they grab a DrawingContext, draw their content,
and then close the drawing context, like this:

public override void Render()

{

DrawingContext dc = this.RenderOpen();

dc.DrawEllipse(null, _stroke, _center, _xradius, _yradius);

dc.Close();

}

I have classes for Lines, Arcs, Ellipses, Polylines, etc. I also have a
class which encapsulates the functionality of a CAD block or figure. It
contains a <List> of GeometryDrawings which it draws in Render() in between
calls to push and pop a transformation for rotation and scaling.

I have changed all instances where I was using PathGeometry to the new
StreamGeometry, to get the performance benefits of the new lightweight
implementation.

My custom classes add to the overhead, but I need to keep track of some of
their properties from the CAD application (ie layer, etc) because my
application will allow filling, selection, etc. I know could also look into
'batching' some of the unimportant geometry and draw it all into a single
visual, but beyond that, I'm not sure what I can do WPF wise with regards to
application performance.

I also use the VisualHost class to provide some support for hit testing, pop
up menus, etc.

So Nothi, or anyone else reading this thread - is this the optimal path to
drawing at the visual layer? If there's anything anyone can point me to
with regards to performance improvement it would be appreciated. All in
all, I'm thrilled with the features and visual fidelity afforded by WPF, but
attaining good performance with a lot of geometry seems like it may require
some real creative approaches.

Thoughts anyone?

Thanks,

FH









My System SpecsSystem Spec
06-07-2006   #8
Nothi


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

Hi Fred!

I just made my stuff run on Windows Vista Beta2. Looks like the new driver
model doens't speed up WPF, the rendering performance didn't improve.
Compared to your solution, my approach is about the same. I dont't have
custom Visuals yet, for I'm in research - state, but I also add a lot of
DrawingVisuals and do all the actual rendering using StreamGeomtry.

Here's what I did to gain performance:
1) Freeze anything thats freezable (Brush, Pen, ...)
2) Changed from one big DrawingVisual containing all geometries to many
DrawingVisuals. This had a big impact on perfomance
3) Followed your advice for Zoom / Pan

Further test showed, that I can't top GDI+ with the WPF - Beta.
Maybe we could get a statement from the WPF - guys from Microsoft...

Cheers,
Nothi


"Fred Vandervelde" wrote:

> Hi Nothi,
>
> Thus far I have been working with the CTP builds on Windows XP, and I am
> most interested in the XP performance, so I'll likely continue to do so. I
> have everything moved over to Beta 2 at the time of writing.
>
> As far as my experience goes, I have actually been somewhat impressed by the
> speed I observed when I initially wrote my renderer, especially considering
> the graphic quality that WPF maintains.
>
> However, I know that I will be taxing the engine much more as I get further
> into development, and I'm looking for the optimal rendering path.
>
> I've attached a screenshot of my test application to give you a feel for
> what I'm doing. (really low quality though).
>
> The white area on the right is a Canvas.
>
> The Canvas has as it's only child a custom VisualHost class based on
> FrameworkElement.
>
> My VisualHost class provides overrides for VisualChildrenCount and
> GetVisualChild, that both reference a VisualCollection.
>
> My "Load" process adds custom objects based on DrawingVisual to the
> VisualCollection. Each of these custom DrawingVisual objects
> overrides Render(), in which they grab a DrawingContext, draw their content,
> and then close the drawing context, like this:
>
> public override void Render()
>
> {
>
> DrawingContext dc = this.RenderOpen();
>
> dc.DrawEllipse(null, _stroke, _center, _xradius, _yradius);
>
> dc.Close();
>
> }
>
> I have classes for Lines, Arcs, Ellipses, Polylines, etc. I also have a
> class which encapsulates the functionality of a CAD block or figure. It
> contains a <List> of GeometryDrawings which it draws in Render() in between
> calls to push and pop a transformation for rotation and scaling.
>
> I have changed all instances where I was using PathGeometry to the new
> StreamGeometry, to get the performance benefits of the new lightweight
> implementation.
>
> My custom classes add to the overhead, but I need to keep track of some of
> their properties from the CAD application (ie layer, etc) because my
> application will allow filling, selection, etc. I know could also look into
> 'batching' some of the unimportant geometry and draw it all into a single
> visual, but beyond that, I'm not sure what I can do WPF wise with regards to
> application performance.
>
> I also use the VisualHost class to provide some support for hit testing, pop
> up menus, etc.
>
> So Nothi, or anyone else reading this thread - is this the optimal path to
> drawing at the visual layer? If there's anything anyone can point me to
> with regards to performance improvement it would be appreciated. All in
> all, I'm thrilled with the features and visual fidelity afforded by WPF, but
> attaining good performance with a lot of geometry seems like it may require
> some real creative approaches.
>
> Thoughts anyone?
>
> Thanks,
>
> FH
>
>
>
>
>
>
>
>

My System SpecsSystem Spec
06-08-2006   #9
Pablo Fernicola [MS]


 
 

Re: DrawingContext.Close() is very slow for many Geometries drawn

You may want to check out Tim Cahill's blog, and send him your scenario.

http://blogs.msdn.com/timothyc/archi...08/621419.aspx

-Pablo

"Nothi" <Nothi@discussions.microsoft.com> wrote in message
news:13F4AF7B-AC9E-4972-A9DE-DA914760DF10@microsoft.com...
> Hi Fred!
>
> I just made my stuff run on Windows Vista Beta2. Looks like the new driver
> model doens't speed up WPF, the rendering performance didn't improve.
> Compared to your solution, my approach is about the same. I dont't have
> custom Visuals yet, for I'm in research - state, but I also add a lot of
> DrawingVisuals and do all the actual rendering using StreamGeomtry.
>
> Here's what I did to gain performance:
> 1) Freeze anything thats freezable (Brush, Pen, ...)
> 2) Changed from one big DrawingVisual containing all geometries to many
> DrawingVisuals. This had a big impact on perfomance
> 3) Followed your advice for Zoom / Pan
>
> Further test showed, that I can't top GDI+ with the WPF - Beta.
> Maybe we could get a statement from the WPF - guys from Microsoft...
>
> Cheers,
> Nothi
>
>
> "Fred Vandervelde" wrote:
>
>> Hi Nothi,
>>
>> Thus far I have been working with the CTP builds on Windows XP, and I am
>> most interested in the XP performance, so I'll likely continue to do so.
>> I
>> have everything moved over to Beta 2 at the time of writing.
>>
>> As far as my experience goes, I have actually been somewhat impressed by
>> the
>> speed I observed when I initially wrote my renderer, especially
>> considering
>> the graphic quality that WPF maintains.
>>
>> However, I know that I will be taxing the engine much more as I get
>> further
>> into development, and I'm looking for the optimal rendering path.
>>
>> I've attached a screenshot of my test application to give you a feel for
>> what I'm doing. (really low quality though).
>>
>> The white area on the right is a Canvas.
>>
>> The Canvas has as it's only child a custom VisualHost class based on
>> FrameworkElement.
>>
>> My VisualHost class provides overrides for VisualChildrenCount and
>> GetVisualChild, that both reference a VisualCollection.
>>
>> My "Load" process adds custom objects based on DrawingVisual to the
>> VisualCollection. Each of these custom DrawingVisual objects
>> overrides Render(), in which they grab a DrawingContext, draw their
>> content,
>> and then close the drawing context, like this:
>>
>> public override void Render()
>>
>> {
>>
>> DrawingContext dc = this.RenderOpen();
>>
>> dc.DrawEllipse(null, _stroke, _center, _xradius, _yradius);
>>
>> dc.Close();
>>
>> }
>>
>> I have classes for Lines, Arcs, Ellipses, Polylines, etc. I also have a
>> class which encapsulates the functionality of a CAD block or figure. It
>> contains a <List> of GeometryDrawings which it draws in Render() in
>> between
>> calls to push and pop a transformation for rotation and scaling.
>>
>> I have changed all instances where I was using PathGeometry to the new
>> StreamGeometry, to get the performance benefits of the new lightweight
>> implementation.
>>
>> My custom classes add to the overhead, but I need to keep track of some
>> of
>> their properties from the CAD application (ie layer, etc) because my
>> application will allow filling, selection, etc. I know could also look
>> into
>> 'batching' some of the unimportant geometry and draw it all into a single
>> visual, but beyond that, I'm not sure what I can do WPF wise with regards
>> to
>> application performance.
>>
>> I also use the VisualHost class to provide some support for hit testing,
>> pop
>> up menus, etc.
>>
>> So Nothi, or anyone else reading this thread - is this the optimal path
>> to
>> drawing at the visual layer? If there's anything anyone can point me to
>> with regards to performance improvement it would be appreciated. All in
>> all, I'm thrilled with the features and visual fidelity afforded by WPF,
>> but
>> attaining good performance with a lot of geometry seems like it may
>> require
>> some real creative approaches.
>>
>> Thoughts anyone?
>>
>> Thanks,
>>
>> FH
>>
>>
>>
>>
>>
>>
>>
>>



My System SpecsSystem Spec
 

RB


Thread Tools


Similar Threads for: DrawingContext.Close() is very slow for many Geometries drawn
Thread Forum
Have to press 'Close' or 'X' twice to close Windows Explorer windo Vista General
Open windows slow to close Vista General
cannot close windows media player when i click the 'close' button Vista music pictures video
close with the X means close, not minimze to the system tray Live Mail
Vista Bug Turns File Copying into Drawn-out Affair Vista General


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd