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