[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Cheap COW clones for surfaces



Of course strictly speaking there is a difference in behavior, however,
from the practical point of view, the difference boils down to the fact
that something gets drawn half a frame earlier rather than half a frame
later (because the command to draw it was given in between the
frames). Unless you have less than 6 frames a second, the difference
wouldn't be easy to notice, especially since it would be rather rare
too, since you would need to get very specific timings to even have it
happen. I wonder if it's worth the effort.

On Sun, 17 Jun 2018 21:40:56 +0100
Daniel Pope <mauve@xxxxxxxxxxxxxx> wrote:

> 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, <pygame@xxxxxxxxxxxx>
> wrote:
> 
> > On Sun, 17 Jun 2018 17:48:26 +0200
> > Daniel Pope <mauve@xxxxxxxxxxxxxx> 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
> >  


-- 
Radomir Dopieralski