Avoid resending lots of D3D state

This change uses trivial caching to determines whether to reset shaders, the viewport, and the currently set vertex declaration. It also caches the render target desc to avoid rereading that. Serial numbers are added to vertex and index buffers, so resending those can be avoided.

These changes can give a big speedup (30% has been measured) on simple content, particularly when used directly or through pepper/native client.

BUG=
TEST=bunch of pages using webgl

Review URL: http://codereview.appspot.com/4964057

git-svn-id: https://angleproject.googlecode.com/svn/trunk@743 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/VertexDataManager.cpp b/src/libGLESv2/VertexDataManager.cpp
index b5626fa..d61968d 100644
--- a/src/libGLESv2/VertexDataManager.cpp
+++ b/src/libGLESv2/VertexDataManager.cpp
@@ -25,6 +25,7 @@
 
 namespace gl
 {
+unsigned int VertexBuffer::mCurrentSerial = 1;
 
 VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
 {
@@ -234,6 +235,7 @@
                 }
 
                 translated[i].vertexBuffer = vertexBuffer->getBuffer();
+                translated[i].serial = vertexBuffer->getSerial();
                 translated[i].type = converter.d3dDeclType;
                 translated[i].stride = converter.outputElementSize;
                 translated[i].offset = streamOffset;
@@ -248,6 +250,7 @@
                 }
 
                 translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
+                translated[i].serial = mCurrentValueBuffer[i]->getSerial();
 
                 translated[i].type = D3DDECLTYPE_FLOAT4;
                 translated[i].stride = 0;
@@ -521,6 +524,7 @@
     {
         D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
         HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
+        mSerial = issueSerial();
         
         if (FAILED(result))
         {
@@ -550,6 +554,16 @@
     return mVertexBuffer;
 }
 
+unsigned int VertexBuffer::getSerial() const
+{
+    return mSerial;
+}
+
+unsigned int VertexBuffer::issueSerial()
+{
+    return mCurrentSerial++;
+}
+
 ConstantVertexBuffer::ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w) : VertexBuffer(device, 4 * sizeof(float), D3DUSAGE_WRITEONLY)
 {
     void *buffer = NULL;
@@ -640,6 +654,7 @@
 
         D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
         HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
+        mSerial = issueSerial();
     
         if (FAILED(result))
         {
@@ -702,7 +717,8 @@
     {
         D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
         HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
-    
+        mSerial = issueSerial();
+
         if (FAILED(result))
         {
             ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);