Reputation: 21
I'm running into out of memory exceptions in device log generated by GPU when trying to load heavy graphics scene using VBO on Android.
20:53:48.640 app W/Adreno-GSL: <sharedmem_gpumem_alloc_id:2255>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
20:53:48.642 app E/Adreno-GSL: <gsl_memory_alloc_pure:1971>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
Raw binary data size i'm trying to supply is less than half of available amount of RAM. After doing some research, i found that after each glBufferData(..)
call the amount of free memory decreases 2 times the size of data supplied (tried on different devices, same result). Here is my setup:
logMem("before buff creation");
ByteBuffer dummyBuff = ByteBuffer.allocateDirect(1024 * 1024 * 16).order(ByteOrder.nativeOrder());
byte[] some = new byte[1024];
for (int i = 0; i < dummyBuff.capacity(); i+= some.length) {
dummyBuff.put(some);
}
dummyBuff.rewind();
logMem("buff data created");
int[] bufferHandles = new int[1];
GLES20.glGenBuffers(1, bufferHandles, 0);
int bufferHandle = bufferHandles[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferHandle);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, dummyBuff.capacity(), dummyBuff, GLES20.GL_STATIC_DRAW);
logMem("buff data supplied");
Amount of memory left is logged with
manager = (ActivityManager) getSystemService( Activity.ACTIVITY_SERVICE );
info = new ActivityManager.MemoryInfo();
...
manager.getMemoryInfo(info);
Log.v("mem", tag + ", mem " + info.availMem/1024/1024);
Here is what i am getting in the log
20:13:34.243 V/mem: before buff creation, mem 1381
20:13:34.466 V/mem: buff data created, mem 1366
20:13:34.500 V/mem: buff data supplied, mem 1334
I also tried a combination of
GLES20.glBufferData(.., dummyBuf.capacity(), null, ..);
GLES20.glBufferSubData(.., 0, dummyBuf.capacity(), dummyBuf);
In this case after first line execution i was getting a loss of 1x buffer size, as expected, but with the second, another 1x buffer size of memory was gone. I tried it on 2 different devices utilizing different GPUs (Adreno, Mali) and was getting same behavior. So, my question is: am i missing something, or is this an expected behavior? Is there any way to decrease this RAM impact when supplying data to VBO?
Upvotes: 2
Views: 729
Reputation: 12084
Are you remembering to free the copy of the buffer you allocated?
In OpenGL ES all GPU server-side resources (textures, buffers, programs, etc) are copied into memory owned by the driver stack. Drivers can't just keep pointers to the buffers allocated by the application.
Once you have uploaded the data you can safely delete the application-side copy; it's not needed any more.
Upvotes: 1