Aug 10, 2009 at 12:38 AM

Just curious if there is any way to improve performance? InfoStrat.VE is very cool, but seems to be quite a bit less responsive than Virtual Earth 3D running by itself. I'm just wondering if there is anything I can do.

On my Lenovo T60p I seem to get a smooth 30+ FPS with Virtual Earth 3D. InfoStrat.VE, however, only seems to maintain about 10 to 15 FPS. There's also a very noticable (~500 ms) delay in the sample applicaiton between when I change lat / long and when the map starts to rotate.

I searched the threads and noticed that the map is running at 768 x 576 for 'performance reasons'. What are those reasons? (I'm guessing it has something to do with the D3D interop?)


Aug 10, 2009 at 1:51 AM

The performance is highly dependent upon the type and size of the graphics card on your computer.  If the graphics card is an integrated type or uses shared RAM, then you might get good performance with VE3D but bad with InfoStrat.VE.  Internally there are some D3D buffers being copied around and lower end graphics card may not have the necessary bandwidth.

The 768 x 576 is exactly related -- we tested with middle tier consumer cards and on Microsof Surface, and the memory bandwidth for those cards results in a slowdown above 768 x 576.

You could test this by searching for those dimensions and replacing them with a smaller size, like 320 x 240 or 640 x 480.  If you see a performance increase, then the bottleneck is your graphics card.  Unfortunately there are few or no additional ways to optimize.  Trust me, I spent a long time testing all possible methods to get maximum performance.

The downside to decreasing this size is that the ideal control size is lower.  If you set it to 320 x 240 and your final control is 1024 x 768, then the map will be fuzzy because it blows up the size of the image.

As for the delay, is that when you use the FlyTo method or directly set the lat/long?  FlyTo is animated and the update is not immediate.  If you see a delay with setting it immediately, it could be due to the graphics card limitations discussed above or due to VE loading and caching the new tiles.  Are you on a broadband connection?  Do you see delay loading tiles when panning?

Aug 11, 2009 at 5:20 PM
Edited Aug 11, 2009 at 5:24 PM

On Map Size:

I tried setting the map to 320 x 240 and it did speed up some (it also got quite blurry as you indicated it would). But it didn’t speed up nearly dramatically as I expected. I’m estimating perhaps 20 FPS now instead of 10 or 15, but it’s still nowhere near the 30+ without InfoStrat. :(


On Setting Location:

I’m actually setting the location in the sample application by replacing the text in the Lat / Long textbox and tabbing out. This textbox is bound to the LatLong property of the VEMap object.

When the LatLong dependency property is changed, the OnMapPositionPropertyChanged handler sets map.isDependencyPropertiesDirty to true. On the next GraphicsEngine_PostRender, InvalidateVESurface is called which in turn calls RaiseViewChanged. Inside of  RaiseViewChanged, the isDependencyPropertiesDirty flag is evaluated and UpdateMapFromDP is called. This finally causes the map position to be updated.

This whole process takes around 800ms to occur on my machine and the delay does not seem to change much whether the map is sized at 768 x 576 or it’s sized at 320 x 240. Interestingly, when I changed the button click handler in the sample to directly set the LatLong property rather than calling FlyTo, it changed almost IMMEDIATELY. So the delay seems to be in the binding process, but that doesn’t seem right. So I did some additional debugging.


Here’s the line of code that executes in the button handler:


map.LatLong = new Point(pin.LatLong.Latitude, pin.LatLong.Longitude);


When that code executes, OnMapPositionPropertyChanged get’s called 4 times:

1 Ticks: 633855853388421371 Position: 38.9444195081574,-77.0630161230201

2 Ticks: 633855853389151444 Position: 14.7488499987245,-104.107306455295

3 Ticks: 633855853389651494 Position: 38.9444195080317,-77.0630161230201

4 Ticks: 633855853389691498 Position: 9992953.37003692


When I paste in the exact same values into the TextBox and binding occurs, OnMapPositionPropertyChanged also gets called 4 times:

1 Ticks: 633855853885041028 Position: 20.9444195080288,-77.0630161230201

2 Ticks: 633855853888621386 Position: 5.9444195080288,-77.0630161230201

3 Ticks: 633855853889421466 Position: 20.9444195080259,-77.0630161230201

4 Ticks: 633855853889441468 Position: 9992953.37003629


However, notice the times between each update. When the LatLong is updated from the button click, there are very short times between the updates:

Between 1-2: 729,984 ticks

Between 2-3: 499,968 ticks

Between 3-4: 40,064 ticks

Total Update Ticks from Button: 1,270,016


When the update is from a data binding, the updates are MUCH longer:

Between 1-2: 3,580,032 ticks

Between 2-3: 800,000 ticks

Between 3-4: 19,968 ticks

Total Update Ticks from Data Binding: 4,400,000


That means it takes 3.4 times longer to update the LatLong property from a data binding as it does from a button click.

Any thoughts?

Oh, and to answer your last two questions: Yes, I’m using broadband and No, I don’t see a delay loading tiles. In fact, just to be sure I did rotate-pause-rotate all around the globe before I started these tests to make sure everything was already loaded and cached.


Thanks for your time and for creating this library. I'm a big fan.

Aug 12, 2009 at 5:36 AM

Wow, great investigation.  This post is just about the setting location delay.

You're pretty much on about the internal process.  It is interesting that setting directly responds quicker than using binding.  From the code's point of view, there is no difference between the two methods.  Both go through the OnMapPositionPropertyChanged and the dirty flag, etc., as you described.

Keep in mind that OnMapPositionPropertyChanged is used by all of the different property changes, including LatLong, Altitude, Roll, Pitch, and Yaw.  Also, it is only called by the binding system.  That's why the values you are printing have different formats.  #4 looks like the altitude, for example.

If you wanted to instrument it to really see the difference, I'd recommend adding tracing points:

  • In the button click handler
  • In a handler for the latlong text field (onchange or onblur? whatever fires when you tab out)
  • OnMapPositionPropertyChanged, try to filter for only the LatLong property. If not, then temporarily change the argument to PropertyChangedCallback() of 
public static readonly DependencyProperty LatLongProperty
so that you have a separate function.
  • In the RaiseViewChanged method, and output the value of isDependencyPropertiesDirty. (Maybe only output if isDependencyPropertiesDirty is true if too much noise).  Once this one is called and then it calls UpdateMapFromDP(), the absolute next frame rendered will use the new coordinates, because of the JumpCameraController.

You'll also want to output the ticks, and perhaps in RaiseViewChanged also automatically calculate the delta from the previous RaiseViewChanged.

What to look here is the amount of time between the original event and the OnMapPositionPropertyChanged (the binding system overhead) and then the time between OnMapPositionPropertyChanged and RaiseViewChanged with isDPDirty=true would be the delay between the event and the next render event.  Also monitor the render loop rates (i.e. FPS) during the time before and after the event to see if the render loop itself slows down. I wouldn't suspect that it does not.  Particularly interesting would be the time between RaiseViewChanged isDPDirty = true and the next RaiseViewChanged.  Of course compare all these between the two methods.

If the source of the delay is in the binding, then it could be because of the overhead of processing the text of the Point data type.  If the source of the delay is between isDPDirty=true and the next render, then try calling Map.JumpTo directly from the button, which is what UpdateMapFromDP does, and see if the delay is also similar.

Hope this helps and good luck!

Aug 12, 2009 at 5:40 AM

On the map size/FPS, your results indicate that it is a limitation of your graphics card.  Since the performance increased when you reduced the map size, we confirmed the graphics memory bandwidth is the bottleneck.  Please try on a computer with a better graphics card.

Do you have a particular requirement to use a computer with a low end graphics card?  What type of application are you creating?