Allowing stimuli to persist (win.flip(clearBuffer=False) not working)


I’m porting a large Psychopy program from version 1.90 to the latest version (2022.2.5). The underlying hardware has also updated from an Intel MBP c. 2018 to an M1 MBP c. 2021, along with the MacOS (currently Ventura 13.2.1).

I’m having a problem displaying stimuli.

I’m using the frame-based method for determining how long stimuli are displayed:(Presenting Stimuli — PsychoPy v2023.1.1)

That is, I write all the desired stimuli to the buffer (using stimulus.draw()).
Then I figure out how many frames (N) are required to reach the requested duration, and then call win.flip() N times.
Because I want the stimuli to persist across each flip, I call win.flip(clearBuffer=False).

This used to work just fine.

But now with the new psychopy version, computer, macOS version, etc., the stimulus is flickering. Upon closer inspection, it appears that each call to win.flip(clearBuffer=False) alternates between displaying a blank screen and displaying the stimulus from the buffer.

My question is: how do I keep this stimulus flickering from happening?

A couple other tidbits that may be helpful:
The following post seems to address some unpredictable behavior from clearBuffer=False. Does anyone know if that’s what’s happening to me, and if so what a workaround may be?

Also, I’ve considered setting autoDraw=True for each stimulus and/or redrawing the stimulus with each flip. Both of these methods work. However, the program is structured such that a general method controls the timing (along with the window flips), while task-specific methods draw the stimuli. Therefore the timing method doesn’t know about the stimuli, so it wouldn’t be able to redraw them for each frame, nor set autoDraw=False when the epoch is over.
So if one of these 2 approaches (autoDraw or redrawing with each flip) is advised, any suggestions on how to either turn off autodraw, or redraw all stimuli, en masse?

Thanks very much for any guidance!

Yes, as I explain in the post you linked to, the behaviour of clearbuffer=False is up to the graphics card manufacturer and that means it’s susceptible to change whenever you switch to a new machine. It shouldn’t be relied upon.

We also don’t recommend using a Mac, other than for creating the experiment, if screen timing is important to you. See the timing megastudy for details.

Honestly though, if you’re moving from 1.90 to the current version I’d really recommend you switch to using Builder rather than hand-coding at all because:

  • timing is generally better (especially around keypress responses because hand-coders tend to use the outdated event.getKeys method, whereas Builder code uses the more precise Keybaord class)
  • it’s easier later for you, or someone else, to update and adapt your code for newer versions
  • it’s faster than writing code by hand
  • if you ever switch to running online you can do so more easily without starting from scratch again

Back in the days of PsychoPy 1.90, Builder wasn’t so developed and this might not have been the recommendation but, these days, I personally would never code an experiment from scratch by hand (despite having the technical ability to do so)

best wishes

1 Like

Hi Jon,

Thanks for explaining and the suggestions. (And thank you for creating such an amazing resource!).

I actually wrote a piece of middleware that operates in the spirit of the Builder (it’s code-based, though, not a GUI). Several experiments rely on this, so I’m motivated to get it working in the current version of psychopy. If this fails, then we’ll look into rewriting each experiment in builder.

With that goal in mind, I wonder if you could advise on the following:

  • What’s your preferred means to cause stimuli to persist when using the frame-counting method for timing?

  • FWIW, I was considering using autoDraw=True. If this is what you recommend, is there a way to turn off autoDraw (or somehow otherwise prevent them from being redrawn at the next window flip) for all stimuli en masse? If not, is there a repository of handles to all the stimuli somewhere so I could loop through that? (If not, I guess I’ll make such a repo)

  • I appreciate your advice about replacing antiquated methods with current best practices, such as replacing event.getKeys with the newer Keyboard class. Is there a list/article somewhere that collects these various recommendations?

Thanks again!