Implement eglCreateImage and eglDestroyImage
Refactor existing KHR functions so that they become common code
that both the KHR and core functions call.
Test: cts-tradefed run commandAndExit cts -m CtsDeqpTestCases --module-arg 'CtsDeqpTestCases:include-filter:dEQP-EGL.*'
Bug: 80297325
Change-Id: I6cdac9adc7b2d0b9f2adef91db099a0e6dc92e57
(cherry picked from commit 63c29fe127c2bbf5f598a24b38e667539dda0449)
(cherry picked from commit fda88bed5923f146eb428a2dffdb44993d6f43d7)
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index e3c708d..3a7979c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -352,6 +352,14 @@
return cnx->platform.eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
}
+EGLImage eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
+ const EGLAttrib* attrib_list) {
+ clearError();
+
+ egl_connection_t* const cnx = &gEGLImpl;
+ return cnx->platform.eglCreateImage(dpy, ctx, target, buffer, attrib_list);
+}
+
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) {
clearError();
@@ -359,6 +367,17 @@
return cnx->platform.eglDestroyImageKHR(dpy, img);
}
+EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImageKHR img) {
+ clearError();
+
+ egl_connection_t* const cnx = &gEGLImpl;
+ return cnx->platform.eglDestroyImage(dpy, img);
+}
+
+// ----------------------------------------------------------------------------
+// EGL_EGLEXT_VERSION 5
+// ----------------------------------------------------------------------------
+
EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
clearError();
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index b587a16..35c2ecb 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -44,6 +44,10 @@
/* EGL 1.4 */
+/* EGL 1.5 */
+EGL_ENTRY(EGLImage, eglCreateImage, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLAttrib *)
+EGL_ENTRY(EGLBoolean, eglDestroyImage, EGLDisplay, EGLImage)
+
/* EGL_EGLEXT_VERSION 3 */
EGL_ENTRY(EGLBoolean, eglLockSurfaceKHR, EGLDisplay, EGLSurface, const EGLint *)
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index 0d69a65..6ef0082 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -598,6 +598,16 @@
return true;
}
+// Note: This only works for existing GLenum's that are all 32bits.
+// If you have 64bit attributes (e.g. pointers) you shouldn't be calling this.
+void convertAttribs(const EGLAttrib* attribList, std::vector<EGLint>& newList) {
+ for (const EGLAttrib* attr = attribList; attr && attr[0] != EGL_NONE; attr += 2) {
+ newList.push_back(static_cast<EGLint>(attr[0]));
+ newList.push_back(static_cast<EGLint>(attr[1]));
+ }
+ newList.push_back(EGL_NONE);
+}
+
// Gets the native pixel format corrsponding to the passed EGLConfig.
void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
android_pixel_format* format) {
@@ -1641,39 +1651,90 @@
return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
}
-EGLImageKHR eglCreateImageKHRImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attrib_list)
-{
+// Note: EGLImageKHR and EGLImage are the same thing so no need
+// to templatize that.
+template <typename AttrType, typename FuncType>
+EGLImageKHR eglCreateImageTmpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const AttrType* attrib_list,
+ FuncType eglCreateImageFunc) {
const egl_display_ptr dp = validate_display(dpy);
if (!dp) return EGL_NO_IMAGE_KHR;
ContextRef _c(dp.get(), ctx);
- egl_context_t * const c = _c.get();
+ egl_context_t* const c = _c.get();
EGLImageKHR result = EGL_NO_IMAGE_KHR;
egl_connection_t* const cnx = &gEGLImpl;
- if (cnx->dso && cnx->egl.eglCreateImageKHR) {
- result = cnx->egl.eglCreateImageKHR(
- dp->disp.dpy,
- c ? c->context : EGL_NO_CONTEXT,
- target, buffer, attrib_list);
+ if (cnx->dso && eglCreateImageFunc) {
+ result = eglCreateImageFunc(dp->disp.dpy, c ? c->context : EGL_NO_CONTEXT, target, buffer,
+ attrib_list);
}
return result;
}
-EGLBoolean eglDestroyImageKHRImpl(EGLDisplay dpy, EGLImageKHR img)
-{
+typedef EGLImage(EGLAPIENTRYP PFNEGLCREATEIMAGE)(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib* attrib_list);
+
+EGLImageKHR eglCreateImageKHRImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint* attrib_list) {
+ return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
+ attrib_list,
+ gEGLImpl.egl.eglCreateImageKHR);
+}
+
+EGLImage eglCreateImageImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
+ const EGLAttrib* attrib_list) {
+ egl_connection_t* const cnx = &gEGLImpl;
+ if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
+ if (cnx->egl.eglCreateImage) {
+ return eglCreateImageTmpl<EGLAttrib, PFNEGLCREATEIMAGE>(dpy, ctx, target, buffer,
+ attrib_list,
+ cnx->egl.eglCreateImage);
+ }
+ // driver doesn't support native function, return EGL_BAD_DISPLAY
+ ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateImage");
+ return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE);
+ }
+
+ std::vector<EGLint> convertedAttribs;
+ convertAttribs(attrib_list, convertedAttribs);
+ return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
+ convertedAttribs.data(),
+ gEGLImpl.egl.eglCreateImageKHR);
+}
+
+EGLBoolean eglDestroyImageTmpl(EGLDisplay dpy, EGLImageKHR img,
+ PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc) {
const egl_display_ptr dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
EGLBoolean result = EGL_FALSE;
egl_connection_t* const cnx = &gEGLImpl;
- if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
- result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
+ if (cnx->dso && destroyImageFunc) {
+ result = destroyImageFunc(dp->disp.dpy, img);
}
return result;
}
+EGLBoolean eglDestroyImageKHRImpl(EGLDisplay dpy, EGLImageKHR img) {
+ return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
+}
+
+EGLBoolean eglDestroyImageImpl(EGLDisplay dpy, EGLImageKHR img) {
+ egl_connection_t* const cnx = &gEGLImpl;
+ if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
+ if (cnx->egl.eglDestroyImage) {
+ return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImage);
+ }
+ // driver doesn't support native function, return EGL_BAD_DISPLAY
+ ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroyImage");
+ return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
+}
+
// ----------------------------------------------------------------------------
// EGL_EGLEXT_VERSION 5
// ----------------------------------------------------------------------------
@@ -2371,6 +2432,7 @@
};
static const implementation_map_t sPlatformImplMap[] = {
+ // clang-format off
{ "eglGetDisplay", (EGLFuncPointer)&eglGetDisplayImpl },
{ "eglInitialize", (EGLFuncPointer)&eglInitializeImpl },
{ "eglTerminate", (EGLFuncPointer)&eglTerminateImpl },
@@ -2412,6 +2474,8 @@
{ "eglUnlockSurfaceKHR", (EGLFuncPointer)&eglUnlockSurfaceKHRImpl },
{ "eglCreateImageKHR", (EGLFuncPointer)&eglCreateImageKHRImpl },
{ "eglDestroyImageKHR", (EGLFuncPointer)&eglDestroyImageKHRImpl },
+ { "eglCreateImage", (EGLFuncPointer)&eglCreateImageImpl },
+ { "eglDestroyImage", (EGLFuncPointer)&eglDestroyImageImpl },
{ "eglCreateSyncKHR", (EGLFuncPointer)&eglCreateSyncKHRImpl },
{ "eglDestroySyncKHR", (EGLFuncPointer)&eglDestroySyncKHRImpl },
{ "eglSignalSyncKHR", (EGLFuncPointer)&eglSignalSyncKHRImpl },
@@ -2447,6 +2511,7 @@
{ "glGetFloatv", (EGLFuncPointer)&glGetFloatvImpl },
{ "glGetIntegerv", (EGLFuncPointer)&glGetIntegervImpl },
{ "glGetInteger64v", (EGLFuncPointer)&glGetInteger64vImpl },
+ // clang-format on
};
EGLFuncPointer FindPlatformImplAddr(const char* name)
diff --git a/opengl/libs/platform_entries.in b/opengl/libs/platform_entries.in
index b28f6cc..6f087fd 100644
--- a/opengl/libs/platform_entries.in
+++ b/opengl/libs/platform_entries.in
@@ -37,6 +37,8 @@
EGL_ENTRY(EGLSurface, eglCreatePbufferFromClientBuffer, EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*)
EGL_ENTRY(EGLBoolean, eglLockSurfaceKHR, EGLDisplay, EGLSurface, const EGLint*)
EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface)
+EGL_ENTRY(EGLImage, eglCreateImage, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLAttrib*)
+EGL_ENTRY(EGLBoolean, eglDestroyImage, EGLDisplay, EGLImage)
EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*)
EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR)
EGL_ENTRY(EGLSyncKHR, eglCreateSyncKHR, EGLDisplay, EGLenum, const EGLint*)