diff options
author | Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> | 2020-05-11 18:26:30 +0200 |
---|---|---|
committer | Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> | 2020-11-02 10:15:47 +0100 |
commit | bd182777c8f2c4468568901ce92b1796674eb87d (patch) | |
tree | 4e060203d54c8a0f8419859417568cf5c1c54bbd | |
parent | 9698a222a6c26e998d9efe6d940e11772aa8610c (diff) |
egl: implement EGL_EXT_protected_surface support
Reviewed-by: Eric Engestrom <eric@engestrom.ch>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5096>
-rw-r--r-- | include/GL/internal/dri_interface.h | 3 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 4 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_drm.c | 8 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_wayland.c | 7 | ||||
-rw-r--r-- | src/egl/drivers/dri2/platform_x11_dri3.c | 9 | ||||
-rw-r--r-- | src/egl/main/eglapi.c | 11 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 1 | ||||
-rw-r--r-- | src/egl/main/eglsurface.c | 14 | ||||
-rw-r--r-- | src/egl/main/eglsurface.h | 2 | ||||
-rw-r--r-- | src/gallium/frontends/dri/dri2.c | 2 | ||||
-rw-r--r-- | src/gallium/frontends/dri/dri_query_renderer.c | 7 | ||||
-rw-r--r-- | src/gbm/backends/dri/gbm_dri.c | 2 | ||||
-rw-r--r-- | src/gbm/main/gbm.h | 6 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.c | 4 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.h | 2 |
15 files changed, 79 insertions, 3 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 76c50ad334f..94406dcb97b 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -1367,6 +1367,7 @@ struct __DRIdri2ExtensionRec { * could be read after a flush." */ #define __DRI_IMAGE_USE_BACKBUFFER 0x0010 +#define __DRI_IMAGE_USE_PROTECTED 0x0020 #define __DRI_IMAGE_TRANSFER_READ 0x1 @@ -1932,6 +1933,8 @@ typedef struct __DRIDriverVtableExtensionRec { #define __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_MEDIUM (1 << 1) #define __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_HIGH (1 << 2) +#define __DRI2_RENDERER_HAS_PROTECTED_CONTENT 0x000e + typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension; struct __DRI2rendererQueryExtensionRec { __DRIextension base; diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index e0d7b05131c..a2ffb60e3bf 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -1017,6 +1017,10 @@ dri2_setup_screen(_EGLDisplay *disp) if (dri2_dpy->buffer_damage && dri2_dpy->buffer_damage->set_damage_region) disp->Extensions.KHR_partial_update = EGL_TRUE; + + disp->Extensions.EXT_protected_content = + dri2_renderer_query_integer(dri2_dpy, + __DRI2_RENDERER_HAS_PROTECTED_CONTENT); } void diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index a0760dfebbb..2944a5d7ad4 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -251,12 +251,16 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) surf->base.format, surf->base.modifiers, surf->base.count); - else + else { + unsigned flags = surf->base.flags; + if (dri2_surf->base.ProtectedContent) + flags |= GBM_BO_USE_PROTECTED; dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base, surf->base.width, surf->base.height, surf->base.format, - surf->base.flags); + flags); + } } if (dri2_surf->back->bo == NULL) diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index cd43fb26d5e..c0b26c4b623 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -574,6 +574,13 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) use_flags = __DRI_IMAGE_USE_SHARE | __DRI_IMAGE_USE_BACKBUFFER; + if (dri2_surf->base.ProtectedContent) { + /* Protected buffers can't be read from another GPU */ + if (dri2_dpy->is_different_gpu) + return -1; + use_flags |= __DRI_IMAGE_USE_PROTECTED; + } + if (dri2_dpy->is_different_gpu && dri2_surf->back->linear_copy == NULL) { /* The LINEAR modifier should be a perfect alias of the LINEAR use diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c index 40d203c9ec1..e117105fcb6 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -183,6 +183,15 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, goto cleanup_pixmap; } + if (dri3_surf->surf.base.ProtectedContent && + dri2_dpy->is_different_gpu) { + _eglError(EGL_BAD_ALLOC, "dri3_surface_create"); + goto cleanup_pixmap; + } + + dri3_surf->loader_drawable.is_protected_content = + dri3_surf->surf.base.ProtectedContent; + return &dri3_surf->surf.base; cleanup_pixmap: diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 405be0367d9..56dafca0d11 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -496,6 +496,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp) _EGL_CHECK_EXTENSION(EXT_create_context_robustness); _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import); _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers); + _EGL_CHECK_EXTENSION(EXT_protected_content); _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata); _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata); _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage); @@ -890,6 +891,14 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); if (read_surf && read_surf->Lost) RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE); + /* EGL_EXT_protected_surface spec says: + * If EGL_PROTECTED_CONTENT_EXT attributes of read is EGL_TRUE and + * EGL_PROTECTED_CONTENT_EXT attributes of draw is EGL_FALSE, an + * EGL_BAD_ACCESS error is generated. + */ + if (read_surf && read_surf->ProtectedContent && + draw_surf && !draw_surf->ProtectedContent) + RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context); @@ -1471,6 +1480,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) native_pixmap_ptr = (void*) target; _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + if (surf->ProtectedContent) + RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE); ret = disp->Driver->CopyBuffers(disp, surf, native_pixmap_ptr); RETURN_EGL_EVAL(disp, ret); diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 87415f81296..46c3008b658 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -106,6 +106,7 @@ struct _egl_extensions EGLBoolean EXT_image_dma_buf_import; EGLBoolean EXT_image_dma_buf_import_modifiers; EGLBoolean EXT_pixel_format_float; + EGLBoolean EXT_protected_content; EGLBoolean EXT_surface_CTA861_3_metadata; EGLBoolean EXT_surface_SMPTE2086_metadata; EGLBoolean EXT_swap_buffers_with_damage; diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 16a718aa09e..9faa800d001 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -303,6 +303,14 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) } surf->MipmapTexture = !!val; break; + case EGL_PROTECTED_CONTENT_EXT: + if (!disp->Extensions.EXT_protected_content) { + err = EGL_BAD_ATTRIBUTE; + break; + } + surf->ProtectedContent = val; + break; + /* no pixmap surface specific attributes */ default: err = EGL_BAD_ATTRIBUTE; @@ -383,6 +391,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type, surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; surf->VGColorspace = EGL_VG_COLORSPACE_sRGB; surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR; + surf->ProtectedContent = EGL_FALSE; surf->MipmapLevel = 0; surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT; @@ -581,6 +590,11 @@ _eglQuerySurface(_EGLDisplay *disp, _EGLSurface *surface, case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT: *value = surface->HdrMetadata.max_fall; break; + case EGL_PROTECTED_CONTENT_EXT: + if (!disp->Extensions.EXT_protected_content) + return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); + *value = surface->ProtectedContent; + break; default: return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); } diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index a98bc8eb18c..7f419cbf7e3 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -169,6 +169,8 @@ struct _egl_surface EGLBoolean PostSubBufferSupportedNV; + EGLBoolean ProtectedContent; + struct _egl_hdr_metadata HdrMetadata; void *NativeSurface; diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 3ed55866ad7..ead1c7d25e5 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -1018,6 +1018,8 @@ dri2_create_image_common(__DRIscreen *_screen, return NULL; tex_usage |= PIPE_BIND_CURSOR; } + if (use & __DRI_IMAGE_USE_PROTECTED) + tex_usage |= PIPE_BIND_PROTECTED; img = CALLOC_STRUCT(__DRIimageRec); if (!img) diff --git a/src/gallium/frontends/dri/dri_query_renderer.c b/src/gallium/frontends/dri/dri_query_renderer.c index e84c955334d..d9d2984bd64 100644 --- a/src/gallium/frontends/dri/dri_query_renderer.c +++ b/src/gallium/frontends/dri/dri_query_renderer.c @@ -67,6 +67,13 @@ dri2_query_renderer_integer(__DRIscreen *_screen, int param, if (!value[0]) return -1; return 0; + case __DRI2_RENDERER_HAS_PROTECTED_CONTENT: + value[0] = + screen->base.screen->get_param(screen->base.screen, + PIPE_CAP_DEVICE_PROTECTED_CONTENT); + if (!value[0]) + return -1; + return 0; default: return driQueryRendererIntegerCommon(_screen, param, value); } diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index bc68f66766e..b5634741554 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -1142,6 +1142,8 @@ gbm_dri_bo_create(struct gbm_device *gbm, dri_use |= __DRI_IMAGE_USE_CURSOR; if (usage & GBM_BO_USE_LINEAR) dri_use |= __DRI_IMAGE_USE_LINEAR; + if (usage & GBM_BO_USE_PROTECTED) + dri_use |= __DRI_IMAGE_USE_PROTECTED; /* Gallium drivers requires shared in order to get the handle/stride */ dri_use |= __DRI_IMAGE_USE_SHARE; diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index 8cb928b9677..5801cd526a0 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -238,6 +238,12 @@ enum gbm_bo_flags { * Buffer is linear, i.e. not tiled. */ GBM_BO_USE_LINEAR = (1 << 4), + /** + * Buffer is protected, i.e. encrypted and not readable by CPU or any + * other non-secure / non-trusted components nor by non-trusted OpenGL, + * OpenCL, and Vulkan applications. + */ + GBM_BO_USE_PROTECTED = (1 << 5), }; int diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 82b8cbaaafe..ccf8d1795e7 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -1419,7 +1419,9 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format, format, __DRI_IMAGE_USE_SHARE | __DRI_IMAGE_USE_SCANOUT | - __DRI_IMAGE_USE_BACKBUFFER, + __DRI_IMAGE_USE_BACKBUFFER | + (draw->is_protected_content ? + __DRI_IMAGE_USE_PROTECTED : 0), buffer); pixmap_buffer = buffer->image; diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 3d50852ba86..5191c89e7f2 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -168,6 +168,8 @@ struct loader_dri3_drawable { unsigned int back_format; xcb_present_complete_mode_t last_present_mode; + bool is_protected_content; + /* Currently protects the following fields: * event_cnd, has_event_waiter, * recv_sbc, ust, msc, recv_msc_serial, |