The mutatation would be on the logic thread side. Consider this:

draw_to_screen(surf_a,  ...)
if cond:
    surf_a.blit(surf_b, ...)
draw_to_screen(surf_a, ...)

Currently draw_to_screen() is synchronous. I'd like it to queue the blit
instead, to happen in another thread. If I just did

def draw_to_screen(surf, ...):
    draw_queue.put((surf, ...))

then there's a race condition - surf_a may be drawn twice with the surf_b
update.

If draw_to_screen() is implemented like

def draw_to_screen(surf, ...):
     draw_queue.put((surf.copy(), ...))

Then I get no change in behaviour, but I copy on every blit, on the logic
thread, ie 2 copies per frame regardless of whether cond is True.

Changing the implementation of copy to create a COW clone means that the
buffer copy actually happens at this line, if it is hit:

surf_a.blit(surf_b, ...)

Which means that there's 1 copy if cond is True and 0 if cond is False.

On Sun, 17 Jun 2018, 20:59 Radomir Dopieralski, <pyg...@sheep.art.pl> wrote:

> On Sun, 17 Jun 2018 17:48:26 +0200
> Daniel Pope <ma...@mauveweb.co.uk> wrote:
>
> > I have been thinking for some time about how to optimise Pygame Zero
> > games on Raspberry Pi. Most Pi models have multiple cores and an
> > obvious improvement is to parallelise. Logic has to be synchronous
> > but I would like to offload painting the screen to a separate thread.
> >
> > The problem I would have is in passing references to mutable objects
> > between threads. Primarily this applies to Surface objects, which are
> > mutable and expensive to copy. If I have a draw thread that maintains
> > a queue of screen blit operations, I want the queue to hold
> > references to surface data that won't change even if I later mutate
> > the surfaces in the logic thread.
>
> Sorry if I am missing something obvious, but it seems to me that the
> draw thread doesn't need to mutate the surfaces? I mean, it only
> accesses them in a read-only fashion to render them. So you don't need
> to pass references to mutable objects — the drawing thread can get a
> read-only reference. Why do you need it to have a reference to
> non-changing data? After all, if it changes, you will have to re-draw
> it in the next frame anyways. Unless the drawing thread is more than
> one frame behind (which really shouldn't happen), you don't care about
> the data changing.
>
> --
> Radomir Dopieralski
>

Reply via email to