user1581348
user1581348

Reputation: 21

OpenGL ES VBO strange memory impact

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

Answers (1)

solidpixel
solidpixel

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

Related Questions