forked from organicmaps/organicmaps
implemented client vertex array support for old GPU's
This commit is contained in:
parent
179db664d0
commit
1d26145e3e
13 changed files with 119 additions and 45 deletions
|
@ -135,15 +135,15 @@ namespace yg
|
|||
immDrawTexturedPrimitives(rectPoints, texRectPoints, 4, texture, true, yg::Color(), false);
|
||||
}
|
||||
|
||||
void Blitter::setupAuxVertexLayout(bool hasColor, bool hasTexture)
|
||||
void Blitter::setupAuxVertexLayout(bool hasColor, bool hasTexture, void * glPtr)
|
||||
{
|
||||
OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY));
|
||||
OGLCHECK(glVertexPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)AuxVertex::vertexOffs));
|
||||
OGLCHECK(glVertexPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::vertexOffs)));
|
||||
|
||||
if (hasColor)
|
||||
{
|
||||
OGLCHECK(glEnableClientState(GL_COLOR_ARRAY));
|
||||
OGLCHECK(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(AuxVertex), (void*)AuxVertex::colorOffs));
|
||||
OGLCHECK(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::colorOffs)));
|
||||
}
|
||||
else
|
||||
OGLCHECK(glDisableClientState(GL_COLOR_ARRAY));
|
||||
|
@ -151,7 +151,7 @@ namespace yg
|
|||
if (hasTexture)
|
||||
{
|
||||
OGLCHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)AuxVertex::texCoordsOffs));
|
||||
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::texCoordsOffs)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -184,7 +184,7 @@ namespace yg
|
|||
m_blitStorage.m_vertices->unlock();
|
||||
m_blitStorage.m_vertices->makeCurrent();
|
||||
|
||||
setupAuxVertexLayout(hasColor, hasTexture);
|
||||
setupAuxVertexLayout(hasColor, hasTexture, m_blitStorage.m_vertices->glPtr());
|
||||
|
||||
if (texture)
|
||||
texture->makeCurrent();
|
||||
|
@ -194,17 +194,17 @@ namespace yg
|
|||
m_blitStorage.m_indices->unlock();
|
||||
m_blitStorage.m_indices->makeCurrent();
|
||||
|
||||
resourceManager()->freeBlitStorage(m_blitStorage);
|
||||
m_blitStorage = yg::gl::Storage();
|
||||
|
||||
OGLCHECK(glDisable(GL_BLEND));
|
||||
OGLCHECK(glDisable(GL_DEPTH_TEST));
|
||||
OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, 0));
|
||||
OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, m_blitStorage.m_indices->glPtr()));
|
||||
OGLCHECK(glEnable(GL_DEPTH_TEST));
|
||||
OGLCHECK(glEnable(GL_TEXTURE_2D));
|
||||
OGLCHECK(glEnable(GL_BLEND));
|
||||
/// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone.
|
||||
OGLCHECK(glFinish());
|
||||
|
||||
resourceManager()->freeBlitStorage(m_blitStorage);
|
||||
m_blitStorage = yg::gl::Storage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace yg
|
|||
|
||||
typedef Clipper base_t;
|
||||
|
||||
void setupAuxVertexLayout(bool hasColor, bool hasTexture);
|
||||
void setupAuxVertexLayout(bool hasColor, bool hasTexture, void * glPtr);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ namespace yg
|
|||
size_t indicesCount)
|
||||
{
|
||||
vertices->makeCurrent();
|
||||
Vertex::setupLayout();
|
||||
/// it's important to setupLayout after vertices->makeCurrent
|
||||
Vertex::setupLayout(vertices->glPtr());
|
||||
indices->makeCurrent();
|
||||
|
||||
texture->makeCurrent();
|
||||
|
@ -28,7 +29,7 @@ namespace yg
|
|||
GL_TRIANGLES,
|
||||
indicesCount,
|
||||
GL_UNSIGNED_SHORT,
|
||||
0));
|
||||
indices->glPtr()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,14 +32,18 @@ namespace yg
|
|||
indexBufferStack.pop_back();
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer() : m_size(0), m_gpuData(0)
|
||||
IndexBuffer::IndexBuffer(bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
{
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(size_t size) : m_size(0), m_gpuData(0)
|
||||
IndexBuffer::IndexBuffer(size_t size, bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
{
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
resize(size);
|
||||
}
|
||||
|
||||
|
@ -49,7 +53,13 @@ namespace yg
|
|||
{
|
||||
m_size = size;
|
||||
makeCurrent();
|
||||
OGLCHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
|
||||
if (m_useVA)
|
||||
{
|
||||
delete [] (unsigned char*) m_gpuData;
|
||||
m_gpuData = new unsigned char[size];
|
||||
}
|
||||
else
|
||||
OGLCHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,11 +70,15 @@ namespace yg
|
|||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
void * IndexBuffer::lock()
|
||||
{
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
|
||||
makeCurrent();
|
||||
|
||||
/// orphaning the old copy of the buffer data.
|
||||
|
@ -82,6 +96,9 @@ namespace yg
|
|||
|
||||
void IndexBuffer::unlock()
|
||||
{
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
ASSERT(m_gpuData != 0, ("IndexBuffer is not locked"));
|
||||
makeCurrent();
|
||||
#ifdef OMIM_GL_ES
|
||||
|
@ -94,9 +111,20 @@ namespace yg
|
|||
|
||||
void IndexBuffer::makeCurrent()
|
||||
{
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
if (m_id != current())
|
||||
OGLCHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_id));
|
||||
}
|
||||
|
||||
void * IndexBuffer::glPtr()
|
||||
{
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,12 @@ namespace yg
|
|||
unsigned int m_id;
|
||||
unsigned int m_size;
|
||||
void * m_gpuData;
|
||||
bool m_useVA;
|
||||
|
||||
public:
|
||||
|
||||
IndexBuffer();
|
||||
IndexBuffer(size_t size);
|
||||
IndexBuffer(bool useVA);
|
||||
IndexBuffer(size_t size, bool useVA);
|
||||
~IndexBuffer();
|
||||
|
||||
void resize(size_t size);
|
||||
|
@ -25,9 +26,12 @@ namespace yg
|
|||
void * lock();
|
||||
void unlock();
|
||||
|
||||
void * glPtr();
|
||||
|
||||
static void pushCurrent();
|
||||
static void popCurrent();
|
||||
static int current();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,26 +22,31 @@ namespace yg
|
|||
size_t blitVBSize, size_t blitIBSize, size_t blitStoragesCount,
|
||||
size_t texWidth, size_t texHeight, size_t texCount,
|
||||
char const * blocksFile, char const * whiteListFile, char const * blackListFile, size_t maxGlyphCacheSize,
|
||||
RtFormat fmt)
|
||||
RtFormat fmt,
|
||||
bool useVA)
|
||||
: m_textureWidth(texWidth), m_textureHeight(texHeight),
|
||||
m_vbSize(vbSize), m_ibSize(ibSize),
|
||||
m_smallVBSize(smallVBSize), m_smallIBSize(smallIBSize),
|
||||
m_blitVBSize(blitVBSize), m_blitIBSize(blitIBSize),
|
||||
m_glyphCache(GlyphCache::Params(blocksFile, whiteListFile, blackListFile, maxGlyphCacheSize)),
|
||||
m_format(fmt)
|
||||
m_format(fmt),
|
||||
m_useVA(useVA)
|
||||
{
|
||||
if (useVA)
|
||||
LOG(LINFO, ("buffer objects are unsupported. using client vertex array instead."));
|
||||
|
||||
for (size_t i = 0; i < storagesCount; ++i)
|
||||
m_storages.push_back(gl::Storage(vbSize, ibSize));
|
||||
m_storages.push_back(gl::Storage(vbSize, ibSize, m_useVA));
|
||||
|
||||
LOG(LINFO, ("allocating ", (vbSize + ibSize) * storagesCount, " bytes for main storage"));
|
||||
|
||||
for (size_t i = 0; i < smallStoragesCount; ++i)
|
||||
m_smallStorages.push_back(gl::Storage(smallVBSize, smallIBSize));
|
||||
m_smallStorages.push_back(gl::Storage(smallVBSize, smallIBSize, m_useVA));
|
||||
|
||||
LOG(LINFO, ("allocating ", (smallVBSize + smallIBSize) * smallStoragesCount, " bytes for small storage"));
|
||||
|
||||
for (size_t i = 0; i < blitStoragesCount; ++i)
|
||||
m_blitStorages.push_back(gl::Storage(blitVBSize, blitIBSize));
|
||||
m_blitStorages.push_back(gl::Storage(blitVBSize, blitIBSize, m_useVA));
|
||||
|
||||
LOG(LINFO, ("allocating ", (blitVBSize + blitIBSize) * blitStoragesCount, " bytes for blit storage"));
|
||||
|
||||
|
@ -227,11 +232,11 @@ namespace yg
|
|||
threads::MutexGuard guard(m_mutex);
|
||||
|
||||
for (list<gl::Storage>::iterator it = m_storages.begin(); it != m_storages.end(); ++it)
|
||||
*it = gl::Storage(m_vbSize, m_ibSize);
|
||||
*it = gl::Storage(m_vbSize, m_ibSize, m_useVA);
|
||||
for (list<gl::Storage>::iterator it = m_smallStorages.begin(); it != m_smallStorages.end(); ++it)
|
||||
*it = gl::Storage(m_smallVBSize, m_smallIBSize);
|
||||
*it = gl::Storage(m_smallVBSize, m_smallIBSize, m_useVA);
|
||||
for (list<gl::Storage>::iterator it = m_blitStorages.begin(); it != m_blitStorages.end(); ++it)
|
||||
*it = gl::Storage(m_blitVBSize, m_blitIBSize);
|
||||
*it = gl::Storage(m_blitVBSize, m_blitIBSize, m_useVA);
|
||||
|
||||
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_dynamicTextures.begin(); it != m_dynamicTextures.end(); ++it)
|
||||
*it = shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_textureWidth, m_textureHeight));
|
||||
|
|
|
@ -63,6 +63,8 @@ namespace yg
|
|||
|
||||
RtFormat m_format;
|
||||
|
||||
bool m_useVA;
|
||||
|
||||
public:
|
||||
|
||||
ResourceManager(size_t vbSize, size_t ibSize, size_t storagesCount,
|
||||
|
@ -70,7 +72,8 @@ namespace yg
|
|||
size_t blitVBSize, size_t blitIBSize, size_t blitStoragesCount,
|
||||
size_t texWidth, size_t texHeight, size_t texCount,
|
||||
char const * blocksFile, char const * whileListFile, char const * blackListFile, size_t maxGlyphCacheSize,
|
||||
RtFormat fmt);
|
||||
RtFormat fmt,
|
||||
bool useVA);
|
||||
|
||||
shared_ptr<gl::BaseTexture> const & getTexture(string const & fileName);
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace yg
|
|||
Storage::Storage()
|
||||
{}
|
||||
|
||||
Storage::Storage(size_t vbSize, size_t ibSize) :
|
||||
m_vertices(new VertexBuffer(vbSize)),
|
||||
m_indices(new IndexBuffer(ibSize))
|
||||
Storage::Storage(size_t vbSize, size_t ibSize, bool useVA) :
|
||||
m_vertices(new VertexBuffer(vbSize, useVA)),
|
||||
m_indices(new IndexBuffer(ibSize, useVA))
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace yg
|
|||
shared_ptr<IndexBuffer> m_indices;
|
||||
|
||||
Storage();
|
||||
Storage(size_t vbSize, size_t ibSize);
|
||||
Storage(size_t vbSize, size_t ibSize, bool useVA);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,14 +29,14 @@ namespace yg
|
|||
return *this;
|
||||
}
|
||||
|
||||
void Vertex::setupLayout()
|
||||
void Vertex::setupLayout(void * glPtr)
|
||||
{
|
||||
OGLCHECK(glDisableClientState(GL_COLOR_ARRAY));
|
||||
OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY));
|
||||
OGLCHECK(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)Vertex::vertexOffset));
|
||||
OGLCHECK(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::vertexOffset)));
|
||||
OGLCHECK(glEnable(GL_TEXTURE_2D));
|
||||
OGLCHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)Vertex::texCoordOffset));
|
||||
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::texCoordOffset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace yg
|
|||
Vertex(Vertex const & v);
|
||||
Vertex const & operator=(Vertex const & v);
|
||||
|
||||
static void setupLayout();
|
||||
static void setupLayout(void * glPtr);
|
||||
};
|
||||
|
||||
struct AuxVertex
|
||||
|
|
|
@ -32,14 +32,18 @@ namespace yg
|
|||
vertexBufferStack.pop_back();
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer() : m_size(0), m_gpuData(0)
|
||||
VertexBuffer::VertexBuffer(bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
{
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(size_t size) : m_size(0), m_gpuData(0)
|
||||
VertexBuffer::VertexBuffer(size_t size, bool useVA)
|
||||
: m_size(0), m_gpuData(0), m_useVA(useVA)
|
||||
{
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
if (!m_useVA)
|
||||
OGLCHECK(glGenBuffers(1, &m_id));
|
||||
resize(size);
|
||||
}
|
||||
|
||||
|
@ -49,7 +53,13 @@ namespace yg
|
|||
{
|
||||
m_size = size;
|
||||
makeCurrent();
|
||||
OGLCHECK(glBufferData(GL_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
|
||||
if (m_useVA)
|
||||
{
|
||||
delete [] (unsigned char*)m_gpuData;
|
||||
m_gpuData = new unsigned char [size];
|
||||
}
|
||||
else
|
||||
OGLCHECK(glBufferData(GL_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,11 +70,17 @@ namespace yg
|
|||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
if (m_useVA)
|
||||
delete [] (unsigned char*)m_gpuData;
|
||||
else
|
||||
OGLCHECK(glDeleteBuffers(1, &m_id));
|
||||
}
|
||||
|
||||
void * VertexBuffer::lock()
|
||||
{
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
|
||||
makeCurrent();
|
||||
|
||||
/// orphaning the old copy of the buffer data.
|
||||
|
@ -82,6 +98,9 @@ namespace yg
|
|||
|
||||
void VertexBuffer::unlock()
|
||||
{
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
ASSERT(m_gpuData != 0, ("VertexBuffer is not locked"));
|
||||
makeCurrent();
|
||||
#ifdef OMIM_GL_ES
|
||||
|
@ -92,8 +111,18 @@ namespace yg
|
|||
m_gpuData = 0;
|
||||
}
|
||||
|
||||
void * VertexBuffer::glPtr() const
|
||||
{
|
||||
if (m_useVA)
|
||||
return m_gpuData;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VertexBuffer::makeCurrent()
|
||||
{
|
||||
if (m_useVA)
|
||||
return;
|
||||
|
||||
if (m_id != current())
|
||||
OGLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_id));
|
||||
}
|
||||
|
|
|
@ -12,10 +12,13 @@ namespace yg
|
|||
unsigned int m_size;
|
||||
void * m_gpuData;
|
||||
|
||||
/// using VA instead of buffer objects on some old GPU's
|
||||
bool m_useVA;
|
||||
|
||||
public:
|
||||
|
||||
VertexBuffer();
|
||||
VertexBuffer(size_t size);
|
||||
VertexBuffer(bool useVA);
|
||||
VertexBuffer(size_t size, bool useVA);
|
||||
~VertexBuffer();
|
||||
|
||||
void resize(size_t size);
|
||||
|
@ -24,6 +27,7 @@ namespace yg
|
|||
void makeCurrent();
|
||||
void * lock();
|
||||
void unlock();
|
||||
void * glPtr() const;
|
||||
|
||||
static unsigned current();
|
||||
static void pushCurrent();
|
||||
|
|
Loading…
Add table
Reference in a new issue