Move the vertex declaration cache to a helper class.

TRAC #14871
Signed-off-by: Daniel Koch
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@613 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 67895db..268a47a 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -33,8 +33,7 @@
 
 namespace gl
 {
-Context::Context(const egl::Config *config, const gl::Context *shareContext)
-    : mConfig(config), mMaxLru(0)
+Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
 {
     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
@@ -154,12 +153,6 @@
     mMaxSupportedSamples = 0;
     mMaskedClearSavedState = NULL;
     markAllStateDirty();
-
-    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
-    {
-        mVertexDeclCache[i].vertexDeclaration = NULL;
-        mVertexDeclCache[i].lruCount = 0;
-    }
 }
 
 Context::~Context()
@@ -225,14 +218,6 @@
     }
 
     mResourceManager->release();
-
-    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
-    {
-        if (mVertexDeclCache[i].vertexDeclaration)
-        {
-            mVertexDeclCache[i].vertexDeclaration->Release();
-        }
-    }
 }
 
 void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
@@ -1977,64 +1962,7 @@
         return err;
     }
 
-    IDirect3DDevice9 *device = getDevice();
-    Program *program = getCurrentProgram();
-
-    D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
-    D3DVERTEXELEMENT9 *element = &elements[0];
-
-    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-    {
-        if (attributes[i].active)
-        {
-            device->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
-
-            element->Stream = i;
-            element->Offset = 0;
-            element->Type = attributes[i].type;
-            element->Method = D3DDECLMETHOD_DEFAULT;
-            element->Usage = D3DDECLUSAGE_TEXCOORD;
-            element->UsageIndex = program->getSemanticIndex(i);
-            element++;
-        }
-    }
-
-    static const D3DVERTEXELEMENT9 end = D3DDECL_END();
-    *(element++) = end;
-
-    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
-    {
-        VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
-        if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
-        {
-            entry->lruCount = ++mMaxLru;
-            device->SetVertexDeclaration(entry->vertexDeclaration);
-            return GL_NO_ERROR;
-        }
-    }
-
-    VertexDeclCacheEntry *lastCache = mVertexDeclCache;
-
-    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
-    {
-        if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
-        {
-            lastCache = &mVertexDeclCache[i];
-        }
-    }
-
-    if (lastCache->vertexDeclaration != NULL)
-    {
-        lastCache->vertexDeclaration->Release();
-        lastCache->vertexDeclaration = NULL;
-    }
-
-    memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
-    device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
-    device->SetVertexDeclaration(lastCache->vertexDeclaration);
-    lastCache->lruCount = ++mMaxLru;
-
-    return GL_NO_ERROR;
+    return mVertexDeclarationCache.applyDeclaration(attributes, getCurrentProgram());
 }
 
 // Applies the indices and element array bindings to the Direct3D 9 device
@@ -3614,6 +3542,88 @@
     }
 }
 
+VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
+{
+    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        mVertexDeclCache[i].vertexDeclaration = NULL;
+        mVertexDeclCache[i].lruCount = 0;
+    }
+}
+
+VertexDeclarationCache::~VertexDeclarationCache()
+{
+    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        if (mVertexDeclCache[i].vertexDeclaration)
+        {
+            mVertexDeclCache[i].vertexDeclaration->Release();
+        }
+    }
+}
+
+GLenum VertexDeclarationCache::applyDeclaration(TranslatedAttribute attributes[], Program *program)
+{
+    IDirect3DDevice9 *device = getDevice();
+
+    D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
+    D3DVERTEXELEMENT9 *element = &elements[0];
+
+    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (attributes[i].active)
+        {
+            device->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
+
+            element->Stream = i;
+            element->Offset = 0;
+            element->Type = attributes[i].type;
+            element->Method = D3DDECLMETHOD_DEFAULT;
+            element->Usage = D3DDECLUSAGE_TEXCOORD;
+            element->UsageIndex = program->getSemanticIndex(i);
+            element++;
+        }
+    }
+
+    static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+    *(element++) = end;
+
+    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
+        if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
+        {
+            entry->lruCount = ++mMaxLru;
+            device->SetVertexDeclaration(entry->vertexDeclaration);
+            
+            return GL_NO_ERROR;
+        }
+    }
+
+    VertexDeclCacheEntry *lastCache = mVertexDeclCache;
+
+    for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
+        {
+            lastCache = &mVertexDeclCache[i];
+        }
+    }
+
+    if (lastCache->vertexDeclaration != NULL)
+    {
+        lastCache->vertexDeclaration->Release();
+        lastCache->vertexDeclaration = NULL;
+    }
+
+    memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
+    device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
+    device->SetVertexDeclaration(lastCache->vertexDeclaration);
+    lastCache->lruCount = ++mMaxLru;
+
+    return GL_NO_ERROR;
+}
+
 }
 
 extern "C"