Implement EGL_KHR_surfaceless_context for D3D, GL and NULL backends.

Skip all config attributes that have the value of EGL_DONT_CARE.  From the
EGL 1.5 spec: "If EGL_DONT_CARE is specified as an attribute value, then
the attribute will not be checked.".

BUG=angleproject:1651

Change-Id: I30c95a1970543fb6f1d4b02d2babf3df61cad543
Reviewed-on: https://chromium-review.googlesource.com/533937
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Config.cpp b/src/libANGLE/Config.cpp
index e70f8b7..5bbd112 100644
--- a/src/libANGLE/Config.cpp
+++ b/src/libANGLE/Config.cpp
@@ -218,6 +218,11 @@
             EGLAttrib attributeKey   = attribIter->first;
             EGLAttrib attributeValue = attribIter->second;
 
+            if (attributeValue == EGL_DONT_CARE)
+            {
+                continue;
+            }
+
             switch (attributeKey)
             {
               case EGL_BUFFER_SIZE:               match = config.bufferSize >= attributeValue;                        break;
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 3a0bc4e..f576cbf 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -1145,6 +1145,9 @@
 
     // getSyncValues requires direct composition.
     outExtensions->getSyncValues = outExtensions->directComposition;
+
+    // D3D11 can be used without a swap chain
+    outExtensions->surfacelessContext = true;
 }
 
 gl::Error Renderer11::flush()
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 8bc634e..22ff7d5 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -566,6 +566,9 @@
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
+
+    // D3D9 can be used without an output surface
+    outExtensions->surfacelessContext = true;
 }
 
 void Renderer9::startScene()
diff --git a/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp b/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
index 4846246..d8935f3 100644
--- a/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
+++ b/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
@@ -776,6 +776,8 @@
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
+
+    outExtensions->surfacelessContext = true;
 }
 
 void DisplayGLX::generateCaps(egl::Caps *outCaps) const
@@ -783,6 +785,13 @@
     outCaps->textureNPOT = true;
 }
 
+egl::Error DisplayGLX::makeCurrentSurfaceless(gl::Context *context)
+{
+    // Nothing to do because GLX always uses the same context and the previous surface can be left
+    // current.
+    return egl::NoError();
+}
+
 int DisplayGLX::getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const
 {
     int result;
diff --git a/src/libANGLE/renderer/gl/glx/DisplayGLX.h b/src/libANGLE/renderer/gl/glx/DisplayGLX.h
index cd542cc..9022ae1 100644
--- a/src/libANGLE/renderer/gl/glx/DisplayGLX.h
+++ b/src/libANGLE/renderer/gl/glx/DisplayGLX.h
@@ -97,6 +97,8 @@
     void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
     void generateCaps(egl::Caps *outCaps) const override;
 
+    egl::Error makeCurrentSurfaceless(gl::Context *context) override;
+
     int getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const;
     egl::Error createContextAttribs(glx::FBConfig,
                                     const Optional<gl::Version> &version,
diff --git a/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp b/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
index 4d71be8..69331d9 100644
--- a/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
+++ b/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
@@ -617,6 +617,8 @@
 
     // Contexts are virtualized so textures can be shared globally
     outExtensions->displayTextureShareGroup = true;
+
+    outExtensions->surfacelessContext = true;
 }
 
 void DisplayWGL::generateCaps(egl::Caps *outCaps) const
@@ -624,6 +626,13 @@
     outCaps->textureNPOT = true;
 }
 
+egl::Error DisplayWGL::makeCurrentSurfaceless(gl::Context *context)
+{
+    // Nothing to do because WGL always uses the same context and the previous surface can be left
+    // current.
+    return egl::NoError();
+}
+
 egl::Error DisplayWGL::waitClient() const
 {
     // Unimplemented as this is not needed for WGL
diff --git a/src/libANGLE/renderer/gl/wgl/DisplayWGL.h b/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
index 5ef41fd..e406d67 100644
--- a/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
+++ b/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
@@ -72,6 +72,8 @@
     void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
     void generateCaps(egl::Caps *outCaps) const override;
 
+    egl::Error makeCurrentSurfaceless(gl::Context *context) override;
+
     HGLRC initializeContextAttribs(const egl::AttributeMap &eglAttributes) const;
     HGLRC createContextAttribs(const gl::Version &version, int profileMask) const;
 
diff --git a/src/libANGLE/renderer/null/DisplayNULL.cpp b/src/libANGLE/renderer/null/DisplayNULL.cpp
index 61b3a8a..6642fa9 100644
--- a/src/libANGLE/renderer/null/DisplayNULL.cpp
+++ b/src/libANGLE/renderer/null/DisplayNULL.cpp
@@ -203,6 +203,7 @@
     outExtensions->createContextWebGLCompatibility    = true;
     outExtensions->createContextBindGeneratesResource = true;
     outExtensions->swapBuffersWithDamage              = true;
+    outExtensions->surfacelessContext                 = true;
 }
 
 void DisplayNULL::generateCaps(egl::Caps *outCaps) const