Implement EGL_ANDROID_image_native_buffer.

BUG=angleproject:2508

Change-Id: I8ef2ce8320edeb336727905055f47bb299dec2ea
Reviewed-on: https://chromium-review.googlesource.com/c/1238886
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Image.cpp b/src/libANGLE/Image.cpp
index 2753f2f..5cbdf5a 100644
--- a/src/libANGLE/Image.cpp
+++ b/src/libANGLE/Image.cpp
@@ -25,7 +25,7 @@
 {
 gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs)
 {
-    if (eglTarget == EGL_GL_RENDERBUFFER)
+    if (!IsTextureTarget(eglTarget))
     {
         return gl::ImageIndex();
     }
@@ -131,6 +131,76 @@
     return mTargetOf->isRenderable(context);
 }
 
+ExternalImageSibling::ExternalImageSibling(rx::EGLImplFactory *factory,
+                                           const gl::Context *context,
+                                           EGLenum target,
+                                           EGLClientBuffer buffer,
+                                           const AttributeMap &attribs)
+    : mImplementation(factory->createExternalImageSibling(context, target, buffer, attribs))
+{
+}
+
+gl::Extents ExternalImageSibling::getAttachmentSize(const gl::ImageIndex &imageIndex) const
+{
+    return mImplementation->getSize();
+}
+
+gl::Format ExternalImageSibling::getAttachmentFormat(GLenum binding,
+                                                     const gl::ImageIndex &imageIndex) const
+{
+    return mImplementation->getFormat();
+}
+
+GLsizei ExternalImageSibling::getAttachmentSamples(const gl::ImageIndex &imageIndex) const
+{
+    return mImplementation->getSamples();
+}
+
+bool ExternalImageSibling::isRenderable(const gl::Context *context,
+                                        GLenum binding,
+                                        const gl::ImageIndex &imageIndex) const
+{
+    return mImplementation->isRenderable(context);
+}
+
+bool ExternalImageSibling::isTextureable(const gl::Context *context) const
+{
+    return mImplementation->isTexturable(context);
+}
+
+void ExternalImageSibling::onAttach(const gl::Context *context)
+{
+}
+
+void ExternalImageSibling::onDetach(const gl::Context *context)
+{
+}
+
+GLuint ExternalImageSibling::getId() const
+{
+    UNREACHABLE();
+    return 0;
+}
+
+gl::InitState ExternalImageSibling::initState(const gl::ImageIndex &imageIndex) const
+{
+    return gl::InitState::Initialized;
+}
+
+void ExternalImageSibling::setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState)
+{
+}
+
+rx::ExternalImageSiblingImpl *ExternalImageSibling::getImplementation() const
+{
+    return mImplementation.get();
+}
+
+rx::FramebufferAttachmentObjectImpl *ExternalImageSibling::getAttachmentImpl() const
+{
+    return mImplementation.get();
+}
+
 ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
     : label(nullptr),
       imageIndex(GetImageIndex(target, attribs)),
@@ -172,6 +242,13 @@
     if (mState.source != nullptr)
     {
         mState.source->removeImageSource(this);
+
+        // If the source is an external object, delete it
+        if (IsExternalImageTarget(mState.sourceType))
+        {
+            delete mState.source;
+        }
+
         mState.source = nullptr;
     }
 }
@@ -205,6 +282,9 @@
 
     if (mState.source == sibling)
     {
+        // The external source of an image cannot be redefined so it cannot be orpahend.
+        ASSERT(!IsExternalImageTarget(mState.sourceType));
+
         // If the sibling is the source, it cannot be a target.
         ASSERT(mState.targets.find(sibling) == mState.targets.end());
         mState.source = nullptr;
@@ -231,11 +311,16 @@
         return mState.format.info->textureAttachmentSupport(context->getClientVersion(),
                                                             context->getExtensions());
     }
-    if (IsRenderbufferTarget(mState.sourceType))
+    else if (IsRenderbufferTarget(mState.sourceType))
     {
         return mState.format.info->renderbufferSupport(context->getClientVersion(),
                                                        context->getExtensions());
     }
+    else if (IsExternalImageTarget(mState.sourceType))
+    {
+        ASSERT(mState.source != nullptr);
+        return mState.source->isRenderable(context, GL_NONE, gl::ImageIndex());
+    }
 
     UNREACHABLE();
     return false;
@@ -248,10 +333,15 @@
         return mState.format.info->textureSupport(context->getClientVersion(),
                                                   context->getExtensions());
     }
-    if (IsRenderbufferTarget(mState.sourceType))
+    else if (IsRenderbufferTarget(mState.sourceType))
     {
         return true;
     }
+    else if (IsExternalImageTarget(mState.sourceType))
+    {
+        ASSERT(mState.source != nullptr);
+        return rx::GetAs<ExternalImageSibling>(mState.source)->isTextureable(context);
+    }
 
     UNREACHABLE();
     return false;