gfxGLPrimitiveBuffer.cpp
Engine/source/gfx/gl/gfxGLPrimitiveBuffer.cpp
Public Variables
Public Functions
Detailed Description
Public Variables
MODULE_INIT
MODULE_SHUTDOWN
Public Functions
getCircularVolatileIndexBuffer()
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "gfx/gl/gfxGLDevice.h" 25#include "gfx/gl/gfxGLPrimitiveBuffer.h" 26#include "gfx/gl/gfxGLEnumTranslate.h" 27 28#include "gfx/gl/tGL/tGL.h" 29#include "gfx/gl/gfxGLUtils.h" 30 31#include "gfx/gl/gfxGLCircularVolatileBuffer.h" 32 33GLCircularVolatileBuffer* getCircularVolatileIndexBuffer() 34{ 35 static GLCircularVolatileBuffer sCircularVolatileIndexBuffer(GL_ELEMENT_ARRAY_BUFFER); 36 return &sCircularVolatileIndexBuffer; 37} 38 39GFXGLPrimitiveBuffer::GFXGLPrimitiveBuffer(GFXDevice *device, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType) : 40 GFXPrimitiveBuffer(device, indexCount, primitiveCount, bufferType), mZombieCache(NULL), 41 mBufferOffset(0) 42{ 43 if( mBufferType == GFXBufferTypeVolatile ) 44 { 45 mBuffer = getCircularVolatileIndexBuffer()->getHandle(); 46 return; 47 } 48 49 // Generate a buffer and allocate the needed memory 50 glGenBuffers(1, &mBuffer); 51 52 PRESERVE_INDEX_BUFFER(); 53 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 54 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(U16), NULL, GFXGLBufferType[bufferType]); 55} 56 57GFXGLPrimitiveBuffer::~GFXGLPrimitiveBuffer() 58{ 59 // This is heavy handed, but it frees the buffer memory 60 if( mBufferType != GFXBufferTypeVolatile ) 61 glDeleteBuffers(1, &mBuffer); 62 63 if( mZombieCache ) 64 delete [] mZombieCache; 65} 66 67void GFXGLPrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr) 68{ 69 if( mBufferType == GFXBufferTypeVolatile ) 70 { 71 AssertFatal(indexStart == 0, ""); 72 getCircularVolatileIndexBuffer()->lock( mIndexCount * sizeof(U16), 0, mBufferOffset, *indexPtr ); 73 } 74 else 75 { 76 mFrameAllocator.lock( mIndexCount * sizeof(U16) ); 77 78 *indexPtr = (void*)(mFrameAllocator.getlockedPtr() + (indexStart * sizeof(U16)) ); 79 } 80 81 lockedIndexStart = indexStart; 82 lockedIndexEnd = indexEnd; 83} 84 85void GFXGLPrimitiveBuffer::unlock() 86{ 87 PROFILE_SCOPE(GFXGLPrimitiveBuffer_unlock); 88 89 if( mBufferType == GFXBufferTypeVolatile ) 90 { 91 getCircularVolatileIndexBuffer()->unlock(); 92 } 93 else 94 { 95 U32 offset = lockedIndexStart * sizeof(U16); 96 U32 length = (lockedIndexEnd - lockedIndexStart) * sizeof(U16); 97 98 // Preserve previous binding 99 PRESERVE_INDEX_BUFFER(); 100 101 // Bind ourselves 102 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 103 104 if( !lockedIndexStart && lockedIndexEnd == mIndexCount) 105 glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexCount * sizeof(U16), NULL, GFXGLBufferType[mBufferType]); // orphan the buffer 106 107 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, mFrameAllocator.getlockedPtr() + offset ); 108 109 mFrameAllocator.unlock(); 110 } 111 112 lockedIndexStart = 0; 113 lockedIndexEnd = 0; 114} 115 116void GFXGLPrimitiveBuffer::prepare() 117{ 118 // Bind 119 GFXGLDevice* glDevice = static_cast<GFXGLDevice*>(mDevice); 120 glDevice->setPB(this); 121 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 122 glDevice->getOpenglCache()->setCacheBinded(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 123} 124 125void GFXGLPrimitiveBuffer::finish() 126{ 127 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 128 static_cast<GFXGLDevice*>(mDevice)->getOpenglCache()->setCacheBinded(GL_ELEMENT_ARRAY_BUFFER, 0); 129} 130 131GLvoid* GFXGLPrimitiveBuffer::getBuffer() 132{ 133 // NULL specifies no offset into the hardware buffer 134 return (GLvoid*)mBufferOffset; 135} 136 137void GFXGLPrimitiveBuffer::zombify() 138{ 139 if(mZombieCache) 140 return; 141 142 mZombieCache = new U8[mIndexCount * sizeof(U16)]; 143 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 144 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mIndexCount * sizeof(U16), mZombieCache); 145 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 146 glDeleteBuffers(1, &mBuffer); 147 mBuffer = 0; 148} 149 150void GFXGLPrimitiveBuffer::resurrect() 151{ 152 if(!mZombieCache) 153 return; 154 155 glGenBuffers(1, &mBuffer); 156 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer); 157 glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexCount * sizeof(U16), mZombieCache, GFXGLBufferType[mBufferType]); 158 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 159 160 delete[] mZombieCache; 161 mZombieCache = NULL; 162} 163 164namespace 165{ 166 bool onGFXDeviceSignal( GFXDevice::GFXDeviceEventType type ) 167 { 168 if( GFX->getAdapterType() == OpenGL && GFXDevice::deEndOfFrame == type ) 169 getCircularVolatileIndexBuffer()->protectUsedRange(); 170 171 return true; 172 } 173} 174 175MODULE_BEGIN( GFX_GL_PrimitiveBuffer ) 176 MODULE_INIT_AFTER( gfx ) 177 MODULE_SHUTDOWN_BEFORE( gfx ) 178 179 MODULE_INIT 180 { 181 GFXDevice::getDeviceEventSignal( ).notify( &onGFXDeviceSignal ); 182 } 183 184 MODULE_SHUTDOWN 185 { 186 GFXDevice::getDeviceEventSignal( ).remove( &onGFXDeviceSignal ); 187 } 188MODULE_END 189
