Bad performance using surfaces

T

TomatoFantasyStudio

Guest
Please, can anyone tell me, maybe I use surfaces the wrong way?Hey, everyone!
Can anyone help me? :D

I create surfaces like in code below.

Code:
surface_set_target(application_surface);
//Draw blood of wounds, fullscreen animation of glitches etc.
surface_reset_target();

//If don't need to use colour displacement shader (hero is alright). Use ONLY shader 1
{
shader_set(<shader1_name>); //Draw shader 1
draw_surface(application_surface,0,0);  
shader_reset();
}
else
//If needed to draw colour displacement shader in addition (when hero were wounded). Use shader 1 AND shader 2
{
    if !surface_exists(surfa)
    {
        surfa = surface_create(gui_w, gui_h);
    }

    shader_set(<shader1_name>); //Draw shader 1
    surface_set_target(surfa);
    draw_surface(application_surface,0,0);  
    surface_reset_target();
    shader_reset();  
   
    shader_set(<shader2_name>); //Shader 2 - colour displacement
    draw_surface(surfa,0,0);  
    shader_reset();
}
And createtion code.
Code:
surfa = -1;

gui_w = display_get_gui_width();
gui_h = display_get_gui_height();

surface_resize(application_surface, gui_w, gui_h);
application_surface_draw_enable(false);

And get VERY bad perfomance. Even with low resolution.
Please, can anyone tell me, maybe I use sufaces the wrong way? :(
 
Last edited by a moderator:
T

TomatoFantasyStudio

Guest
How big is the surface you are drawing? i.e. what is the value of gui_w and gui_h? Is it still slow when you remove the shader processes?
Surfaces are equal to resolution you choose in game. It can be 960x540, 1280x720 or 1920x1080. And when I remove shaders it doesn't effects fps much (maybe about 1-2 fps).


check what is taking time with the debugger. I have had experience of getting bad performance with suing many surface_reset_target.
I have only one surface_reset_target. Debugger says this function takes about 0.063 ms.


Make sure you have "synchronization to avoid tearing" or whatever the option is called now disabled. Some computers can't handle more than 1 or 2 surfaces.
"Synchronization to avoid tearing" was disabled.

One more interesting thing. Many people launched the game one time and get very bad performance. But after reloading PC sometimes it was fine. And after some work time on PC againg bad. Not the only one man, so I think there problem in game.
Maybe someone came across this? :confused:
 
Last edited by a moderator:

Pfap

Member
Surfaces are equal to resolution you choose in game. It can be 960x540, 1280x720 or 1920x1080. And when I remove shaders it doesn't effects fps much (maybe about 1-2 fps).



I have only one surface_reset_target. Debugger says this function takes about 0.063 ms.



"Synchronization to avoid tearing" was disabled.

One more interesting thing. Many people launched the game one time and get very bad performance. But after reloading PC sometimes it was fine. And after some work time on PC againg bad. Not the only one man, so I think there problem in game.
Maybe someone came across this? :confused:
Are you calling surface_free(your_surface); when you are finished with it?
What event is your code located in?


I copied and pasted your code below:
Code:
surface_set_target(application_surface);
//Draw blood of wounds, fullscreen animation of glitches etc.
surface_reset_target();

//If don't need to use colour displacement shader (hero is alright). Use ONLY shader 1
{
shader_set(<shader1_name>); //Draw shader 1
draw_surface(application_surface,0,0);  
shader_reset();
}
else
//If needed to draw colour displacement shader in addition (when hero were wounded). Use shader 1 AND shader 2
{
    if !surface_exists(surfa)
    {
        surfa = surface_create(gui_w, gui_h);
    }

/******************************
I added this else block
*******************************/
else{
surface_free(surfa);
}

    shader_set(<shader1_name>); //Draw shader 1
    surface_set_target(surfa);
    draw_surface(application_surface,0,0);  
    surface_reset_target();
    shader_reset();  
   
    shader_set(<shader2_name>); //Shader 2 - colour displacement
    draw_surface(surfa,0,0);  
    shader_reset();
}

I think you might need that else block to free the surface existing in the previous step.
 

TheouAegis

Member
Are you calling surface_free(your_surface); when you are finished with it?
What event is your code located in?


I copied and pasted your code below:
Code:
surface_set_target(application_surface);
//Draw blood of wounds, fullscreen animation of glitches etc.
surface_reset_target();

//If don't need to use colour displacement shader (hero is alright). Use ONLY shader 1
{
shader_set(<shader1_name>); //Draw shader 1
draw_surface(application_surface,0,0); 
shader_reset();
}
else
//If needed to draw colour displacement shader in addition (when hero were wounded). Use shader 1 AND shader 2
{
    if !surface_exists(surfa)
    {
        surfa = surface_create(gui_w, gui_h);
    }

/******************************
I added this else block
*******************************/
else{
surface_free(surfa);
}

    shader_set(<shader1_name>); //Draw shader 1
    surface_set_target(surfa);
    draw_surface(application_surface,0,0); 
    surface_reset_target();
    shader_reset(); 
  
    shader_set(<shader2_name>); //Shader 2 - colour displacement
    draw_surface(surfa,0,0); 
    shader_reset();
}

I think you might need that else block to free the surface existing in the previous step.
But why would he free the surface every step if you just going to recreate it again The next step anyway? If you are using it from step to step to step, then there's no point in freeing it.
 

Pfap

Member
But why would he free the surface every step if you just going to recreate it again The next step anyway? If you are using it from step to step to step, then there's no point in freeing it.
Otherwise, your surfaces will start to pile up creating a surface on top of surface effect. If you are drawing something non-static and creating the surface in the draw event you want to free it and draw a clear alpha on the newly created one.


Edit:

To the op

I forgot to mention the draw clear alpha part.
Code:
surface_free(surface);


surface = surface_create(camera_get_view_width(view_camera[1]), camera_get_view_height(view_camera[1]));


surface_set_target(surface);
draw_clear_alpha(c_black, 0);
surface_reset_target();
Depending upon what you're drawing you may not need to always draw the clear alpha.
 
Last edited:

TheouAegis

Member
Otherwise, your surfaces will start to pile up creating a surface on top of surface effect.
Unless he's using room_restart or game_restart elsewhere in his project, where is he repeatedly creating a surface on top of another surface? It's code specifically states to create a new service only if there is no corresponding surface to the variable that holds the surface ID.
if !surface_exists(surfa) {
surfa = surface_create(gui_w, gui_h);
}
in the code that he posted, I see no memory leak. Nor do I see anywhere where he declares the variable surf a with the command var, at which point freeing the surface every step is just a waste of the program's time. Surfaces are not meant to be destroyed every step.
 

Pfap

Member
Unless he's using room_restart or game_restart elsewhere in his project, where is he repeatedly creating a surface on top of another surface? It's code specifically states to create a new service only if there is no corresponding surface to the variable that holds the surface ID.

in the code that he posted, I see no memory leak. Nor do I see anywhere where he declares the variable surf a with the command var, at which point freeing the surface every step is just a waste of the program's time. Surfaces are not meant to be destroyed every step.
Yea you're right, I missed that for some reason.
 
Top