Initial work to connect gralloc to egl::Image

Change-Id: Ia11a9520bb6525dc367e0b2956850574b29e4796
Reviewed-on: https://swiftshader-review.googlesource.com/2900
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Android.mk b/src/Android.mk
index f31a1db..dbf2932 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -9,6 +9,7 @@
 	Common/CPUID.cpp \
 	Common/Configurator.cpp \
 	Common/DebugAndroid.cpp \
+	Common/GrallocAndroid.cpp \
 	Common/Half.cpp \
 	Common/Math.cpp \
 	Common/Memory.cpp \
@@ -65,6 +66,7 @@
 	Shader/VertexShader.cpp \
 
 LOCAL_SRC_FILES += \
+	OpenGL/common/AndroidCommon.cpp \
 	OpenGL/common/NameSpace.cpp \
 	OpenGL/common/Object.cpp \
 	OpenGL/common/MatrixStack.cpp \
diff --git a/src/Common/GrallocAndroid.cpp b/src/Common/GrallocAndroid.cpp
new file mode 100644
index 0000000..307a16f
--- /dev/null
+++ b/src/Common/GrallocAndroid.cpp
@@ -0,0 +1,31 @@
+#include "GrallocAndroid.hpp"
+
+#include <cutils/log.h>
+
+GrallocModule* GrallocModule::getInstance()
+{
+    static GrallocModule instance;
+    return &instance;
+}
+
+GrallocModule::GrallocModule()
+{
+    const hw_module_t* module;
+    hw_get_module("converting_gralloc", &module);
+    if (module)
+    {
+        m_supportsConversion = true;
+        ALOGI("Loaded converting gralloc");
+    }
+    else
+    {
+        m_supportsConversion = false;
+        ALOGE("Falling back to standard gralloc with reduced format support");
+        hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    }
+    if (!module)
+    {
+        ALOGE("Failed to load standard gralloc");
+    }
+    m_module = reinterpret_cast<const gralloc_module_t*>(module);
+}
diff --git a/src/Common/GrallocAndroid.hpp b/src/Common/GrallocAndroid.hpp
new file mode 100644
index 0000000..4714d36
--- /dev/null
+++ b/src/Common/GrallocAndroid.hpp
@@ -0,0 +1,27 @@
+#ifndef GRALLOC_ANDROID
+#define GRALLOC_ANDROID
+
+#include <hardware/gralloc.h>
+
+class GrallocModule
+{
+public:
+    static GrallocModule* getInstance();
+    bool supportsConversion() const { return m_supportsConversion; }
+    int lock(
+        buffer_handle_t handle, int usage,
+        int left, int top, int width, int height, void**vaddr) {
+        return m_module->lock(m_module, handle, 0, left, top, width, height, vaddr);
+    }
+
+    int unlock(buffer_handle_t handle) {
+        return m_module->unlock(m_module, handle);
+    }
+
+private:
+    GrallocModule();
+    bool m_supportsConversion;
+    const gralloc_module_t* m_module;
+};
+
+#endif  // GRALLOC_ANDROID
diff --git a/src/OpenGL/common/AndroidCommon.cpp b/src/OpenGL/common/AndroidCommon.cpp
new file mode 100644
index 0000000..3177141
--- /dev/null
+++ b/src/OpenGL/common/AndroidCommon.cpp
@@ -0,0 +1,125 @@
+#include <system/window.h>
+#include "GL/glcorearb.h"
+#include "GL/glext.h"
+#include "EGL/egl.h"
+
+#define GL_RGB565_OES                     0x8D62
+
+#include "AndroidCommon.hpp"
+
+#include "../../Common/DebugAndroid.hpp"
+#include "../../Common/GrallocAndroid.hpp"
+
+GLenum getColorFormatFromAndroid(int format)
+{
+    switch(format)
+    {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+            return GL_RGBA;
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return GL_RGB;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            return GL_RGB;
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            return GL_BGRA_EXT;
+        case HAL_PIXEL_FORMAT_RGB_565:
+#if LATER
+            if (GrallocModule::getInstance()->supportsConversion()) {
+                return GL_RGB565_OES;
+            } else {
+                UNIMPLEMENTED();
+                return GL_RGB565_OES;
+            }
+#else
+            return GL_RGB565_OES;
+#endif
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_Y8:
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+        default:
+            UNIMPLEMENTED();
+    }
+    return GL_RGBA;
+}
+
+// Used internally
+GLenum getPixelFormatFromAndroid(int format)
+{
+    switch(format)
+    {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+            return GL_UNSIGNED_BYTE;
+        case HAL_PIXEL_FORMAT_RGB_565:
+#if LATER
+            if (GrallocModule::getInstance()->supportsConversion()) {
+                return GL_UNSIGNED_SHORT_5_6_5;
+            } else {
+                UNIMPLEMENTED();
+                return GL_UNSIGNED_SHORT_5_6_5;
+            }
+#else
+            return GL_UNSIGNED_SHORT_5_6_5;
+#endif
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_Y8:
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+        default:
+            UNIMPLEMENTED();
+    }
+    return GL_UNSIGNED_BYTE;
+}
+
+// Used in V1 & V2 Context.cpp
+GLenum isSupportedAndroidBuffer(GLuint name)
+{
+    ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
+
+    if(!name)
+    {
+        ALOGE("%s called with name==NULL %s:%d", __FUNCTION__, __FILE__, __LINE__);
+        return EGL_BAD_PARAMETER;
+    }
+    if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+    {
+        ALOGE("%s: failed: bad magic", __FUNCTION__);
+        return EGL_BAD_PARAMETER;
+    }
+
+    if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))
+    {
+        ALOGE("%s: failed: bad size", __FUNCTION__ );
+        return EGL_BAD_PARAMETER;
+    }
+
+    switch(nativeBuffer->format)
+    {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            return EGL_SUCCESS;
+        case HAL_PIXEL_FORMAT_RGB_565:
+#if LATER
+            if (GrallocModule::getInstance()->supportsConversion()) {
+                return EGL_SUCCESS;
+            } else {
+                ALOGE("%s: failed: bad format", __FUNCTION__ );
+                return EGL_BAD_PARAMETER;
+            }
+#else
+            return EGL_SUCCESS;
+#endif
+        default:
+            ALOGE("%s: failed: bad format", __FUNCTION__ );
+            return EGL_BAD_PARAMETER;
+    }
+}
diff --git a/src/OpenGL/common/AndroidCommon.hpp b/src/OpenGL/common/AndroidCommon.hpp
index c0b831a..0d5f890 100644
--- a/src/OpenGL/common/AndroidCommon.hpp
+++ b/src/OpenGL/common/AndroidCommon.hpp
@@ -1,54 +1,30 @@
 #ifndef ANDROID_COMMON
 #define ANDROID_COMMON
 
-static inline GLenum getColorFormatFromAndroid(int format)
+// Used internally
+GLenum getColorFormatFromAndroid(int format);
+
+// Used internally
+GLenum getPixelFormatFromAndroid(int format);
+
+// Used in V1 & V2 Context.cpp
+GLenum isSupportedAndroidBuffer(GLuint name);
+
+// Used in V1 & V2 Context.cpp
+template <typename I> I* wrapAndroidNativeWindow(GLuint name)
 {
-    switch(format)
-    {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-            return GL_RGBA;
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-            return GL_RGB;
-        case HAL_PIXEL_FORMAT_RGB_888:
-            return GL_RGB;
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            return GL_BGRA_EXT;
-        case HAL_PIXEL_FORMAT_RGB_565:
-            return GL_RGB565_OES;
-        case HAL_PIXEL_FORMAT_YV12:
-        case HAL_PIXEL_FORMAT_Y8:
-        case HAL_PIXEL_FORMAT_Y16:
-        case HAL_PIXEL_FORMAT_RAW_SENSOR:
-        case HAL_PIXEL_FORMAT_BLOB:
-        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-        case HAL_PIXEL_FORMAT_YCbCr_420_888:
-        default:
-            UNIMPLEMENTED();
-    }
-    return GL_RGBA;
+    ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
+    ALOGV("%s: wrapping %p", __FUNCTION__, nativeBuffer);
+    nativeBuffer->common.incRef(&nativeBuffer->common);
+
+    GLenum format = getColorFormatFromAndroid(nativeBuffer->format);
+    GLenum type = getPixelFormatFromAndroid(nativeBuffer->format);
+
+    I *image = new I(0, nativeBuffer->width, nativeBuffer->height, format, type);
+    image->setNativeBuffer(nativeBuffer);
+    image->markShared();
+
+    return image;
 }
 
-static inline GLenum getPixelFormatFromAndroid(int format)
-{
-    switch(format)
-    {
-        case HAL_PIXEL_FORMAT_RGBA_8888:
-        case HAL_PIXEL_FORMAT_RGBX_8888:
-        case HAL_PIXEL_FORMAT_RGB_888:
-        case HAL_PIXEL_FORMAT_BGRA_8888:
-            return GL_UNSIGNED_BYTE;
-        case HAL_PIXEL_FORMAT_RGB_565:
-            return GL_UNSIGNED_SHORT_5_6_5;
-        case HAL_PIXEL_FORMAT_YV12:
-        case HAL_PIXEL_FORMAT_Y8:
-        case HAL_PIXEL_FORMAT_Y16:
-        case HAL_PIXEL_FORMAT_RAW_SENSOR:
-        case HAL_PIXEL_FORMAT_BLOB:
-        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-        case HAL_PIXEL_FORMAT_YCbCr_420_888:
-        default:
-            UNIMPLEMENTED();
-    }
-    return GL_UNSIGNED_BYTE;
-}
 #endif  // ANDROID_COMMON
diff --git a/src/OpenGL/libEGL/Image.hpp b/src/OpenGL/libEGL/Image.hpp
index 0b48442..f96402c 100644
--- a/src/OpenGL/libEGL/Image.hpp
+++ b/src/OpenGL/libEGL/Image.hpp
@@ -6,6 +6,7 @@
 #if defined(__ANDROID__)

 #include <hardware/gralloc.h>

 #include <system/window.h>

+#include "../../Common/GrallocAndroid.hpp"

 #endif

 

 #ifdef __ANDROID__

@@ -35,7 +36,6 @@
 

 		#if defined(__ANDROID__)

 			nativeBuffer = 0;

-			gralloc = 0;

 		#endif

 	}

 

@@ -47,7 +47,6 @@
 

 		#if defined(__ANDROID__)

 			nativeBuffer = 0;

-			gralloc = 0;

 		#endif

 	}

 

@@ -185,35 +184,19 @@
 

 	#if defined(__ANDROID__)

 	ANativeWindowBuffer *nativeBuffer;

-	gralloc_module_t const *gralloc;

-

-	void initGralloc()

-	{

-		hw_module_t const *module;

-		hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);

-		gralloc = reinterpret_cast<gralloc_module_t const*>(module);

-	}

 

 	void* lockNativeBuffer(int usage)

 	{

-		if(!gralloc)

-		{

-			initGralloc();

-		}

-

 		void *buffer = 0;

-		gralloc->lock(gralloc, nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);

+		GrallocModule::getInstance()->lock(

+			nativeBuffer->handle, usage, 0, 0,

+			nativeBuffer->width, nativeBuffer->height, &buffer);

 		return buffer;

 	}

 

 	void unlockNativeBuffer()

 	{

-		if(!gralloc)

-		{

-			initGralloc();

-		}

-

-		gralloc->unlock(gralloc, nativeBuffer->handle);

+		GrallocModule::getInstance()->unlock(nativeBuffer->handle);

 	}

 	#endif

 };

diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index d683338..403cb20 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -2639,27 +2639,7 @@
     #if defined(__ANDROID__)

     else if(target == EGL_NATIVE_BUFFER_ANDROID)

     {

-        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);

-

-        if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        switch(nativeBuffer->format)

-		{

-        case HAL_PIXEL_FORMAT_RGBA_8888:

-        case HAL_PIXEL_FORMAT_RGBX_8888:

-        case HAL_PIXEL_FORMAT_RGB_565:

-            break;

-        default:

-            return EGL_BAD_PARAMETER;

-        }

+		return isSupportedAndroidBuffer(name);

     }

     #endif

     else UNREACHABLE();

@@ -2684,17 +2664,7 @@
     #if defined(__ANDROID__)

     else if(target == EGL_NATIVE_BUFFER_ANDROID)

     {

-        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);

-        nativeBuffer->common.incRef(&nativeBuffer->common);

-

-        GLenum format = getColorFormatFromAndroid(nativeBuffer->format);

-        GLenum type = getPixelFormatFromAndroid(nativeBuffer->format);

-

-        es1::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type);

-        image->setNativeBuffer(nativeBuffer);

-        image->markShared();

-

-        return image;

+		return wrapAndroidNativeWindow<es1::Image>(name);

     }

     #endif

     else UNREACHABLE();

diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index cc7bb01..0666ac3 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -3967,27 +3967,7 @@
     #if defined(__ANDROID__)

     else if(target == EGL_NATIVE_BUFFER_ANDROID)

     {

-        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);

-        

-		if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))

-        {

-            return EGL_BAD_PARAMETER;

-        }

-

-        switch(nativeBuffer->format)

-		{

-        case HAL_PIXEL_FORMAT_RGBA_8888:

-        case HAL_PIXEL_FORMAT_RGBX_8888:

-        case HAL_PIXEL_FORMAT_RGB_565:

-            break;

-        default:

-            return EGL_BAD_PARAMETER;

-        }

+		return isSupportedAndroidBuffer(name);

     }

     #endif

     else UNREACHABLE();

@@ -4025,17 +4005,7 @@
     #if defined(__ANDROID__)

     else if(target == EGL_NATIVE_BUFFER_ANDROID)

     {

-        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);

-        nativeBuffer->common.incRef(&nativeBuffer->common);

-

-        GLenum format = getColorFormatFromAndroid(nativeBuffer->format);

-        GLenum type = getPixelFormatFromAndroid(nativeBuffer->format);

-

-        es2::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type);

-        image->setNativeBuffer(nativeBuffer);

-        image->markShared();

-

-        return image;

+		return wrapAndroidNativeWindow<es2::Image>(name);

     }

     #endif

     else UNREACHABLE();