Adds private EGL extension to create an EGLClientBuffer from a gralloc'd buffer. This lets you create a color EGLimage backed by gralloc, which is needed to support protected textures.
Bug: 22775237
Bug: 22855417
Change-Id: I8e03061d74a74a8fdd6524ffa97a6c75a6ced89c
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index b2abdb1..267f8af 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -598,6 +598,19 @@
#endif
#endif
+#ifndef EGL_ANDROID_create_native_client_buffer
+#define EGL_ANDROID_create_native_client_buffer 1
+#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143
+#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001
+#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_ANDROID 0x00000002
+#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_ANDROID 0x00000004
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer eglCreateNativeClientBufferANDROID (const EGLint *attrib_list);
+#else
+typedef EGLAPI EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROID) (const EGLint *attrib_list);
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 3f9e332..eb86860 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -31,7 +31,7 @@
EGL/Loader.cpp \
#
-LOCAL_SHARED_LIBRARIES += libcutils libutils liblog
+LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libui
LOCAL_MODULE:= libEGL
LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
LOCAL_SHARED_LIBRARIES += libdl
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 5bd7464..c7e2afb 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -33,6 +33,8 @@
#include <cutils/properties.h>
#include <cutils/memory.h>
+#include <ui/GraphicBuffer.h>
+
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
@@ -80,6 +82,7 @@
"EGL_KHR_get_all_proc_addresses "
"EGL_ANDROID_presentation_time "
"EGL_KHR_swap_buffers_with_damage "
+ "EGL_ANDROID_create_native_client_buffer "
;
extern char const * const gExtensionString =
"EGL_KHR_image " // mandatory
@@ -168,6 +171,10 @@
{ "eglSwapBuffersWithDamageKHR",
(__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
+ // EGL_ANDROID_native_client_buffer
+ { "eglCreateNativeClientBufferANDROID",
+ (__eglMustCastToProperFunctionPointerType)&eglCreateNativeClientBufferANDROID },
+
// EGL_KHR_partial_update
{ "eglSetDamageRegionKHR",
(__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
@@ -1770,6 +1777,97 @@
return EGL_TRUE;
}
+EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
+{
+ clearError();
+
+ int usage = 0;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t format = 0;
+ uint32_t red_size = 0;
+ uint32_t green_size = 0;
+ uint32_t blue_size = 0;
+ uint32_t alpha_size = 0;
+
+#define GET_POSITIVE_VALUE(case_name, target) \
+ case case_name: \
+ if (value > 0) { \
+ target = value; \
+ } else { \
+ return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); \
+ } \
+ break
+
+ if (attrib_list) {
+ while (*attrib_list != EGL_NONE) {
+ GLint attr = *attrib_list++;
+ GLint value = *attrib_list++;
+ switch (attr) {
+ GET_POSITIVE_VALUE(EGL_WIDTH, width);
+ GET_POSITIVE_VALUE(EGL_HEIGHT, height);
+ GET_POSITIVE_VALUE(EGL_RED_SIZE, red_size);
+ GET_POSITIVE_VALUE(EGL_GREEN_SIZE, green_size);
+ GET_POSITIVE_VALUE(EGL_BLUE_SIZE, blue_size);
+ GET_POSITIVE_VALUE(EGL_ALPHA_SIZE, alpha_size);
+ case EGL_NATIVE_BUFFER_USAGE_ANDROID:
+ if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
+ usage |= GRALLOC_USAGE_PROTECTED;
+ // If we are using QCOM then add in extra bits. This
+ // should be removed before launch. These correspond to:
+ // USAGE_PRIVATE_MM_HEAP | USAGE_PRIVATE_UNCACHED
+ usage |= 0x82000000;
+ }
+ if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_ANDROID) {
+ usage |= GRALLOC_USAGE_HW_RENDER;
+ }
+ if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_ANDROID) {
+ usage |= GRALLOC_USAGE_HW_TEXTURE;
+ }
+ // The buffer must be used for either a texture or a
+ // renderbuffer.
+ if ((value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_ANDROID) &&
+ (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_ANDROID)) {
+ return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
+ }
+ break;
+ default:
+ return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
+ }
+ }
+ }
+#undef GET_POSITIVE_VALUE
+
+ // Validate format.
+ if (red_size == 8 && green_size == 8 && blue_size == 8) {
+ if (alpha_size == 8) {
+ format = HAL_PIXEL_FORMAT_RGBA_8888;
+ } else {
+ format = HAL_PIXEL_FORMAT_RGB_888;
+ }
+ } else if (red_size == 5 && green_size == 6 && blue_size == 5 &&
+ alpha_size == 0) {
+ format == HAL_PIXEL_FORMAT_RGB_565;
+ } else {
+ ALOGE("Invalid native pixel format { r=%d, g=%d, b=%d, a=%d }",
+ red_size, green_size, blue_size, alpha_size);
+ return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
+ }
+
+ GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage);
+ const status_t err = gBuffer->initCheck();
+ if (err != NO_ERROR) {
+ ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
+ width, height, format, usage, err);
+ // Destroy the buffer.
+ sp<GraphicBuffer> holder(gBuffer);
+ return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
+ }
+ ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
+ gBuffer, width, height, format, usage);
+ return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
+}
+
// ----------------------------------------------------------------------------
// NVIDIA extensions
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index 498b2fc..2b56718 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -80,6 +80,7 @@
EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint)
EGL_ENTRY(EGLClientBuffer, eglGetRenderBufferANDROID, EGLDisplay, EGLSurface)
EGL_ENTRY(EGLint, eglDupNativeFenceFDANDROID, EGLDisplay, EGLSyncKHR)
+EGL_ENTRY(EGLClientBuffer, eglCreateNativeClientBufferANDROID, const EGLint *)
/* NVIDIA extensions */