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();