Implement the egl and gl layers of EGL Image.

Add end2end tests and unittests.

BUG=angleproject:970

Change-Id: I13fc501b24c3f11bfedc810c1ff80fcf1318877c
Reviewed-on: https://chromium-review.googlesource.com/287343
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 0761d93..60d1a9f 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -10,10 +10,12 @@
 #include "libANGLE/validationES2.h"
 #include "libANGLE/validationES3.h"
 #include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
 #include "libANGLE/Texture.h"
 #include "libANGLE/Framebuffer.h"
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/formatutils.h"
+#include "libANGLE/Image.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/Program.h"
 #include "libANGLE/Uniform.h"
@@ -2006,7 +2008,43 @@
                                         GLenum target,
                                         egl::Image *image)
 {
-    UNIMPLEMENTED();
+    if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    switch (target)
+    {
+        case GL_TEXTURE_2D:
+            break;
+
+        default:
+            context->recordError(Error(GL_INVALID_ENUM, "invalid texture target."));
+            return false;
+    }
+
+    if (!display->isValidImage(image))
+    {
+        context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid."));
+        return false;
+    }
+
+    if (image->getSamples() > 0)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION,
+                                   "cannot create a 2D texture from a multisampled EGL image."));
+        return false;
+    }
+
+    const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat());
+    if (!textureCaps.texturable)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION,
+                                   "EGL image internal format is not supported as a texture."));
+        return false;
+    }
+
     return true;
 }
 
@@ -2015,7 +2053,36 @@
                                                   GLenum target,
                                                   egl::Image *image)
 {
-    UNIMPLEMENTED();
+    if (!context->getExtensions().eglImage)
+    {
+        context->recordError(Error(GL_INVALID_OPERATION));
+        return false;
+    }
+
+    switch (target)
+    {
+        case GL_RENDERBUFFER:
+            break;
+
+        default:
+            context->recordError(Error(GL_INVALID_ENUM, "invalid renderbuffer target."));
+            return false;
+    }
+
+    if (!display->isValidImage(image))
+    {
+        context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid."));
+        return false;
+    }
+
+    const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat());
+    if (!textureCaps.renderable)
+    {
+        context->recordError(Error(
+            GL_INVALID_OPERATION, "EGL image internal format is not supported as a renderbuffer."));
+        return false;
+    }
+
     return true;
 }
 }