Increasing Control Rendering Performance
-
I'm creating my own custom control as part of a level editor for a video game. The video game is two-dimensional and is composed of square tiles. The basic idea is that the user has a toolbar containing square images, and that when the user clicks on a tile on the map, that tile is filled with the corresponding image. The user also has the option to click and drag to create a selection rectangle, thus allowing a range of tiles to be filled simultaneously. The initial implementation initially worked well. I was able to create a control showing all the tiles, and allowing individual tiles to be filled. I even got it to the point where dragging the cursor would "highlight" the borders of tiles that were going to be filled. However, I ran into a performance problem when the number of filled tiles increases. The problem is that I was invalidating the form everytime the mouse was moved (to draw the selection rectangle and highlight borders), which caused all of the images to be repainted as well. I made several modifications to attempt to increase performance. The first choice was to enable double buffering, which reduced flickering and improved performance a little. The second mod was to change the invalidate method so that the control was invalidated only when the selection rectangle selected new cells. This resulted in a less-smooth selection method, but increased performance a little. Realizing that invalidating the entire control was wasteful, I made it so that only the "changed" region was invalidated (the region enclosing both the new and old selection between mouse movements). This helped performance as well, but only minimally. Since performance was quite good when there were no filled tiles, the obvious problem is redrawing all of the images (imagine a 20 x 20 grid of 48 x 48 pixel images, so rougly 400 individual images). Despite the fact that double buffering was used, I realized that the images never really need to be painted until AFTER the selection rectangle has finished. So, my next mod focused on keeping a cached bitmap of the current viewing area in the back ground, and in the paint method I just combined this cached background with the selection rectangle when the mouse was moved. When the mouse was released (which invokes an action to fill the cells), I would update the corresponding region on the cached bitmap. The problem with this method is that it still caused the tiled images to be painted each time the mouse was moved (even if the tiles were batched rather than in