How can we accelerate the vgDrawPath

I found that vgDrawPath is taking too much time to draw if vgPath contains around 18000 segments. this takes around 0.4 second to draw in a single iterator which is really slow for H/W acclerated api. Is there any way to accelerate the drawing?


18,000… 0.4s… that’s actually pretty quick considering all the work you’re asking of it.
With that many segments, things like intersection tests slow things down partly due to VG’s fill rules and requirement not to have overdraw. (18,000 segments could be approximated by some 30,000-120,000 lines, and the intersection tests are generally not a linear algorithm)
Is there anyway to break down that geometry a little? For example, it’s generally a bad idea to construct a single path saying “Hello World” instead of 7 paths rendering each letter separately (one for each of: “H”, “e”, “l”, “o”, “W”, “r”, and “d”). That sort of thing could cause a speed up.

If you have control over the path’s geometry, lines are better than curves (quads better than cubics).
What exactly are you rendering to have that many segments in a single path?

I am trying to draw the map’s road with that path.
If I breaked the path segments into different path also, I think in this case there will be more path with less segments and I feel overall result will be same in terms of time consumed to draw a single iteration.

No, it will not be the same. That’s my point.
When submitting all map geometry in a single pass, several things happen:

1 - all intersections are covered once. For example, if you drew the paths with 50% alpha on a solid background, you’d notice the intersections (where 2 lines cross) are the same color as the rest road. If you drew the roads one by one, the intersections would be a different color than the rest of the road. The computation to find and eliminate these intersections takes some time (In general, it’s not linear time with the number of coordinates) - it could be part of the problem. Since you’re probably not going rendering the roads with not full alpha, the final result will look no different either way. This may not make a huge difference (especially with small amounts of geometry [in fact it may be slower due to the overdraw]), but for 18,000 segments you might start seeing some gains. Experiment to see if it makes a difference.

2 (and most importantly) - you are, in all likelihood, attempting to render much more geometry than is necessary. All vertecies will never-the-less have to be transformed and clipped. It’s a giant waste of processing power. If you have zoomed out far enough to actually be able to see almost everything, then things like short dead-end streets should disappear off the map at that distance. Controlling “Level of Detail” is all important in a map application. Don’t render too much, and don’t render bits that are off screen. Your application is much better suited for determining which roads can and cannot appear on the screen than the graphics driver. Also, by submitting a large section of “InsertName Rd.” you can keep it around in a separate OpenVG object, and re-use it. The driver probably has some caching mechanism to render the path quicker the next time around. If you are continuously changing the path data (i.e. continuously calling vgAppendPathData() to change what the visible roads look like), no such caching is possible and it will run slower.

I also recommend you try to find an optimization guide for your particular OpenVG implementation. Some drivers will be faster doing certain things rather than others (questions like: “will integer coordinates be faster than floating point coordinates for path data?” are all driver specific, and you’ll need to look to your driver vendor to finer points of optimization).

Thanks Ivo,
By creating multiple path for different roads, instead of putting all the segments into a single path, I found that the drawing time reduced by 50%:).

There should be no problems with doing vgCreatpath and vgAppendPathData from outside your render loop (that;s how it’s supposed to be done, in fact).
What does need to happen is the creates, appenddata, and draw all have to happen from the same context. It sounds like your context is current in the place you put the create functions (no OpenVG call works without a context being current). If you’re multi-threaded/processes, you will also want to look at how your EGL deals with that (I don’t think that creating the path object in one process and using it in another is legal for example).

As for scissoring, whether it’s accelerated or not depends on the hardware. Scissoring might require a lot of the rendering to default to software rendering, and hence be real slow. If that’s the case, you can try clever ways around it - like rendering to a small buffer and blitting the result to the screen or something.

In general, destroy paths you no longer plan to use - it frees memory in the driver for other things. However, do NOT free, if you’re just going to be re-creating it again and reloading it with the same data later. Feel free to use vgClearPath() if you just want to free memory but reuse the object.