Page 1 of 1

VG_OUT_OF_MEMORY_ERROR

Posted: Wed Sep 03, 2014 4:16 am
by olso4539
I keep receiving VG_OUT_OF_MEMORY_ERROR errors in my application. I'm using OpenVG through egl dispmanx windows from the console.
I'm trying to create a scrolling effect by drawing paths (data series) in a narrow band on the right, updating the window buffer, copying the window contents to the left by the width of the drawing band, and repeating. I'm doing it this way so that I can plot huge arrays of data without repeating the expensive rasterization operation involved with redrawing the paths as they scroll.

As a starting point I was updating the entire plot with each iteration and I was able to append ~32000 data points (an exact, repeatable maximum) to a path in one operation before I got a VG_OUT_OF_MEMORY_ERROR. I assume I was eating up large amounts of ram with some rasterization step. Increasing the available GPU memory did not affect this limit. Reading through the openvg source, it seems like the problem is coming from vgAppendPathData, and it is a failed call to malloc that cascades back through function calls. (that also explains why extending a path takes so long...)
(malloc)->(_vcos_platform_malloc)->(vcos_generic_mem_alloc_aligned)->(vcos_generic_mem_alloc)->(vcos_malloc)->(khrn_platform_malloc)->(khrn_vector_extend)->(vgAppendPathData)
What I wonder is, why is it trying to extend the path every time in the first place? It iterates with the exact same path length many times before failing, is vgClearPath not only clearing the path data, but freeing the memory? Looking at the source I'm guessing that's what khrn_vector_clear does within vgClearPath. Maybe my cpu memory is fragmenting like crazy and filling up from all these mallocs and frees? I'll try watching htop while this is running, i had previously assumed it was GPU memory it was running out of...

Once I implemented the scrolling function using vgCopyPixels I started to get random and unrepeatable VG_OUT_OF_MEMORY_ERROR errors. If run for a low enough number of iterations the program occasionally finishes without error. If the errors are ignored (assert statements commented out) the program continues to run, with occasional hangs that last several seconds resulting from failed vgDrawPath(...) operations (out of memory failures). Sometimes, the entire system locks up, and other times the display turns to garbage. What am I doing wrong, or, did I find an OpenVG implementation bug? Am I or the OpenVG implementation leaking GPU CPU memory?

The entire project source code is available here https://github.com/olso4539/HSDMPi. The relevant code section is here. If using the full source, it is compiled with make, and run with ./HSDMPi. It can also be configured through the first four lines of example1.config if run with the command line argument example1.config.

Code: Select all

void UpdatePlot() {
	int i, width, height;

	static int j = 0;

	width = plotWidth;
	height = plotHeight;

	if (n>10000) n=10000;

	vgCopyPixels(0, 0, (width*n)/total, 0, width-(width*n)/total, height);

	vgClear(width-(width*n)/total, 0, (width*n)/total, height);

	for (i=0;i<(2*n);i+=2) {
		dataPoints[0][i]=dataPoints[1][i]=dataPoints[2][i]=dataPoints[3][i]=dataPoints[4][i]=dataPoints[5][i]=dataPoints[6][i]=dataPoints[7][i]=width*(1-(float) n/total + (float) i/(2*total));
	}

	for (i=1;i<(2*n);i+=2) {
		dataPoints[0][i]=height*(1+sinf((float) j/1000))/2;
		dataPoints[1][i]=height*(1+sinf((float) j/1010))/2;
		dataPoints[2][i]=height*(1+sinf((float) j/1020))/2;
		dataPoints[3][i]=height*(1+sinf((float) j/1030))/2;
		dataPoints[4][i]=height*(1+sinf((float) j/1040))/2;
		dataPoints[5][i]=height*(1+sinf((float) j/1050))/2;
		dataPoints[6][i]=height*(1+sinf((float) j/1060))/2;
		dataPoints[7][i]=height*(1+sinf((float) j/1070))/2;
		++j;
	}
	--j;

	for (i=0;i<8;++i) {
		vgAppendPathData(paths[i], n, pathcommands, dataPoints[i]);
//		vgError = vgGetError();
//		assert(vgError != VG_OUT_OF_MEMORY_ERROR);

		setstroke(colors[i], 1);
		vgDrawPath(paths[i], VG_STROKE_PATH);
//		vgError = vgGetError();
//		assert(vgError != VG_OUT_OF_MEMORY_ERROR);
		vgClearPath(paths[i],VG_PATH_CAPABILITY_ALL);
	}
}
After this function, eglSwapBuffers is called. eglSurfAttrib EGL_SWAP_BEHAVIOR is set to EGL_BUFFER_PRESERVED so that the back buffer is preserved by eglSwapBuffers

Re: VG_OUT_OF_MEMORY_ERROR

Posted: Sun Sep 07, 2014 4:03 am
by olso4539
I have done a few things that seem to have lessened the problem. I replaced repeated calls to vgAppendPathData and vgClearPath with one call to vgAppendPathData and repeated calls to vgModifyPathCoords. I also removed calls to vgCreatePaint and vgDestroyPaint and any other code that repeatedly creates and destroys objects. It seems that i no longer get any out of memory errors.

My advice to anyone working with openvg, reuse data structures as much possible to avoid excessive memory reallocation (especially in tight loops). I'm still trying to figure out how i can plot only part of a path so that i can change the size of a path without deallocating and reallocating the path memory.

Re: VG_OUT_OF_MEMORY_ERROR

Posted: Fri Dec 19, 2014 8:31 am
by blackshard83
Maybe you were just experiencing some sort of heavy memory fragmentation.

My project uses lots of small buffers (rendered glyph images) and now I have 31 different free memory blocks in my heap, ranging from 48 bytes to 130 megabytes.

I guess you know, but "vcdbg reloc" shows the current heap status with all memory allocations.