draw_text/ draw_obj slow...?

Posted By: Superku

draw_text/ draw_obj slow...? - 07/02/18 13:30

At the AckCon I was running a test of a multiplayer game on various machines. On many machines the FPS was all over the place, in particular not consistent at all (as in let's say jumping between 30 and 90 FPS or equivalent ms of processing every few frames).

I've narrowed down the performance bottlenecks using dtimer(). Turns out, drawing text on screen (for example for names or live rankings) consumes way more performance than all other things in the game combined.

Example test project:
Click to reveal..
Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>
///////////////////////////////

FONT* dummy_fnt = "Courier New#40b";

TEXT* dummy_txt =
{
	string("");
	font = dummy_fnt;
	flags = LIGHT | OUTLINE;
}

TEXT* array_txt[30];

void main()
{
	fps_max = 60;
	video_mode = 9;
	vec_fill(screen_color,64);
	double dMax = 0;
	/*short shortArray[4];
	shortArray[0] = 0xd853;
	shortArray[1] = 0xdf5c;
	shortArray[2] = shortArray[3] = 0;
	STRING* strW = str_createw(shortArray); regular ASCII text is enough*/
	
	int i;
	for(i = 0; i < 30; i++)
	{
		TEXT* txt = txt_create(1,1);
		str_printf((txt.pstring)[0],"String %d at frame 1234",i);
		txt.font = dummy_fnt;
		txt.flags = LIGHT | OUTLINE;
		txt.pos_x = 10;
		txt.pos_y = 60+20*i;
		array_txt[i] = txt;
	}
	
	while(1)
	{
		//draw_text(strW,800,20,COLOR_RED);
		dtimer();
		int i;
		for(i = 0; i < 30; i++)
		{
			if(key_space) draw_obj(array_txt[i]);
			else
			{
				STRING* str = str_printf(NULL,"String %d at frame %d",i,(int)total_frames);
				//draw_text(str,10,60+20*i,COLOR_RED);
				str_cpy((dummy_txt.pstring)[0],str);
				dummy_txt.pos_x = 10;
				dummy_txt.pos_y = 60+20*i;
				vec_set(dummy_txt.blue,COLOR_WHITE);
				draw_obj(dummy_txt);
			}
		}
		double dTime = dtimer();
		if(dTime*0.001 > dMax) dMax = dTime*0.001;
		if(total_frames%120 == 0) dMax = 0;
		draw_text(str_printf(NULL,"Time for drawing 30 strings: %.3fms (max: %.3fms)",(double)(dTime*0.001),dMax),10,20,COLOR_RED);
		
		wait(1);
	}
}



My desktop PC runs on an i7-6700K. It takes around 2.7ms on average to draw 30 strings, with spikes of 10+ms every few seconds.
On my weaker (i7 still) laptop I have an average execution time of 5ms but highly fluctuating betwen 4.9ms and 10ms, with spikes of 13+ms.


Why it is that slow and why are there huge differences in execution time (including but not limited to the spikes), instead of being about the same every frame?
Can this be fixed/ improved?
Posted By: Superku

Re: draw_text/ draw_obj slow...? - 07/02/18 13:53

Using the SHOW flag instead for the TEXT array objects seems to be a little faster but does show some spikes as well (in time_panels).

EDIT: Drawing bitmaps with draw_quad is much faster (as one would expect) but even there you'll find some spikes. No spikes when I don't use draw_ instructions (saved frame_time into an array, wrote that into a file at the end of the application, so it's draw_ related).
Posted By: jcl

Re: draw_text/ draw_obj slow...? - 07/04/18 14:06

The text is drawn with DirectX functions, which in turn call functions of the video drivers. That's why it is machine dependent. I suppose the problem is the switch between 3D and 2D drawing with some drivers, but I have no ready solution to make it faster. Using a TEXT object helps because that is drawn after all content of the 3D pipeline.
Posted By: Superku

Re: draw_text/ draw_obj slow...? - 07/04/18 14:34

Okay, thanks for giving insight.

For anybody wondering:
As a workaround I use an array of dummy TEXT objects. In draw instructions I use their IDs as an extra argument.
A custom DRAWCONTAINER struct is stored in a TEXT object's skill_x. If any parameters (in the custom draw_text or draw_obj call) changed or if it's the first time that text is supposed to be drawn, the text will be drawn to a BMAP.
If nothing changes, just the bitmap from previous frames will be drawn to the screen using draw_quad.
This has cut down the text rendering performance impact from 2.5+ms to ~0.15ms (depending on how often strings change) in my game on my machine.

Click to reveal..
Code:
typedef struct
{
	int type;
	void *obj;
	BMAP* bmp;
	int bmpIsExternal;
	int forceUpdate;
	int lastFrameUpdate;
	long flags;
	STRING *pstr;
	char *charsCopy;
	char *pchars;
	int length;
	COLOR color;
	FONT* font;
	var size_x,size_y;
} DRAWCONTAINER;

int draw_obj_cached(void *sourceObj)
{
	int index = ((int*)sourceObj)[0];
	int type = (index >> 24);
	
	if(type == HBYTE_TEXT)
	{
		TEXT* txt = (TEXT*)sourceObj;
		STRING* str = (txt->pstring)[0];
		DRAWCONTAINER* container = (DRAWCONTAINER*)txt->skill_x;
		compare data... -> create bmap if necessary and redraw
		draw_quad(bmp)
	}
}

Posted By: pegamode

Re: draw_text/ draw_obj slow...? - 07/05/18 06:48

Looks like a smart workaround ...
© 2024 lite-C Forums