Expose extension for obtaining an EGLClientBuffer from an AHardwareBuffer

Bug: 34050596
Test: deqp test checks for extension
Change-Id: I0da1173688cd27b8dd9e907e535100b9a0605290
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 6485ae5..5a81f7c 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -619,6 +619,16 @@
 #endif
 #endif
 
+#ifndef EGL_ANDROID_get_native_client_buffer
+#define EGL_ANDROID_get_native_client_buffer 1
+struct AHardwareBuffer;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const AHardwareBuffer *buffer);
+#else
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const AHardwareBuffer *buffer);
+#endif
+#endif
+
 #ifndef EGL_ANDROID_front_buffer_auto_refresh
 #define EGL_ANDROID_front_buffer_auto_refresh 1
 #define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 2d02b72..2422177 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -27,6 +27,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include <android/hardware_buffer.h>
 #include <cutils/atomic.h>
 #include <cutils/compiler.h>
 #include <cutils/memory.h>
@@ -87,6 +88,7 @@
         "EGL_ANDROID_presentation_time "
         "EGL_KHR_swap_buffers_with_damage "
         "EGL_ANDROID_create_native_client_buffer "
+        "EGL_ANDROID_get_native_client_buffer "
         "EGL_ANDROID_front_buffer_auto_refresh "
 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
         "EGL_ANDROID_get_frame_timestamps "
@@ -182,10 +184,14 @@
     { "eglSwapBuffersWithDamageKHR",
             (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
 
-    // EGL_ANDROID_native_client_buffer
+    // EGL_ANDROID_create_native_client_buffer
     { "eglCreateNativeClientBufferANDROID",
             (__eglMustCastToProperFunctionPointerType)&eglCreateNativeClientBufferANDROID },
 
+    // EGL_ANDROID_get_native_client_buffer
+    { "eglGetNativeClientBufferANDROID",
+            (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
+
     // EGL_KHR_partial_update
     { "eglSetDamageRegionKHR",
             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
@@ -1982,6 +1988,17 @@
     return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
 }
 
+EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) {
+    clearError();
+
+    if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
+
+    // FIXME: remove this dangerous reinterpret_cast.
+    const GraphicBuffer* graphicBuffer =
+            reinterpret_cast<const GraphicBuffer*>(buffer);
+    return static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer());
+}
+
 // ----------------------------------------------------------------------------
 // NVIDIA extensions
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index 2b56718..b587a16 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -81,6 +81,7 @@
 EGL_ENTRY(EGLClientBuffer, eglGetRenderBufferANDROID, EGLDisplay, EGLSurface)
 EGL_ENTRY(EGLint, eglDupNativeFenceFDANDROID, EGLDisplay, EGLSyncKHR)
 EGL_ENTRY(EGLClientBuffer, eglCreateNativeClientBufferANDROID, const EGLint *)
+EGL_ENTRY(EGLClientBuffer, eglGetNativeClientBufferANDROID, const AHardwareBuffer *)
 
 /* NVIDIA extensions */
 
diff --git a/opengl/libs/libEGL.map.txt b/opengl/libs/libEGL.map.txt
index c8b83f5..89269a0 100644
--- a/opengl/libs/libEGL.map.txt
+++ b/opengl/libs/libEGL.map.txt
@@ -28,6 +28,7 @@
     eglGetCurrentSurface;
     eglGetDisplay;
     eglGetError;
+    eglGetNativeClientBufferANDROID; # introduced=26
     eglGetProcAddress;
     eglGetStreamFileDescriptorKHR; # introduced=23
     eglGetSyncAttribKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
diff --git a/opengl/specs/EGL_ANDROID_get_native_client_buffer.txt b/opengl/specs/EGL_ANDROID_get_native_client_buffer.txt
new file mode 100644
index 0000000..de012a0
--- /dev/null
+++ b/opengl/specs/EGL_ANDROID_get_native_client_buffer.txt
@@ -0,0 +1,96 @@
+Name
+
+    ANDROID_get_native_client_buffer
+
+Name Strings
+
+    EGL_ANDROID_get_native_client_buffer
+
+Contributors
+
+    Craig Donner
+
+Contact
+
+    Craig Donner, Google Inc. (cdonner 'at' google.com)
+
+Status
+
+    Draft
+
+Version
+
+    Version 1.0, January 27, 2017
+
+Number
+
+    EGL Extension #XXX
+
+Dependencies
+
+    Requires EGL 1.2.
+
+    EGL_ANDROID_image_native_buffer and EGL_KHR_image_base are required.
+
+    This extension is written against the wording of the EGL 1.2
+    Specification as modified by EGL_KHR_image_base and
+    EGL_ANDROID_image_native_buffer.
+
+Overview
+
+    This extension allows creating an EGLClientBuffer from an Android
+    AHardwareBuffer object which can be later used to create an EGLImage.
+
+New Types
+
+struct AHardwareBuffer
+
+New Procedures and Functions
+
+EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer)
+
+New Tokens
+
+    None
+
+Changes to Chapter 3 of the EGL 1.2 Specification (EGL Functions and Errors)
+
+    Add the following to section 2.5.1 "EGLImage Specification" (as modified by
+    the EGL_KHR_image_base and EGL_ANDROID_image_native_buffer specifications),
+    below the description of eglCreateImageKHR:
+
+   "The command
+
+        EGLClientBuffer eglGeteNativeClientBufferANDROID(
+                                AHardwareBuffer *buffer)
+
+    may be used to create an EGLClientBuffer from an AHardwareBuffer object.
+    EGL implementations must guarantee that the lifetime of the returned
+    EGLClientBuffer is at least as long as the EGLImage(s) it is bound to,
+    following the lifetime semantics described below in section 2.5.2; the
+    EGLClientBuffer must be destroyed no earlier than when all of its associated
+    EGLImages are destroyed by eglDestroyImageKHR.
+
+    Errors
+
+        If eglGeteNativeClientBufferANDROID fails, NULL will be returned, no
+        memory will be allocated, and the following error will be generated:
+
+       * If the value of buffer is NULL, the error EGL_BAD_PARAMETER is
+         generated.
+
+Issues
+
+    1. Should this extension define what particular AHardwareBuffer formats EGL
+    implementations are required to support?
+
+    RESOLVED: No.
+
+    The set of valid formats is implementation-specific and may depend on
+    additional EGL extensions. The particular valid combinations for a given
+    Android version and implementation should be documented by that version.
+
+Revision History
+
+#1 (Craig Donner, January 27, 2017)
+    - Initial draft.