memleaks on SDLx::Layer, SDLx::LayerManager, SDLx::Text and probably others

[email protected] (LS) Mon, 26 Sep 2011 02:09:01 +0200
Newsgroups perl.sdl.devel
Message-ID <20110926020901.40c3e5e5@cube>
hello list,

i recently started writing a small game in perl & sdl and noticed a few memleaks
which i was able to (partially) avoid by rewriting a few things, however it's
kind of frustrating. maybe i just use the wrong version or something - i would 
realy appreciate if anyone can point me out a good solution.

i attached a small script to demonstrate some issues, where is also one similar
issue with the SDLx::Text write* methods, it seems there is a leak somewhere 
during creation of the surface used internally.

just posting this here because it seems the server where the bug tracking is 
hosted is down, if it just was moved can someone please provide me the new url?


regards
memleaks.pl (application/x-perl, 3.5 KB)
#!/usr/bin/perl

use 5.14.1;             # tested with 5.10.1, 5.12.4, 5.14.1 under Linux/amd64 (debian squeeze), also Strawberry Perl 5.12.3 on WinXP (32bit)
                        # Alien::SDL build from source + all prereq ( usually last choice on running build script ) version 1.428
                        # SDL version 2.533

use Inline with => 'SDL';
no strict;
use Inline C;
use strict;


use SDL::Event;
use SDL::Surface;
use SDLx::App;
use SDLx::Layer;
use SDLx::LayerManager;
use SDL::Image;


#my $app = SDLx::App->new(t => 'memleaks', w => 640, h => 480, flags => SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWACCEL);
my $app = SDLx::App->new(t => 'memleaks', w => 640, h => 480, flags => SDL_SWSURFACE);  # SW or HW surface dosent matter, the leaking is the same

my $button1 = SDL::Image::load('login_button.png');
my $button2 = SDL::Image::load('login_button_hover.png');

my $layer1 = SDLx::Layer->new($button1, 100, 100);
my $layer2 = SDLx::Layer->new($button2, 110, 110);

my $layers = SDLx::LayerManager->new();

my $surface1 = $layer1->surface;
my $surface2 = $layer2->surface;

my $rect1    = $layer1->clip;
my $rect2    = $layer2->clip;

my $pos1    = $layer1->pos;
my $pos2    = $layer2->pos;


$layers->add($layer1);
$layers->add($layer2);

sub event_handler{
    my ($event, $app) = @_;
    if($event->type == SDL_QUIT) {
        $app->stop;
    }
}
$app->add_event_handler( \&event_handler );




# example #1
sub show_handler_1{
    my($delta, $screen) = @_;
    
    $layers->blit($screen); # this leaks some memory
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_1 );


# example #2
sub show_handler_2{
    my($delta, $screen) = @_;
    
    for my $layer(@{$layers->layers}){
        SDL::Video::blit_surface( $layer->surface, $layer->clip, $screen->surface, $layer->pos );  # this also leaks (even more) memory
    }
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_2 );


# example #3
sub show_handler_3{
    my($delta, $screen) = @_;
    
    for my $layer(@{$layers->layers}){
        native_blit($layer->surface, $layer->pos->x, $layer->pos->y, $screen);   # the same
    }
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_3 );


# example #4
sub show_handler_4{
    my($delta, $screen) = @_;
    
    for my $layer(@{$layers->layers}){ # this is ok... but,
        $layer->surface;    # in fact even this leaks
        $layer->pos->x;     # also this
        $layer->clip;       # and this
    }
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_4);


# example #5
sub show_handler_5{
    my($delta, $screen) = @_;
    
     native_blit($surface1, 100, 100, $screen);   # this finally works
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_5 );



# example #6
sub show_handler_6{
    my($delta, $screen) = @_;
    
    SDL::Video::blit_surface( $surface1, $rect1, $screen->surface, $pos1 ); # this also works
    SDL::Video::blit_surface( $surface2, $rect2, $screen->surface, $pos2 );
    
    $screen->flip();    
}
#$app->add_show_handler( \&show_handler_6 );




$app->run();



__END__
__C__

void native_blit(SDL_Surface *layer, Sint16 x, Sint16 y, SDL_Surface *screen){

    SDL_Rect dest_rect = {x, y, 0, 0 };
    SDL_Rect *drect_p;
    drect_p =& dest_rect;
    
    if(SDL_MUSTLOCK(screen))
        if(SDL_LockSurface(screen) < 0)
            return;      

    SDL_BlitSurface(layer, NULL, screen, drect_p);

    if (SDL_MUSTLOCK(screen))
           SDL_UnlockSurface(screen);

    drect_p = NULL;
}