Hello,

this blit_list, blits, blit_mult, blit_many call...

I feel we should call it "Surface.blits". To go with drawline/drawlines.
It would take a sequence of tuples which match up with the blit arguments.

The original Surface.blit API.
    http://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit
  blit(source, dest, area=None, special_flags = 0) -> Rect

The new blits API.
    blits(args) -> [rects]
    args = [(source: Surface, dest: Rect, area: Rect = None, special_flags:
int = 0), ...]
    Draws a sequence of Surfaces onto this Surface...

    :Example:
    >>> surf.blits([(source, dest),
                   (source, dest),
                   (source, dest, area),
                   (source, dest, area, BLEND_ADD)]
    [Rect(), Rect(), Rect(), Rect()]



One potential option...

   - Have a return_rects=False argument, where if you pass it, then it can
   return None instead of a list of rects. This way you avoid allocating a
   list, and all the rects inside it. I'll benchmark this to see if it's worth
   it -- but I have a feeling all those allocations will be significant. But
   some people don't track updates, so allocating the rects is not worth it
   for them. eg. the implementation from Leif doesn't return rects.


It can handle these use cases:

   - blit many different surfaces to one surface (like the screen)
   - blit one surface many times to one surface.
   - when you don't care about rects, it doesn't allocate them.
   - when you do care about update tracking, it can track them.

It can *not* handle (but would anyone care?):

   - blit many surfaces, to many other surfaces.


Areas not included in the scope of this:

   - This could be used by two sprite groups quite easily (Group,
   RenderUpdates). But I think it's worth trying to compile the sprite groups
   with Cython instead, as a separate piece of work.
   - Multi processing. It should be possible to use this API to build a
   multi process blitter. However, this is not addressed in this work. The
   Surface we are blitting onto could be split up into numberOfCore tiles, and
   rendered that way. This is classic tile rendering, and nothing in this API
   stops an implementation of this later.



Enhancements, objections?



cheers,





On Mon, Mar 27, 2017 at 6:38 PM, René Dudfield <ren...@gmail.com> wrote:

> Cool about the blit function. Since the rect and surfaces are by
> reference, then you only need to make sprite_image_list once (if you are
> blitting the same thing every time). Additionally, I think it would likely
> be fast enough for another commonly requested case (blit the same image to
> many different spots). It would also work nicely for sprite groups. I think
> it's worth some more API discussion, before merging it in. We'd also need
> some tests and docs.
>
>
>
> On Mon, Mar 27, 2017 at 4:59 PM, Leif Theden <leif.the...@gmail.com>
> wrote:
>
>> I think a function that accepts a sequence of tuples in the form of
>> (dest_surface, dest_position, source_area, blend_mode) would be enough.  It
>> is only needed as a power-user optimization and I don't seem much value in
>> watering it down or splitting it into multiple functions for beginners.  No
>> need to overthink and complicate it.  Cython may help sprite rendering in
>> Groups, but it would have to be implemented and tested.
>>
>> Has anyone considered releasing the GIL during blit operations?  Is it
>> possible the release the GIL during a blit, then block when needed, in the
>> cases of subsequent draw operations?  The optimized case would be to allow
>> math operations to execute while the display buffer is being modified,
>> while you are iterating over sprites.
>>
>> Here is my preliminary C code for a "blit_multi" function.  It is called
>> "blit_list".  It only supports (dest_surface, dest_position) tuples, but it
>> works as so far.
>> https://gist.github.com/bitcraft/1785face7c5684916cde
>>
>> Use it like this:
>>
>> sprite_image_list = [(s.image, s.rect) for s in self.sprites]
>> display.blit_list(sprite_image_list)
>>
>>

Reply via email to