diff options
Diffstat (limited to 'src/egl')
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 49 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11.c | 1 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 108 | ||||
-rw-r--r-- | src/egl/main/eglapi.h | 6 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 2 | ||||
-rw-r--r-- | src/egl/main/eglfallbacks.c | 3 | ||||
-rw-r--r-- | src/egl/main/eglimage.c | 10 | ||||
-rw-r--r-- | src/egl/main/eglimage.h | 3 |
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; }; /** |