I'm trying to speedup the rendering (both latency and throughput wise) in the Inkscape vector image editor so that it can be more artist friendly.
I'm trying to decide whether to draw directly to the window or draw to an intermediate offscreen surface and then copy it to the window.
If the whole canvas had to be redrawn every time, then drawing directly to the window will clearly be faster by conserving memory bandwidth. But unfortunately, Inkscape doesn't do GPU rendering so it can't afford to redraw the whole window, only the rectangles that were invalidated.
Let's say i have 2 rectangles that need to be redrawn.
The 1st method is to get acquire a sub surface for each rectangle using gdk_window_begin_draw_frame(rect), draw, and send it to the screen. But the disadvantage is you can't draw the 2 in parallel because GTK only allows 1 rectangle to be locked at a time.
The 2nd method I thought of is to ask the windowing system (GTK) for the bounding box of the 2 rectangles. Then draw the 2 in parallel, and send the results to the screen. But here the problem is GTK doesn't preserve the old contents of the window - it clears the entire update region, creating blank areas in the gap between the 2 rectangles.
So for the 2nd method to work, I could either ask the GUI toolkit to preserve the contents of the window or render to an intermediate buffer that preserves the whole window. But that would require extra copying. I want to know is it customary to discard the previous contents when drawing? I'm aware that discarding has the performance advantage of not having to wait for previous rendering to complete and not having to read back from GPU memory to CPU memory. That advice is given for OpenGL's glMapBuffer() and DirectX surfaces' LockRect(). But glMapBuffer() does have an option to return the old contents. So should GTK have such an option too? Or is that too much to ask?
It seems a lot of the problems I face are artificial due to the GUI toolkit limitations. For example, if the GUI toolkit lets you update multiple regions in parallel, then the 1st method would work and be easier. OpenGL lets you do that with glMapBufferRange().
I would like a good solution for GTK, but at the same time I would like to know if you had very direct access to the GPU hardware, how would you implement the partial drawing I described most efficiently?