Add extension to create software device.

Add an extension so that users can receive a device that renders in software. Currently this is done by loading a swiftshader dll.

BUG=
TEST=

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

git-svn-id: https://angleproject.googlecode.com/svn/trunk@705 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/common/version.h b/src/common/version.h
index b984318..fe089ad 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 0
 #define MINOR_VERSION 0
 #define BUILD_VERSION 0
-#define BUILD_REVISION 704
+#define BUILD_REVISION 705
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index ac51af2..ea5fcc3 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -11,6 +11,7 @@
 #include "libEGL/Display.h"
 
 #include <algorithm>
+#include <map>
 #include <vector>
 
 #include "common/debug.h"
@@ -31,7 +32,41 @@
 
 namespace egl
 {
-Display::Display(HDC deviceContext) : mDc(deviceContext)
+namespace
+{
+    typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; 
+    DisplayMap displays;
+}
+
+egl::Display *Display::getDisplay(EGLNativeDisplayType displayId)
+{
+    if (displays.find(displayId) != displays.end())
+    {
+        return displays[displayId];
+    }
+
+    egl::Display *display = NULL;
+
+    if (displayId == EGL_DEFAULT_DISPLAY)
+    {
+        display = new egl::Display(displayId, (HDC)NULL, false);
+    }
+    else if (displayId == EGL_SOFTWARE_DISPLAY_ANGLE)
+    {
+        display = new egl::Display(displayId, (HDC)NULL, true);
+    }
+    else
+    {
+        // FIXME: Check if displayId is a valid display device context
+
+        display = new egl::Display(displayId, (HDC)displayId, false);
+    }
+
+    displays[displayId] = display;
+    return display;
+}
+
+Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software) : mDc(deviceContext)
 {
     mD3d9Module = NULL;
     
@@ -51,11 +86,20 @@
 
     mMinSwapInterval = 1;
     mMaxSwapInterval = 1;
+    mSoftwareDevice = software;
+    mDisplayId = displayId;
 }
 
 Display::~Display()
 {
     terminate();
+
+    DisplayMap::iterator thisDisplay = displays.find(mDisplayId);
+
+    if (thisDisplay != displays.end())
+    {
+      displays.erase(thisDisplay);
+    }
 }
 
 bool Display::initialize()
@@ -65,7 +109,14 @@
         return true;
     }
 
-    mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
+    if (mSoftwareDevice)
+    {
+      mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+    } 
+    else
+    {
+      mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
+    }
     if (mD3d9Module == NULL)
     {
         terminate();
@@ -856,6 +907,12 @@
 void Display::initExtensionString()
 {
     mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+    HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+
+    if (swiftShader)
+    {
+      mExtensionString += "EGL_ANGLE_software_display ";
+    }
 
     if (isD3d9ExDevice()) {
         mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index 86de5cd..3c6ac88 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -29,8 +29,6 @@
 class Display
 {
   public:
-    Display(HDC deviceContext);
-
     ~Display();
 
     bool initialize();
@@ -39,6 +37,8 @@
     virtual void startScene();
     virtual void endScene();
 
+    static egl::Display *getDisplay(EGLNativeDisplayType displayId);
+
     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
 
@@ -79,8 +79,11 @@
   private:
     DISALLOW_COPY_AND_ASSIGN(Display);
 
+    Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software);
+
     D3DPRESENT_PARAMETERS getDefaultPresentParameters();
 
+    EGLNativeDisplayType mDisplayId;
     const HDC mDc;
 
     HMODULE mD3d9Module;
@@ -98,6 +101,7 @@
     bool mSceneStarted;
     EGLint mMaxSwapInterval;
     EGLint mMinSwapInterval;
+    bool mSoftwareDevice;
     
     typedef std::set<Surface*> SurfaceSet;
     SurfaceSet mSurfaceSet;
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 8689a4e..89986e6 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -99,18 +99,7 @@
 
     try
     {
-        // FIXME: Return the same EGLDisplay handle when display_id already created a display
-
-        if (display_id == EGL_DEFAULT_DISPLAY)
-        {
-            return new egl::Display((HDC)NULL);
-        }
-        else
-        {
-            // FIXME: Check if display_id is a valid display device context
-
-            return new egl::Display((HDC)display_id);
-        }
+        return egl::Display::getDisplay(display_id);
     }
     catch(std::bad_alloc&)
     {