Improving performance of drawing multiple images and clipping using Silverlight Excanvas

197 views
Skip to first unread message

Andreas Rosdal

unread,
Dec 27, 2009, 7:52:46 AM12/27/09
to google-excanvas
Hello

I appreciate the help I've gotten so far with adapting excanvas to my
application running at http://www.freeciv.net/
However, I haven't been able to get the performance good enough yet,
and would really like some more help.

I'm using the latest Silverlight version, to render a 2d isometric
map. The performance is
acceptable using canvas in Firefox, Safari and Crome. However, using
excanvas it's still
too slow to be usable.

This is basically how I use excanvas (slightly simplified):

1. Download a tileset containing many sprites:
http://freeciv.net/tileset/freeciv-web-tileset-1.png
http://freeciv.net/tileset/freeciv-web-tileset-2.png
2. Iterate over all visible map tiles
3. Clip the sprite I want from tile tileset downloaded in 1.
4. Draw the sprite using excanvas, using drawImage()
This results in create() being called 16247 times inside excanvas.


The issue is that this process takes too long using Excanvas and
silverlight,
so I'd really like some advice about how to improve this performance.

Here are some ideas I have:
- Try to cache the cropped sprited generated in step #3, and draw
these directly in step 4.
- Implement a native C# method to do all this directly inside
Silverlight.
- One reason that rendering slows down might be that this method
constantly
adds new XAML Image-objects each time I render a frame, but never
seems to
clean up after it self. Should I do something special in before I
render a new full
isometric map frame?

Any other ideas or advice? I have been struggling with this for a
while now.. :)

Thanks!

- Andreas R.

Fabien Ménager

unread,
Dec 27, 2009, 8:36:02 AM12/27/09
to google-excanvas
Hello Andreas,
Seeing the number of different sprites your application seems to
handle, I'm not surprised by your problem. Does your application
really need to use the Canvas tag ? Could it be, even partially, be
drawn using DIVs with the tiles as background images ? With this, no
new nodes will be inserted, they'll just be moved with CSS styles.
I'm not very optimistic about the quantity of optimizations ExCanvas
could have, as it is already really well optimized, and a binary like
you'd like could make your app even more complicated.

Don't hesitate to tell me if my idea is crazy ;)

Fabien

On Dec 27, 1:52 pm, Andreas Rosdal <andre...@pvv.ntnu.no> wrote:
> Hello
>
> I appreciate the help I've gotten so far with adapting excanvas to my

> application running athttp://www.freeciv.net/

Andreas Rosdal

unread,
Dec 28, 2009, 4:44:05 AM12/28/09
to google-excanvas
Thanks for the advice. I'll take another look at using DIVs with
background-images for IE.

However, I'm not quite sure how the DIVs can just be "moved with CSS
styles".
The whole map is too lagre to create one DIV for each tile of the
entire map, so I would probably
have to create DIVs for only the tiles which are in the visible
rectangle shown to the user.
Further, there's no way to know in advance exactly how many DIVs are
needed to draw all the images
which are part of the visible map canvas. Therefore I don't think it's
possible to have a predetermined
number of DIVs which are moved around to draw the mapview. So to
render a frame I would have to
first remove all DIVs, then add new DIVs depending on which map tiles
are visible, which could be slow.
If you can think of another way to create DIVs in advance, and then
move them around with CSS
styles, I'd be interested.

Here's an example of an isometric map engine which uses DIVs:
http://www.pc-gamers.com/webgamex/iso_js_coords.php

As you can see from this example, it appears to flicker during each
redraw, because there's
no way to control when the browser will do the rendering to the
screen. I suspect that this
flickering will be worse when a larger screen is drawn to, and when
more tiles are drawn,
as my app requires.

Further, there's no good way to render lines and text using this DIV
method,
while these methods are provided by excanvas.

- Andreas

Jay Link

unread,
Dec 28, 2009, 1:38:14 PM12/28/09
to google-...@googlegroups.com
Yes, I think Fabien has the right idea.


> However, I'm not quite sure how the DIVs can just be "moved with CSS
> styles".

Use absolute positioning in CSS + javascript to set to top and left coordinates.


> Further, there's no way to know in advance exactly how many DIVs are
> needed to draw all the images

You can create elements dynamically, after page load, like so:

document.createElement("div");

and then use <parent element>.appendChild() to put it on the visible page.


If this is all foreign to you, there are some good tutorials on using
javascript to manipulate the DOM on this guy's site:

http://www.quirksmode.org/js/contents.html

Check the "DOM" and "CSS manipulation" sections especially.


Here is something I'm working on that is similar to what Fabien's
talking about. I have a hack of excanvas to handle rotations, but
otherwise just use simple javascript to move DIVs:

http://traindemo.jaylink.name/

Press 1, 2, or 3 to move the loco. 0 or the space key stops it. Use
the arrow keys to change direction. Click on the switches to turn
them. (as of yet, there's no visual indication that the switches have
been thrown).

Andreas Rosdal

unread,
Jan 3, 2010, 4:34:57 PM1/3/10
to google-excanvas
I have now created a new version of the game, which renders the map
using DIV's with background images. It appears to work pretty good in
Internet Explorer, but not quite as fast as using Canvas.
Thanks for the help.

- Andreas

Reply all
Reply to author
Forward
0 new messages