1

I've noticed something very strange about blitting items in pygame. If you have a list of items to be blitted to the screen, if the screen has no colorkey then there is no problem, the framerate stays level. But when there is a colorkey, for each object being blitted there is a huge loss in framerate per item to be blitted.

Take the following code:

import pygame
import copy

pygame.init()

d=786,684
screen=pygame.display.set_mode(d)
screen.set_colorkey((255,255,255)) #anything white is transparent

canv=pygame.image.load('canvas.png')
screen.blit(canv,(0,0))
canvas=screen.copy() #main canvas, first object in the list of blitted items

tmpcanv=copy.copy(canvas) #this is the surface to which all the lines are drawn
                          #this surface is then added to the blitlist once the mouse
                          #comes up.

blitlist=[canvas,tmpcanv] #the list of items to be blitted
mp=[] #the list of mouse points for the draw tool

timer=pygame.time.Clock()
fpsLim=120

drawing=False

def display(): #blits the items to the screen in order
    for item in blitlist:
        r=item.get_rect()
        screen.blit(item,(r[0],r[1]))

def getmouse_pos():
    mp.append((mx,my))
    if len(mp)>2:
        del mp[0]

def add_drawing(surf):
    if not surf is blitlist[-1]:
        blitlist.append(surf)

def reinit_tmpcanv():
    tmpcanv=copy.copy(canvas)

display()

running=True
while running:
    for evt in pygame.event.get():
        if evt.type==pygame.QUIT:
            running=False
        elif evt.type==pygame.MOUSEBUTTONDOWN:
            drawing=True
            add_drawing(tmpcanv)
        elif evt.type==pygame.MOUSEBUTTONUP:
            drawing=False
            tmpcanv=copy.copy(canvas)

    timer.tick(fpsLim)

    if drawing:
        s=mp[0]; e=mp[1]
        pygame.draw.aaline(tmpcanv,(0,0,0),s,e)

    mx,my=pygame.mouse.get_pos()
    getmouse_pos()

    print(timer.get_fps())

    display()

    pygame.display.update()
pygame.quit()

Notice that the framerate limit is 120 fps. Well with 30 or more drawings in the blitlist the framerate drops to 8 fps. It will continue to go down from there as well. I've gotten it down to 0.5 fps (albeit with 200+ drawings in the blitlist).

So my question; is there something wrong with my code that is causing this substantial loss in framerate, or is pygame just really inefficiently blitting the surfaces when a colorkey is involved?

user3002473
  • 4,835
  • 8
  • 35
  • 61
  • 1
    A colorkey blit that doesn't have any hardware support will require the software check every pixel (see if it matches the colorkey or not) before drawing the "new" pixel. Obviously, if there is hardware support for colorkeying, the hardware will do the checking, and this is much faster. Since I have no idea if pygame can support hardware support for colorkey, I can't say if this is even an option. – Mats Petersson Jan 04 '14 at 18:41
  • Do you think the pygame surfarray module and numpy might speed up the process a little bit? – user3002473 Jan 04 '14 at 18:43
  • Sorry, I understand graphics very well, but don't know what will work in pygame and what won't (currently working with OpenCL, but have been working with graphics chips, drivers and such in one way or another for about 8 out of the last 10 years). I'd be VERY surprised if numpy offers any benefit tho'. – Mats Petersson Jan 04 '14 at 18:46

0 Answers0