package org.andengine.opengl.vbo; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.concurrent.locks.ReentrantLock; import org.andengine.opengl.util.BufferUtils; import org.andengine.opengl.vbo.attribute.VertexBufferObjectAttributes; /** * Compared to {@link ZeroMemoryVertexBufferObject}, all {@link SharedMemoryVertexBufferObject}s share a single {@link ByteBuffer} which is used by whichever {@link SharedMemoryVertexBufferObject} instance is currently buffering data, * at the cost of expensive data buffering (<b>up to <u>5x</u> slower!</b>) and a little synchronization overhead. * <p/> * Usually a {@link SharedMemoryVertexBufferObject} is preferred to a {@link ZeroMemoryVertexBufferObject} when the following conditions need to be met: * <ol> * <li>Minimum amount of runtime GarbageCollector activity.</li> * </ol> * <p/> * (c) Zynga 2011 * * @author Nicolas Gramlich <ngramlich@zynga.com> * @author Greg Haynes * @since 19:22:13 - 10.02.2012 */ public abstract class SharedMemoryVertexBufferObject extends ZeroMemoryVertexBufferObject { // =========================================================== // Constants // =========================================================== private static ReentrantLock sSharedByteBufferLock = new ReentrantLock(true); private static ByteBuffer sSharedByteBuffer; public static int getSharedByteBufferByteCapacity() { final int byteCapacity; try { SharedMemoryVertexBufferObject.sSharedByteBufferLock.lock(); final ByteBuffer sharedByteBuffer = SharedMemoryVertexBufferObject.sSharedByteBuffer; if(sharedByteBuffer == null) { byteCapacity = 0; } else { byteCapacity = sharedByteBuffer.capacity(); } } finally { SharedMemoryVertexBufferObject.sSharedByteBufferLock.unlock(); } return byteCapacity; } // =========================================================== // Fields // =========================================================== // =========================================================== // Constructors // =========================================================== public SharedMemoryVertexBufferObject(final VertexBufferObjectManager pVertexBufferObjectManager, final int pCapacity, final DrawType pDrawType, final VertexBufferObjectAttributes pVertexBufferObjectAttributes) { super(pVertexBufferObjectManager, pCapacity, pDrawType, false, pVertexBufferObjectAttributes); } // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public void dispose() { super.dispose(); try { SharedMemoryVertexBufferObject.sSharedByteBufferLock.lock(); if(SharedMemoryVertexBufferObject.sSharedByteBuffer != null) { BufferUtils.freeDirectByteBuffer(SharedMemoryVertexBufferObject.sSharedByteBuffer); SharedMemoryVertexBufferObject.sSharedByteBuffer = null; } } finally { SharedMemoryVertexBufferObject.sSharedByteBufferLock.unlock(); } } @Override protected ByteBuffer aquireByteBuffer() { SharedMemoryVertexBufferObject.sSharedByteBufferLock.lock(); final int byteCapacity = this.getByteCapacity(); if(SharedMemoryVertexBufferObject.sSharedByteBuffer == null || SharedMemoryVertexBufferObject.sSharedByteBuffer.capacity() < byteCapacity) { if(SharedMemoryVertexBufferObject.sSharedByteBuffer != null) { BufferUtils.freeDirectByteBuffer(SharedMemoryVertexBufferObject.sSharedByteBuffer); } SharedMemoryVertexBufferObject.sSharedByteBuffer = BufferUtils.allocateDirectByteBuffer(byteCapacity); SharedMemoryVertexBufferObject.sSharedByteBuffer.order(ByteOrder.nativeOrder()); } SharedMemoryVertexBufferObject.sSharedByteBuffer.limit(byteCapacity); return SharedMemoryVertexBufferObject.sSharedByteBuffer; } @Override protected void releaseByteBuffer(final ByteBuffer byteBuffer) { SharedMemoryVertexBufferObject.sSharedByteBufferLock.unlock(); } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }