egl/dri2: implement createImageFromDmaBufs3
And refuse to import image with protected_content enabled. We don't want a compositor to import an encrypted buffer in a image without the ProtectedContent attribute enabled, because that will lead to incorrect display. Similarly, if the compositor thinks the image is encrypted, we fail the import if the buffer is not. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5096>
This commit is contained in:
@@ -2866,7 +2866,28 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
|
||||
has_modifier = true;
|
||||
}
|
||||
|
||||
if (has_modifier) {
|
||||
if (attrs.ProtectedContent) {
|
||||
if (dri2_dpy->image->base.version < 18 ||
|
||||
dri2_dpy->image->createImageFromDmaBufs3 == NULL) {
|
||||
_eglError(EGL_BAD_MATCH, "unsupported protected_content attribute");
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (!has_modifier)
|
||||
modifier = DRM_FORMAT_MOD_INVALID;
|
||||
|
||||
dri_image =
|
||||
dri2_dpy->image->createImageFromDmaBufs3(dri2_dpy->dri_screen,
|
||||
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
|
||||
modifier, fds, num_fds, pitches, offsets,
|
||||
attrs.DMABufYuvColorSpaceHint.Value,
|
||||
attrs.DMABufSampleRangeHint.Value,
|
||||
attrs.DMABufChromaHorizontalSiting.Value,
|
||||
attrs.DMABufChromaVerticalSiting.Value,
|
||||
attrs.ProtectedContent ? __DRI_IMAGE_PROTECTED_CONTENT_FLAG : 0,
|
||||
&error,
|
||||
NULL);
|
||||
}
|
||||
else if (has_modifier) {
|
||||
if (dri2_dpy->image->base.version < 15 ||
|
||||
dri2_dpy->image->createImageFromDmaBufs2 == NULL) {
|
||||
_eglError(EGL_BAD_MATCH, "unsupported dma_buf format modifier");
|
||||
|
@@ -740,6 +740,7 @@ static __DRIimage *
|
||||
dri2_create_image_from_winsys(__DRIscreen *_screen,
|
||||
int width, int height, const struct dri2_format_mapping *map,
|
||||
int num_handles, struct winsys_handle *whandle,
|
||||
bool is_protected_content,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
struct dri_screen *screen = dri_screen(_screen);
|
||||
@@ -829,6 +830,16 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Reject image creation if there's an inconsistency between
|
||||
* content protection status of tex and img.
|
||||
*/
|
||||
if ((tex->bind & PIPE_BIND_PROTECTED) != is_protected_content) {
|
||||
pipe_resource_reference(&img->texture, NULL);
|
||||
pipe_resource_reference(&tex, NULL);
|
||||
FREE(img);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
img->texture = tex;
|
||||
}
|
||||
|
||||
@@ -861,7 +872,7 @@ dri2_create_image_from_name(__DRIscreen *_screen,
|
||||
whandle.stride = pitch * util_format_get_blocksize(map->pipe_format);
|
||||
|
||||
img = dri2_create_image_from_winsys(_screen, width, height, map,
|
||||
1, &whandle, loaderPrivate);
|
||||
1, &whandle, false, loaderPrivate);
|
||||
|
||||
if (!img)
|
||||
return NULL;
|
||||
@@ -923,8 +934,8 @@ static __DRIimage *
|
||||
dri2_create_image_from_fd(__DRIscreen *_screen,
|
||||
int width, int height, int fourcc,
|
||||
uint64_t modifier, int *fds, int num_fds,
|
||||
int *strides, int *offsets, unsigned *error,
|
||||
void *loaderPrivate)
|
||||
int *strides, int *offsets, bool protected_content,
|
||||
unsigned *error, void *loaderPrivate)
|
||||
{
|
||||
struct winsys_handle whandles[4];
|
||||
const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
|
||||
@@ -961,7 +972,8 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
|
||||
}
|
||||
|
||||
img = dri2_create_image_from_winsys(_screen, width, height, map,
|
||||
num_fds, whandles, loaderPrivate);
|
||||
num_fds, whandles, protected_content,
|
||||
loaderPrivate);
|
||||
if(img == NULL) {
|
||||
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
|
||||
goto exit;
|
||||
@@ -1366,7 +1378,7 @@ dri2_from_names(__DRIscreen *screen, int width, int height, int format,
|
||||
whandle.modifier = DRM_FORMAT_MOD_INVALID;
|
||||
|
||||
img = dri2_create_image_from_winsys(screen, width, height, map,
|
||||
1, &whandle, loaderPrivate);
|
||||
1, &whandle, false, loaderPrivate);
|
||||
if (img == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1435,7 +1447,7 @@ dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc,
|
||||
{
|
||||
return dri2_create_image_from_fd(screen, width, height, fourcc,
|
||||
DRM_FORMAT_MOD_INVALID, fds, num_fds,
|
||||
strides, offsets, NULL, loaderPrivate);
|
||||
strides, offsets, false, NULL, loaderPrivate);
|
||||
}
|
||||
|
||||
static boolean
|
||||
@@ -1507,7 +1519,7 @@ dri2_from_dma_bufs(__DRIscreen *screen,
|
||||
|
||||
img = dri2_create_image_from_fd(screen, width, height, fourcc,
|
||||
DRM_FORMAT_MOD_INVALID, fds, num_fds,
|
||||
strides, offsets, error, loaderPrivate);
|
||||
strides, offsets, false, error, loaderPrivate);
|
||||
if (img == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1536,6 +1548,37 @@ dri2_from_dma_bufs2(__DRIscreen *screen,
|
||||
|
||||
img = dri2_create_image_from_fd(screen, width, height, fourcc,
|
||||
modifier, fds, num_fds, strides, offsets,
|
||||
false, error, loaderPrivate);
|
||||
if (img == NULL)
|
||||
return NULL;
|
||||
|
||||
img->yuv_color_space = yuv_color_space;
|
||||
img->sample_range = sample_range;
|
||||
img->horizontal_siting = horizontal_siting;
|
||||
img->vertical_siting = vertical_siting;
|
||||
|
||||
*error = __DRI_IMAGE_ERROR_SUCCESS;
|
||||
return img;
|
||||
}
|
||||
|
||||
static __DRIimage *
|
||||
dri2_from_dma_bufs3(__DRIscreen *screen,
|
||||
int width, int height, int fourcc,
|
||||
uint64_t modifier, int *fds, int num_fds,
|
||||
int *strides, int *offsets,
|
||||
enum __DRIYUVColorSpace yuv_color_space,
|
||||
enum __DRISampleRange sample_range,
|
||||
enum __DRIChromaSiting horizontal_siting,
|
||||
enum __DRIChromaSiting vertical_siting,
|
||||
uint32_t flags,
|
||||
unsigned *error,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
__DRIimage *img;
|
||||
|
||||
img = dri2_create_image_from_fd(screen, width, height, fourcc,
|
||||
modifier, fds, num_fds, strides, offsets,
|
||||
flags & __DRI_IMAGE_PROTECTED_CONTENT_FLAG,
|
||||
error, loaderPrivate);
|
||||
if (img == NULL)
|
||||
return NULL;
|
||||
@@ -1652,7 +1695,7 @@ dri2_get_capabilities(__DRIscreen *_screen)
|
||||
|
||||
/* The extension is modified during runtime if DRI_PRIME is detected */
|
||||
static __DRIimageExtension dri2ImageExtension = {
|
||||
.base = { __DRI_IMAGE, 17 },
|
||||
.base = { __DRI_IMAGE, 18 },
|
||||
|
||||
.createImageFromName = dri2_create_image_from_name,
|
||||
.createImageFromRenderbuffer = dri2_create_image_from_renderbuffer,
|
||||
@@ -1672,6 +1715,7 @@ static __DRIimageExtension dri2ImageExtension = {
|
||||
.unmapImage = dri2_unmap_image,
|
||||
.createImageWithModifiers = NULL,
|
||||
.createImageFromDmaBufs2 = NULL,
|
||||
.createImageFromDmaBufs3 = NULL,
|
||||
.queryDmaBufFormats = NULL,
|
||||
.queryDmaBufModifiers = NULL,
|
||||
.queryDmaBufFormatModifierAttribs = NULL,
|
||||
@@ -2180,6 +2224,7 @@ dri2_init_screen(__DRIscreen * sPriv)
|
||||
dri2ImageExtension.createImageFromFds = dri2_from_fds;
|
||||
dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
|
||||
dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2;
|
||||
dri2ImageExtension.createImageFromDmaBufs3 = dri2_from_dma_bufs3;
|
||||
dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats;
|
||||
dri2ImageExtension.queryDmaBufModifiers =
|
||||
dri2_query_dma_buf_modifiers;
|
||||
@@ -2260,6 +2305,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
|
||||
dri2ImageExtension.createImageFromFds = dri2_from_fds;
|
||||
dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
|
||||
dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2;
|
||||
dri2ImageExtension.createImageFromDmaBufs3 = dri2_from_dma_bufs3;
|
||||
dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats;
|
||||
dri2ImageExtension.queryDmaBufModifiers = dri2_query_dma_buf_modifiers;
|
||||
}
|
||||
|
Reference in New Issue
Block a user