For VAOs, track and deduplicate redundant chunks

* This is really a spot optimisation but I have a feeling it might be
  useful for more programs.
* If a program uses a single VAO and updates the attrib pointers/enables
  and disables them, then this will prevent an unbounded number of chunks
  building up pointlessly while READING and pushing into the record.
* A 'better' fix for this would be to gather pointer/enabled state as
  initial contents and not tracking any of this except for in CAPFRAME,
  but that isn't happening at the moment.
This commit is contained in:
Baldur Karlsson
2014-06-27 13:13:46 +01:00
parent e5664a0838
commit 5cb6edffb8
3 changed files with 51 additions and 4 deletions
+14
View File
@@ -139,6 +139,20 @@ struct ResourceRecord
ResourceId GetResourceID() const { return ResID; }
void RemoveChunk(Chunk *chunk)
{
LockChunks();
for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it)
{
if(it->second == chunk)
{
m_Chunks.erase(it);
break;
}
}
UnlockChunks();
}
void AddChunk(Chunk *chunk, int32_t ID = 0)
{
LockChunks();
+5
View File
@@ -101,6 +101,8 @@ struct GLResourceRecord : public ResourceRecord
usage(eGL_UNKNOWN_ENUM)
{
RDCEraseEl(ShadowPtr);
RDCEraseEl(ptrchunks);
RDCEraseEl(enabledchunks);
}
~GLResourceRecord()
@@ -154,6 +156,9 @@ struct GLResourceRecord : public ResourceRecord
{
return ShadowPtr[p];
}
Chunk *ptrchunks[12];
Chunk *enabledchunks[12];
private:
byte *ShadowPtr[2];
@@ -1120,9 +1120,16 @@ void WrappedOpenGL::glVertexAttribPointer(GLuint index, GLint size, GLenum type,
Serialise_glVertexAttribPointer(index, size, type, normalized, stride, pointer);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
r->AddChunk(scope.Get());
{
r->RemoveChunk(r->ptrchunks[index]);
delete r->ptrchunks[index];
Chunk *newchunk = r->ptrchunks[index] = scope.Get();
r->AddChunk(newchunk);
}
}
}
@@ -1166,9 +1173,16 @@ void WrappedOpenGL::glVertexAttribIPointer(GLuint index, GLint size, GLenum type
Serialise_glVertexAttribIPointer(index, size, type, stride, pointer);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
r->AddChunk(scope.Get());
{
r->RemoveChunk(r->ptrchunks[index]);
delete r->ptrchunks[index];
Chunk *newchunk = r->ptrchunks[index] = scope.Get();
r->AddChunk(newchunk);
}
}
}
@@ -1207,9 +1221,16 @@ void WrappedOpenGL::glEnableVertexAttribArray(GLuint index)
Serialise_glEnableVertexAttribArray(index);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
r->AddChunk(scope.Get());
{
r->RemoveChunk(r->enabledchunks[index]);
delete r->enabledchunks[index];
Chunk *newchunk = r->enabledchunks[index] = scope.Get();
r->AddChunk(newchunk);
}
}
}
@@ -1247,9 +1268,16 @@ void WrappedOpenGL::glDisableVertexAttribArray(GLuint index)
Serialise_glDisableVertexAttribArray(index);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
r->AddChunk(scope.Get());
{
r->RemoveChunk(r->enabledchunks[index]);
delete r->enabledchunks[index];
Chunk *newchunk = r->enabledchunks[index] = scope.Get();
r->AddChunk(newchunk);
}
}
}