summaryrefslogtreecommitdiff
path: root/src/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c49
-rw-r--r--src/egl/drivers/dri2/platform_x11.c1
-rw-r--r--src/egl/main/eglapi.c108
-rw-r--r--src/egl/main/eglapi.h6
-rw-r--r--src/egl/main/egldisplay.h2
-rw-r--r--src/egl/main/eglfallbacks.c3
-rw-r--r--src/egl/main/eglimage.c10
-rw-r--r--src/egl/main/eglimage.h3
8 files changed, 181 insertions, 1 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index a428f284ae7..0f9ab7391cd 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1328,16 +1328,25 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
GLuint renderbuffer = (GLuint) (uintptr_t) buffer;
+ _EGLImageAttribs attrs;
__DRIimage *dri_image;
+ unsigned dri_use = 0;
if (renderbuffer == 0) {
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
}
+ if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS)
+ return EGL_NO_IMAGE_KHR;
+
+ if (attrs.ExplicitFlush)
+ dri_use |= __DRI_IMAGE_USE_FLUSH_EXTERNAL;
+
dri_image =
dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context,
- renderbuffer, NULL);
+ renderbuffer, dri_use,
+ NULL);
return dri2_create_image_from_dri(disp, dri_image);
}
@@ -1462,6 +1471,36 @@ dri2_get_sync_values_chromium(_EGLDisplay *dpy, _EGLSurface *surf,
}
/**
+ * TODO - where to query if external device requires a resolve? We should
+ * not have only vendor specific but a SoC specific solution here.
+ */
+static EGLBoolean
+dri2_image_flush_external(_EGLDisplay *dpy, _EGLImage *img,
+ const EGLAttribKHR *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+ return dri2_dpy->image->flushImageExternal(dri2_ctx->dri_context,
+ dri2_img->dri_image);
+}
+
+static EGLBoolean
+dri2_image_invalidate_external(_EGLDisplay *dpy, _EGLImage *img,
+ const EGLAttribKHR *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+ return dri2_dpy->image->invalidateImageExternal(dri2_ctx->dri_context,
+ dri2_img->dri_image);
+}
+
+/**
* Set the error code after a call to
* dri2_egl_image::dri_image::createImageFromTexture.
*/
@@ -1509,6 +1548,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
GLuint depth;
GLenum gl_target;
unsigned error;
+ unsigned dri_use = 0;
if (texture == 0) {
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
@@ -1553,6 +1593,9 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
return EGL_NO_IMAGE_KHR;
}
+ if (attrs.ExplicitFlush)
+ dri_use |= __DRI_IMAGE_USE_FLUSH_EXTERNAL;
+
dri2_img->dri_image =
dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context,
gl_target,
@@ -1560,6 +1603,7 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
depth,
attrs.GLTextureLevel,
&error,
+ dri_use,
dri2_img);
dri2_create_image_khr_texture_error(error);
@@ -2284,6 +2328,9 @@ _eglBuiltInDriverDRI2(const char *args)
#endif
dri2_drv->base.API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
+ dri2_drv->base.API.ImageFlushExternalEXT = dri2_image_flush_external;
+ dri2_drv->base.API.ImageInvalidateExternalEXT = dri2_image_invalidate_external;
+
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index ddb3b54e843..db28bb00f9b 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -1302,6 +1302,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
disp->Extensions.NV_post_sub_buffer = EGL_TRUE;
disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
+ disp->Extensions.EXT_image_flush_external = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index ea2ee734a21..d9243686fee 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -425,6 +425,8 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(NV_post_sub_buffer);
_EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
+
+ _EGL_CHECK_EXTENSION(EXT_image_flush_external);
#undef _EGL_CHECK_EXTENSION
}
@@ -1148,6 +1150,18 @@ eglGetError(void)
return e;
}
+/**
+ * Forward declarations for functions not yet in EGL headers.
+ */
+EGLBoolean
+eglImageFlushExternalEXT(EGLDisplay dpy,
+ EGLImageKHR image,
+ const EGLAttribKHR *attrib_list);
+
+EGLBoolean
+eglImageInvalidateExternalEXT(EGLDisplay dpy,
+ EGLImageKHR image,
+ const EGLAttribKHR *attrib_list);
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname)
@@ -1245,6 +1259,8 @@ eglGetProcAddress(const char *procname)
{ "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
{ "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
#endif
+ { "eglImageFlushExternalEXT", (_EGLProc) eglImageFlushExternalEXT },
+ { "eglImageInvalidateExternalEXT", (_EGLProc) eglImageInvalidateExternalEXT },
{ NULL, NULL }
};
EGLint i;
@@ -1933,6 +1949,98 @@ eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
RETURN_EGL_EVAL(disp, ret);
}
+/* TODO - to be removed when we have real enum values in place. */
+enum flush_external_args
+{
+ EGL_IMAGE_EXTERNAL_DISPLAY_EXT = 42,
+ EGL_IMAGE_EXTERNAL_VIDEO_ENCODER_EXT,
+ EGL_IMAGE_EXTERNAL_VIDEO_DECODER_EXT,
+ EGL_IMAGE_EXTERNAL_CAMERA_EXT,
+ EGL_IMAGE_EXTERNAL_CPU_EXT,
+ EGL_IMAGE_EXTERNAL_TARGET_EXT,
+ EGL_IMAGE_EXTERNAL_SOURCE_EXT,
+};
+
+static EGLBoolean
+validate_flush_external_attribs(const EGLAttribKHR *attrib_list,
+ const EGLAttribKHR func_attrib)
+{
+ for (const EGLAttribKHR *attr = attrib_list; *attr != EGL_NONE; attr += 2) {
+
+ /* Must be EXTERNAL_SOURCE or EXTERNAL_TARGET */
+ if (attr[0] != func_attrib)
+ return EGL_FALSE;
+
+ switch (attr[1]) {
+ case EGL_IMAGE_EXTERNAL_DISPLAY_EXT:
+ case EGL_IMAGE_EXTERNAL_VIDEO_ENCODER_EXT:
+ if (func_attrib != EGL_IMAGE_EXTERNAL_TARGET_EXT)
+ return EGL_FALSE;
+ break;
+ case EGL_IMAGE_EXTERNAL_VIDEO_DECODER_EXT:
+ case EGL_IMAGE_EXTERNAL_CAMERA_EXT:
+ if (func_attrib != EGL_IMAGE_EXTERNAL_SOURCE_EXT)
+ return EGL_FALSE;
+ break;
+ case EGL_IMAGE_EXTERNAL_CPU_EXT:
+ break;
+ default:
+ return EGL_FALSE;
+ }
+ }
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY
+eglImageFlushExternalEXT(EGLDisplay dpy, EGLImageKHR image,
+ const EGLAttribKHR *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ _EGLImage *img;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ img = _eglLookupImage(image, disp);
+
+ if (!img)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ if (!validate_flush_external_attribs(attrib_list,
+ EGL_IMAGE_EXTERNAL_TARGET_EXT))
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.ImageFlushExternalEXT(disp, img, attrib_list);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
+EGLBoolean EGLAPIENTRY
+eglImageInvalidateExternalEXT(EGLDisplay dpy, EGLImageKHR image,
+ const EGLAttribKHR *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLDriver *drv;
+ _EGLImage *img;
+ EGLBoolean ret;
+
+ _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
+
+ img = _eglLookupImage(image, disp);
+
+ if (!img)
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ if (!validate_flush_external_attribs(attrib_list,
+ EGL_IMAGE_EXTERNAL_SOURCE_EXT))
+ RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
+
+ ret = drv->API.ImageInvalidateExternalEXT(disp, img, attrib_list);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+
#ifdef EGL_MESA_image_dma_buf_export
EGLBoolean EGLAPIENTRY
eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImageKHR image,
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index eb5f58e6fa9..6c2da597af4 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -145,6 +145,9 @@ typedef EGLBoolean (*ExportDMABUFImageQueryMESA_t)(_EGLDriver *drv, _EGLDisplay
typedef EGLBoolean (*ExportDMABUFImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *fds, EGLint *strides, EGLint *offsets);
#endif
+typedef EGLBoolean (*ImageFlushExternalEXT_t) (_EGLDisplay *dpy, _EGLImage *image, const EGLAttribKHR *attrib_list);
+typedef EGLBoolean (*ImageInvalidateExternalEXT_t) (_EGLDisplay *dpy, _EGLImage *image, const EGLAttribKHR *attrib_list);
+
/**
* The API dispatcher jumps through these functions
*/
@@ -236,6 +239,9 @@ struct _egl_api
ExportDMABUFImageQueryMESA_t ExportDMABUFImageQueryMESA;
ExportDMABUFImageMESA_t ExportDMABUFImageMESA;
#endif
+
+ ImageFlushExternalEXT_t ImageFlushExternalEXT;
+ ImageInvalidateExternalEXT_t ImageInvalidateExternalEXT;
};
#endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 4a1fb4ab15c..dc424ac3ff3 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -125,6 +125,8 @@ struct _egl_extensions
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean MESA_image_dma_buf_export;
+
+ EGLBoolean EXT_image_flush_external;
};
diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c
index c108ca7687c..42ae5b1eb44 100644
--- a/src/egl/main/eglfallbacks.c
+++ b/src/egl/main/eglfallbacks.c
@@ -123,4 +123,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
drv->API.ExportDMABUFImageQueryMESA = NULL;
drv->API.ExportDMABUFImageMESA = NULL;
#endif
+
+ drv->API.ImageFlushExternalEXT = (ImageFlushExternalEXT_t) _eglReturnFalse;
+ drv->API.ImageInvalidateExternalEXT = (ImageInvalidateExternalEXT_t) _eglReturnFalse;
}
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 818b5975cd2..634475b9267 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -33,6 +33,7 @@
#include "eglimage.h"
#include "egllog.h"
+#define EGL_IMAGE_EXTERNAL_FLUSH_EXT 42
/**
* Parse the list of image attributes and return the proper error code.
@@ -169,6 +170,15 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
}
break;
+ /* EGL_EXT_image_flush_external */
+ case EGL_IMAGE_EXTERNAL_FLUSH_EXT:
+ if (val != EGL_FALSE && val != EGL_TRUE) {
+ err = EGL_BAD_ATTRIBUTE;
+ } else {
+ attrs->ExplicitFlush = val;
+ }
+ break;
+
default:
/* unknown attrs are ignored */
break;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 50a87a18890..d479fa76b74 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -69,6 +69,9 @@ struct _egl_image_attribs
struct _egl_image_attrib_int DMABufSampleRangeHint;
struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
struct _egl_image_attrib_int DMABufChromaVerticalSiting;
+
+ /* EGL_EXT_image_flush_external */
+ EGLBoolean ExplicitFlush;
};
/**