screen – What is surface locking and unlocking in Pygame?

Surface locking allows you to directly access the pixel data of accelerated surfaces. It’s not so much about improving performance. Rather, an accelerated surface already has performance improvements, but it comes with a trade off of requiring locking & unlocking if you’re going to directly change its data.

All of the built in Pygame functions will automatically lock and unlock the Surface data as needed. So for basic blitting, you don’t need to worry about it.

When might you need it? Let’s say you had some code that required multiple get_at() &/or set_at() calls. Each such call requires locking & unlocking the surface & according to the docs:

Getting and setting pixels one at a time is generally too slow to be used in a game or realtime situation.

In that situation, it would likely be more performant to lock the surface once, perform any required reads & writes to the pixel data and then unlock it.

Here’s what the the docs say about locking:

On accelerated Surfaces, the pixel data may be stored in volatile video memory or nonlinear compressed forms. When a Surface is locked the pixel memory becomes available to access by regular software. Code that reads or writes pixel values will need the Surface to be locked.

Surfaces should not remain locked for more than necessary. A locked Surface can often not be displayed or managed by pygame.

Not all Surfaces require locking. The mustlock() method can determine if it is actually required. There is no performance penalty for locking and unlocking a Surface that does not need it.

All pygame functions will automatically lock and unlock the Surface data as needed. If a section of code is going to make calls that will repeatedly lock and unlock the Surface many times, it can be helpful to wrap the block inside a lock and unlock pair.

It is safe to nest locking and unlocking calls. The surface will only be unlocked after the final lock is released.