diff options
author | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-02 18:31:49 +0200 |
---|---|---|
committer | Christoph Bumiller <e0425955@student.tuwien.ac.at> | 2010-09-02 18:31:49 +0200 |
commit | 222d2f2ac2c7d93cbc0643082c78278ad2c8cfce (patch) | |
tree | b79152c238022b2a901201c22e5809ac520732bf /src/egl | |
parent | 443abc80db9e1a288ce770e76cccd43664348098 (diff) | |
parent | e73c5501b2fe20290d1b691c85a5d82ac3a0431c (diff) |
Merge remote branch 'origin/master' into nv50-compiler
Conflicts:
src/gallium/drivers/nv50/nv50_program.c
Diffstat (limited to 'src/egl')
-rw-r--r-- | src/egl/docs/EGL_MESA_screen_surface | 2 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 223 | ||||
-rw-r--r-- | src/egl/main/Makefile | 6 | ||||
-rw-r--r-- | src/egl/main/SConscript | 4 | ||||
-rw-r--r-- | src/egl/main/egl.def | 35 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 189 | ||||
-rw-r--r-- | src/egl/main/eglapi.h | 28 | ||||
-rw-r--r-- | src/egl/main/eglconfig.c | 7 | ||||
-rw-r--r-- | src/egl/main/eglcontext.c | 20 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 8 | ||||
-rw-r--r-- | src/egl/main/egldriver.c | 9 | ||||
-rw-r--r-- | src/egl/main/eglmisc.c | 4 | ||||
-rw-r--r-- | src/egl/main/eglsync.c | 128 | ||||
-rw-r--r-- | src/egl/main/eglsync.h | 120 | ||||
-rw-r--r-- | src/egl/main/egltypedefs.h | 2 |
15 files changed, 769 insertions, 16 deletions
diff --git a/src/egl/docs/EGL_MESA_screen_surface b/src/egl/docs/EGL_MESA_screen_surface index 6beb4ce88e..698a240578 100644 --- a/src/egl/docs/EGL_MESA_screen_surface +++ b/src/egl/docs/EGL_MESA_screen_surface @@ -14,7 +14,7 @@ Contact Status - Preliminary - totally subject to change. + Obsolete. Version diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index efb93bcf06..2b78bcc763 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -836,6 +836,7 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp, goto cleanup_configs; } + disp->Extensions.MESA_drm_image = EGL_TRUE; disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_image_pixmap = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; @@ -994,6 +995,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp, for (i = 0; dri2_dpy->driver_configs[i]; i++) dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0); + disp->Extensions.MESA_drm_image = EGL_TRUE; disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; @@ -1621,6 +1623,96 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, } static _EGLImage * +dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_image *dri2_img; + EGLint width, height, format, name, stride, pitch, i, err; + + name = (EGLint) buffer; + + err = EGL_SUCCESS; + width = 0; + height = 0; + format = 0; + stride = 0; + + for (i = 0; attr_list[i] != EGL_NONE; i++) { + EGLint attr = attr_list[i++]; + EGLint val = attr_list[i]; + + switch (attr) { + case EGL_WIDTH: + width = val; + break; + case EGL_HEIGHT: + height = val; + break; + case EGL_DRM_BUFFER_FORMAT_MESA: + format = val; + break; + case EGL_DRM_BUFFER_STRIDE_MESA: + stride = val; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr); + return NULL; + } + } + + if (width <= 0 || height <= 0 || stride <= 0) { + _eglError(EGL_BAD_PARAMETER, + "bad width, height or stride"); + return NULL; + } + + switch (format) { + case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: + format = __DRI_IMAGE_FORMAT_ARGB8888; + pitch = stride; + break; + default: + _eglError(EGL_BAD_PARAMETER, + "dri2_create_image_khr: unsupported pixmap depth"); + return NULL; + } + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_mesa_drm"); + return NULL; + } + + if (!_eglInitImage(&dri2_img->base, disp, attr_list)) { + free(dri2_img); + return NULL; + } + + dri2_img->dri_image = + dri2_dpy->image->createImageFromName(dri2_ctx->dri_context, + width, + height, + format, + name, + pitch, + dri2_img); + if (dri2_img->dri_image == NULL) { + free(dri2_img); + _eglError(EGL_BAD_ALLOC, "dri2_create_image_mesa_drm"); + return NULL; + } + + return &dri2_img->base; +} + +static _EGLImage * dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) @@ -1630,6 +1722,8 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list); case EGL_GL_RENDERBUFFER_KHR: return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); + case EGL_DRM_BUFFER_MESA: + return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); default: _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); return EGL_NO_IMAGE_KHR; @@ -1648,6 +1742,133 @@ dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image) return EGL_TRUE; } +static _EGLImage * +dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, + const EGLint *attr_list) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_image *dri2_img; + int width, height, format, i; + unsigned int use, dri_use, valid_mask; + EGLint err = EGL_SUCCESS; + + dri2_img = malloc(sizeof *dri2_img); + if (!dri2_img) { + _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); + return EGL_NO_IMAGE_KHR; + } + + if (!attr_list) { + err = EGL_BAD_PARAMETER; + goto cleanup_img; + } + + if (!_eglInitImage(&dri2_img->base, disp, attr_list)) { + err = EGL_BAD_PARAMETER; + goto cleanup_img; + } + + width = 0; + height = 0; + format = 0; + use = 0; + for (i = 0; attr_list[i] != EGL_NONE; i++) { + EGLint attr = attr_list[i++]; + EGLint val = attr_list[i]; + + switch (attr) { + case EGL_WIDTH: + width = val; + break; + case EGL_HEIGHT: + height = val; + break; + case EGL_DRM_BUFFER_FORMAT_MESA: + format = val; + break; + case EGL_DRM_BUFFER_USE_MESA: + use = val; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr); + goto cleanup_img; + } + } + + if (width <= 0 || height <= 0) { + _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", width, height); + goto cleanup_img; + } + + switch (format) { + case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: + format = __DRI_IMAGE_FORMAT_ARGB8888; + break; + default: + _eglLog(_EGL_WARNING, "bad image format value 0x%04x", format); + goto cleanup_img; + } + + valid_mask = + EGL_DRM_BUFFER_USE_SCANOUT_MESA | + EGL_DRM_BUFFER_USE_SHARE_MESA; + if (use & ~valid_mask) { + _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", use & ~valid_mask); + goto cleanup_img; + } + + dri_use = 0; + if (use & EGL_DRM_BUFFER_USE_SHARE_MESA) + dri_use |= __DRI_IMAGE_USE_SHARE; + if (use & EGL_DRM_BUFFER_USE_SCANOUT_MESA) + dri_use |= __DRI_IMAGE_USE_SCANOUT; + + dri2_img->dri_image = + dri2_dpy->image->createImage(dri2_dpy->dri_screen, + width, height, format, dri_use, dri2_img); + if (dri2_img->dri_image == NULL) { + err = EGL_BAD_ALLOC; + goto cleanup_img; + } + + return &dri2_img->base; + + cleanup_img: + free(dri2_img); + _eglError(err, "dri2_create_drm_image_mesa"); + + return EGL_NO_IMAGE_KHR; +} + +static EGLBoolean +dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, + EGLint *name, EGLint *handle, EGLint *stride) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_image *dri2_img = dri2_egl_image(img); + + if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, + __DRI_IMAGE_ATTRIB_NAME, name)) { + _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); + return EGL_FALSE; + } + + if (handle) + dri2_dpy->image->queryImage(dri2_img->dri_image, + __DRI_IMAGE_ATTRIB_HANDLE, handle); + + if (stride) + dri2_dpy->image->queryImage(dri2_img->dri_image, + __DRI_IMAGE_ATTRIB_STRIDE, stride); + + return EGL_TRUE; +} + /** * This is the main entrypoint into the driver, called by libEGL. * Create a new _EGLDriver object and init its dispatch table. @@ -1681,6 +1902,8 @@ _eglMain(const char *args) dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr; dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr; dri2_drv->base.API.SwapBuffersRegionNOK = dri2_swap_buffers_region; + dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa; + dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa; dri2_drv->base.Name = "DRI2"; dri2_drv->base.Unload = dri2_unload; diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 41d301fc14..d92fbf6d9a 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -26,7 +26,8 @@ HEADERS = \ eglmutex.h \ eglscreen.h \ eglstring.h \ - eglsurface.h + eglsurface.h \ + eglsync.h SOURCES = \ eglapi.c \ @@ -44,7 +45,8 @@ SOURCES = \ eglmode.c \ eglscreen.c \ eglstring.c \ - eglsurface.c + eglsurface.c \ + eglsync.c OBJECTS = $(SOURCES:.c=.o) diff --git a/src/egl/main/SConscript b/src/egl/main/SConscript index 3d7ae3a8e4..06846475ba 100644 --- a/src/egl/main/SConscript +++ b/src/egl/main/SConscript @@ -12,6 +12,7 @@ if env['platform'] != 'winddk': '_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_WINDOWS', '_EGL_DRIVER_SEARCH_DIR=\\"\\"', '_EGL_OS_WINDOWS', + '_EGL_GET_CORE_ADDRESSES', 'KHRONOS_DLL_EXPORTS', ]) @@ -36,11 +37,12 @@ if env['platform'] != 'winddk': 'eglscreen.c', 'eglstring.c', 'eglsurface.c', + 'eglsync.c', ] egl = env.SharedLibrary( target = 'libEGL', - source = egl_sources, + source = egl_sources + ['egl.def'], ) env.InstallSharedLibrary(egl, version=(1, 4, 0)) diff --git a/src/egl/main/egl.def b/src/egl/main/egl.def new file mode 100644 index 0000000000..0cfe920e0e --- /dev/null +++ b/src/egl/main/egl.def @@ -0,0 +1,35 @@ +EXPORTS + eglBindAPI + eglBindTexImage + eglChooseConfig + eglCopyBuffers + eglCreateContext + eglCreatePbufferFromClientBuffer + eglCreatePbufferSurface + eglCreatePixmapSurface + eglCreateWindowSurface + eglDestroyContext + eglDestroySurface + eglGetConfigAttrib + eglGetConfigs + eglGetCurrentContext + eglGetCurrentDisplay + eglGetCurrentSurface + eglGetDisplay + eglGetError + eglGetProcAddress + eglInitialize + eglMakeCurrent + eglQueryAPI + eglQueryContext + eglQueryString + eglQuerySurface + eglReleaseTexImage + eglReleaseThread + eglSurfaceAttrib + eglSwapBuffers + eglSwapInterval + eglTerminate + eglWaitClient + eglWaitGL + eglWaitNative diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 4dc8707cfb..31c5419bbc 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -68,6 +68,7 @@ #include "eglscreen.h" #include "eglmode.h" #include "eglimage.h" +#include "eglsync.h" /** @@ -126,6 +127,8 @@ #define _EGL_CHECK_MODE(disp, m, ret, drv) \ _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) +#define _EGL_CHECK_SYNC(disp, s, ret, drv) \ + _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) static INLINE _EGLDriver * @@ -185,6 +188,26 @@ _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) } +#ifdef EGL_KHR_reusable_sync + + +static INLINE _EGLDriver * +_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) +{ + _EGLDriver *drv = _eglCheckDisplay(disp, msg); + if (!drv) + return NULL; + if (!s) { + _eglError(EGL_BAD_PARAMETER, msg); + return NULL; + } + return drv; +} + + +#endif /* EGL_KHR_reusable_sync */ + + #ifdef EGL_MESA_screen_surface @@ -809,7 +832,44 @@ eglGetProcAddress(const char *procname) const char *name; _EGLProc function; } egl_functions[] = { - /* extensions only */ + /* core functions should not be queryable, but, well... */ +#ifdef _EGL_GET_CORE_ADDRESSES + /* alphabetical order */ + { "eglBindAPI", (_EGLProc) eglBindAPI }, + { "eglBindTexImage", (_EGLProc) eglBindTexImage }, + { "eglChooseConfig", (_EGLProc) eglChooseConfig }, + { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, + { "eglCreateContext", (_EGLProc) eglCreateContext }, + { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, + { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, + { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, + { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, + { "eglDestroyContext", (_EGLProc) eglDestroyContext }, + { "eglDestroySurface", (_EGLProc) eglDestroySurface }, + { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, + { "eglGetConfigs", (_EGLProc) eglGetConfigs }, + { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, + { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, + { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, + { "eglGetDisplay", (_EGLProc) eglGetDisplay }, + { "eglGetError", (_EGLProc) eglGetError }, + { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, + { "eglInitialize", (_EGLProc) eglInitialize }, + { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, + { "eglQueryAPI", (_EGLProc) eglQueryAPI }, + { "eglQueryContext", (_EGLProc) eglQueryContext }, + { "eglQueryString", (_EGLProc) eglQueryString }, + { "eglQuerySurface", (_EGLProc) eglQuerySurface }, + { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, + { "eglReleaseThread", (_EGLProc) eglReleaseThread }, + { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, + { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, + { "eglSwapInterval", (_EGLProc) eglSwapInterval }, + { "eglTerminate", (_EGLProc) eglTerminate }, + { "eglWaitClient", (_EGLProc) eglWaitClient }, + { "eglWaitGL", (_EGLProc) eglWaitGL }, + { "eglWaitNative", (_EGLProc) eglWaitNative }, +#endif /* _EGL_GET_CORE_ADDRESSES */ #ifdef EGL_MESA_screen_surface { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, @@ -834,6 +894,10 @@ eglGetProcAddress(const char *procname) #ifdef EGL_NOK_swap_region { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, #endif +#ifdef EGL_MESA_drm_image + { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, + { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, +#endif { NULL, NULL } }; EGLint i; @@ -1245,6 +1309,90 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) #endif /* EGL_KHR_image_base */ +#ifdef EGL_KHR_reusable_sync + + +EGLSyncKHR EGLAPIENTRY +eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + _EGLSync *sync; + EGLSyncKHR ret; + + _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); + + sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); + ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR; + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + _eglUnlinkSync(s); + ret = drv->API.DestroySyncKHR(drv, disp, s); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLint EGLAPIENTRY +eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLint ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + ret = drv->API.SignalSyncKHR(drv, disp, s, mode); + + RETURN_EGL_EVAL(disp, ret); +} + + +EGLBoolean EGLAPIENTRY +eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSync *s = _eglLookupSync(sync, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); + ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); + + RETURN_EGL_EVAL(disp, ret); +} + + +#endif /* EGL_KHR_reusable_sync */ + + #ifdef EGL_NOK_swap_region EGLBoolean EGLAPIENTRY @@ -1272,3 +1420,42 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, } #endif /* EGL_NOK_swap_region */ + + +#ifdef EGL_MESA_drm_image + +EGLImageKHR EGLAPIENTRY +eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + _EGLImage *img; + EGLImageKHR ret; + + _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); + + img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); + ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; + + RETURN_EGL_EVAL(disp, ret); +} + +EGLBoolean EGLAPIENTRY +eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, + EGLint *name, EGLint *handle, EGLint *stride) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLImage *img = _eglLookupImage(image, disp); + _EGLDriver *drv; + EGLBoolean ret; + + _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); + if (!img) + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); + + ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); + + RETURN_EGL_EVAL(disp, ret); +} + +#endif diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index d8c8b49a49..127becc9ac 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -76,10 +76,25 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); #endif /* EGL_KHR_image_base */ + +#ifdef EGL_KHR_reusable_sync +typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); +typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (*SignalSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLenum mode); +typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLint *value); +#endif /* EGL_KHR_reusable_sync */ + + #ifdef EGL_NOK_swap_region typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects); #endif +#ifdef EGL_MESA_drm_image +typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attr_list); +typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride); +#endif + /** * The API dispatcher jumps through these functions */ @@ -138,9 +153,22 @@ struct _egl_api DestroyImageKHR_t DestroyImageKHR; #endif /* EGL_KHR_image_base */ +#ifdef EGL_KHR_reusable_sync + CreateSyncKHR_t CreateSyncKHR; + DestroySyncKHR_t DestroySyncKHR; + ClientWaitSyncKHR_t ClientWaitSyncKHR; + SignalSyncKHR_t SignalSyncKHR; + GetSyncAttribKHR_t GetSyncAttribKHR; +#endif /* EGL_KHR_reusable_sync */ + #ifdef EGL_NOK_swap_region SwapBuffersRegionNOK_t SwapBuffersRegionNOK; #endif + +#ifdef EGL_MESA_drm_image + CreateDRMImageMESA_t CreateDRMImageMESA; + ExportDRMImageMESA_t ExportDRMImageMESA; +#endif }; #endif /* EGLAPI_INCLUDED */ diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index ea8e47d02b..01e7144d40 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -460,11 +460,14 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) } if (!matched) { -#ifdef DEBUG +#ifndef DEBUG + /* only print the common errors when DEBUG is not defined */ + if (attr != EGL_RENDERABLE_TYPE) + break; +#endif _eglLog(_EGL_DEBUG, "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)", val, attr, cmp); -#endif break; } } diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 9fc529613e..e72664c23c 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -83,15 +83,6 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list) } } - if (err == EGL_SUCCESS && ctx->Config) { - EGLint renderable_type, api_bit; - - renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE); - api_bit = _eglGetContextAPIBit(ctx); - if (!(renderable_type & api_bit)) - err = EGL_BAD_CONFIG; - } - return err; } @@ -121,6 +112,17 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, ctx->ClientVersion = 1; /* the default, per EGL spec */ err = _eglParseContextAttribList(ctx, attrib_list); + if (err == EGL_SUCCESS && ctx->Config) { + EGLint renderable_type, api_bit; + + renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE); + api_bit = _eglGetContextAPIBit(ctx); + if (!(renderable_type & api_bit)) { + _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x", + api_bit, renderable_type); + err = EGL_BAD_CONFIG; + } + } if (err != EGL_SUCCESS) return _eglError(err, "eglCreateContext"); diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index a2cee08bf6..3863cce010 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -24,6 +24,7 @@ enum _egl_resource_type { _EGL_RESOURCE_CONTEXT, _EGL_RESOURCE_SURFACE, _EGL_RESOURCE_IMAGE, + _EGL_RESOURCE_SYNC, _EGL_NUM_RESOURCES }; @@ -53,6 +54,8 @@ struct _egl_extensions EGLBoolean MESA_screen_surface; EGLBoolean MESA_copy_context; EGLBoolean MESA_drm_display; + EGLBoolean MESA_drm_image; + EGLBoolean KHR_image_base; EGLBoolean KHR_image_pixmap; EGLBoolean KHR_vg_parent_image; @@ -60,9 +63,14 @@ struct _egl_extensions EGLBoolean KHR_gl_texture_cubemap_image; EGLBoolean KHR_gl_texture_3D_image; EGLBoolean KHR_gl_renderbuffer_image; + + EGLBoolean KHR_reusable_sync; + EGLBoolean KHR_fence_sync; + EGLBoolean KHR_surfaceless_gles1; EGLBoolean KHR_surfaceless_gles2; EGLBoolean KHR_surfaceless_opengl; + EGLBoolean NOK_swap_region; EGLBoolean NOK_texture_from_pixmap; diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 8fc9e792b0..67f1d3dbaa 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -21,6 +21,7 @@ #include "eglstring.h" #include "eglsurface.h" #include "eglimage.h" +#include "eglsync.h" #include "eglmutex.h" #if defined(_EGL_OS_UNIX) @@ -722,6 +723,14 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.CreateImageKHR = _eglCreateImageKHR; drv->API.DestroyImageKHR = _eglDestroyImageKHR; #endif /* EGL_KHR_image_base */ + +#ifdef EGL_KHR_reusable_sync + drv->API.CreateSyncKHR = _eglCreateSyncKHR; + drv->API.DestroySyncKHR = _eglDestroySyncKHR; + drv->API.ClientWaitSyncKHR = _eglClientWaitSyncKHR; + drv->API.SignalSyncKHR = _eglSignalSyncKHR; + drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR; +#endif /* EGL_KHR_reusable_sync */ } diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index 985d1e0069..eb3dde1fb4 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -85,6 +85,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy) _EGL_CHECK_EXTENSION(MESA_screen_surface); _EGL_CHECK_EXTENSION(MESA_copy_context); _EGL_CHECK_EXTENSION(MESA_drm_display); + _EGL_CHECK_EXTENSION(MESA_drm_image); _EGL_CHECK_EXTENSION(KHR_image_base); _EGL_CHECK_EXTENSION(KHR_image_pixmap); @@ -97,6 +98,9 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy) _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); + _EGL_CHECK_EXTENSION(KHR_reusable_sync); + _EGL_CHECK_EXTENSION(KHR_fence_sync); + _EGL_CHECK_EXTENSION(KHR_surfaceless_gles1); _EGL_CHECK_EXTENSION(KHR_surfaceless_gles2); _EGL_CHECK_EXTENSION(KHR_surfaceless_opengl); diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c new file mode 100644 index 0000000000..b6c62d0087 --- /dev/null +++ b/src/egl/main/eglsync.c @@ -0,0 +1,128 @@ +#include <string.h> + +#include "eglsync.h" +#include "eglcurrent.h" +#include "egllog.h" + + +#ifdef EGL_KHR_reusable_sync + + +/** + * Parse the list of sync attributes and return the proper error code. + */ +static EGLint +_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + + if (!attrib_list) + return EGL_SUCCESS; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + default: + (void) val; + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr); + break; + } + } + + return err; +} + + +EGLBoolean +_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, + const EGLint *attrib_list) +{ + EGLint err; + + if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync) && + !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync)) + return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + + memset(sync, 0, sizeof(*sync)); + + sync->Resource.Display = dpy; + + sync->Type = type; + sync->SyncStatus = EGL_UNSIGNALED_KHR; + sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; + + err = _eglParseSyncAttribList(sync, attrib_list); + if (err != EGL_SUCCESS) + return _eglError(err, "eglCreateSyncKHR"); + + return EGL_TRUE; +} + + +_EGLSync * +_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, + EGLenum type, const EGLint *attrib_list) +{ + return NULL; +} + + +EGLBoolean +_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) +{ + return EGL_TRUE; +} + + +EGLint +_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint flags, EGLTimeKHR timeout) +{ + return EGL_FALSE; +} + + +EGLBoolean +_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLenum mode) +{ + return EGL_FALSE; +} + + +EGLBoolean +_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint attribute, EGLint *value) +{ + if (!value) + return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs"); + + switch (attribute) { + case EGL_SYNC_TYPE_KHR: + *value = sync->Type; + break; + case EGL_SYNC_STATUS_KHR: + *value = sync->SyncStatus; + break; + case EGL_SYNC_CONDITION_KHR: + if (sync->Type != EGL_SYNC_FENCE_KHR) + return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); + *value = sync->SyncCondition; + break; + default: + return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); + break; + } + + return EGL_TRUE; +} + + +#endif /* EGL_KHR_reusable_sync */ diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h new file mode 100644 index 0000000000..25c467175e --- /dev/null +++ b/src/egl/main/eglsync.h @@ -0,0 +1,120 @@ +#ifndef EGLSYNC_INCLUDED +#define EGLSYNC_INCLUDED + + +#include "egltypedefs.h" +#include "egldisplay.h" + + +#ifdef EGL_KHR_reusable_sync + + +/** + * "Base" class for device driver syncs. + */ +struct _egl_sync +{ + /* A sync is a display resource */ + _EGLResource Resource; + + EGLenum Type; + EGLenum SyncStatus; + EGLenum SyncCondition; +}; + + +PUBLIC EGLBoolean +_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, + const EGLint *attrib_list); + + +extern _EGLSync * +_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, + EGLenum type, const EGLint *attrib_list); + + +extern EGLBoolean +_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); + + +extern EGLint +_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint flags, EGLTimeKHR timeout); + + +extern EGLBoolean +_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLenum mode); + + +extern EGLBoolean +_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, + EGLint attribute, EGLint *value); + + +/** + * Link a sync to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLSyncKHR +_eglLinkSync(_EGLSync *sync, _EGLDisplay *dpy) +{ + _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC, dpy); + return (EGLSyncKHR) sync; +} + + +/** + * Unlink a linked sync from its display. + */ +static INLINE void +_eglUnlinkSync(_EGLSync *sync) +{ + _eglUnlinkResource(&sync->Resource, _EGL_RESOURCE_SYNC); +} + + +/** + * Lookup a handle to find the linked sync. + * Return NULL if the handle has no corresponding linked sync. + */ +static INLINE _EGLSync * +_eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy) +{ + _EGLSync *sync = (_EGLSync *) handle; + if (!dpy || !_eglCheckResource((void *) sync, _EGL_RESOURCE_SYNC, dpy)) + sync = NULL; + return sync; +} + + +/** + * Return the handle of a linked sync, or EGL_NO_SYNC_KHR. + */ +static INLINE EGLSyncKHR +_eglGetSyncHandle(_EGLSync *sync) +{ + _EGLResource *res = (_EGLResource *) sync; + return (res && _eglIsResourceLinked(res)) ? + (EGLSyncKHR) sync : EGL_NO_SYNC_KHR; +} + + +/** + * Return true if the sync is linked to a display. + * + * The link is considered a reference to the sync (the display is owning the + * sync). Drivers should not destroy a sync when it is linked. + */ +static INLINE EGLBoolean +_eglIsSyncLinked(_EGLSync *sync) +{ + _EGLResource *res = (_EGLResource *) sync; + return (res && _eglIsResourceLinked(res)); +} + + +#endif /* EGL_KHR_reusable_sync */ + + +#endif /* EGLSYNC_INCLUDED */ diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 0e29e9aa47..b65f3b72ae 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -32,6 +32,8 @@ typedef struct _egl_screen _EGLScreen; typedef struct _egl_surface _EGLSurface; +typedef struct _egl_sync _EGLSync; + typedef struct _egl_thread_info _EGLThreadInfo; #endif /* EGLTYPEDEFS_INCLUDED */ |