Is it possible to save and restore graphics?

Hello,

I wrote a very simple touch drawing program (shameless plug: http://twolivesleft.com/Codea/Talk/discussion/85/minimalist-drawing-program), and I’m trying to see if I can improve its performance. Right now, I record every touch as they occur, and in the draw method I erase the whole thing and redraw the touches. Of course, after a while the list of things to draw gets big and the program starts lagging. I tried not calling the “background” method to erase things but then the screen flicker.

What I would like to do is, instead of replaying the list of touches, to be able to save the current buffer at the end of the draw method, then restore it at the beginning of the next one. Is it possible? If not, could I file this as a feature request?

From the sound of it, this is pretty much the default behaviour. Just make sure you’re not clearing the screen in the draw() method (the background() function does the clear). Then paint each touch as it comes in, you don’t need to store anything.

Note though that you’ll hit the triple-buffering bug/feature and you’ll get some flickering. There’s a thread about it, I think the solution was something like drawing every 3rd frame.

Ah, thanks for the suggestion. I thought that the flickering was normal, but if there is a workaround, I’ll definitely try it.

If you’re painting strokes, the flicker might not be a problem. It can cause the illusion of movement, as if the stroke is flowing, which is kind of cool :slight_smile:

The flicker seems to be specific to iPad hardware. You can do drawing every Xth frame like so:

--
function draw()
    frame = frame + 1
    if frame%X == 0 then
        -- draw
    end

Note that if you only draw every X frames, it will still flicker because the screen will be blank every frame before the x’th one.
What you really need to do is only update every X frame, and draw that frame yourself every other frame.

I agree it would be good to have a command to copy the previous frame into the current one. We will look into it.

Might be possible to add some sort of render-to-texture mechanism as well.

+5 yes please! render to texture, and blitting, are maybe my #1 wants at this point (other than the code sharing stuff, which is in the pipeline)

Thanks for the comments. I’m currently investigating how rendering works, but I see a rendering bug will be fixed in the next version. Is it this flicker things?

Not the flickering, Dylan has found that using a retained backing store on the OpenGL context will eliminate the flickering – however it really kills iPad 1 performance.

The rendering bug fixed in the new version is that it clears the back buffer when the project starts running, so you don’t get “left over” pictures from other projects in your view. The

I have just added the ability to use “retained” backing. Its a call you make in setup, to say if you want to retain the previous frame. Due to the way the iPad works, this will roughly halve the frame rate on iPad 1 for anything with a decent amount of drawing (like some of the example apps).

It should be in the version after the next one.

Woot - that sounds like the ideal solution. I thank you, my complex fonts thank you.

No problems :slight_smile:
Next on my list is setting pixels… this is going to be interesting!

Great news about that setting.

In my tests about flickering, this is what I found out, using the following very simple code:

frame = 0
first_frame = 30
nb_frames = 2

function draw()
    fill(180, 85, 85, 255)
    
    if frame < first_frame + nb_frames then
        frame = frame + 1
        if frame >= first_frame then
            ellipse(600,400,10)
        end
    end
end

If you set nb_frames at 1 you get flickering, and at 2 you don’t.

What’s more interesting is that you don’t retain the drawing before frame 20 or so: try setting first_frame to 10 for instance, and the dot will go away. Above 20, it stays, and the transition is somewhere around 16 or 17, but I’m not sure it’s clearly defined. I guess some setup code must still be running as the event loop starts, and one needs to wait 20 frames or so before things settle down.