From 7a68aa6fc753bcf07a4024aa08807823630b444b Mon Sep 17 00:00:00 2001 From: Elvis Lee Date: Thu, 28 Jan 2021 17:16:04 +0900 Subject: [PATCH] Support EGL protected content extension A protected context is required to allow the GPU to operate on protected resources, including protected surfaces and protected EGLImages. For example, GPU can post-process on protected content like DRM protected content so that complex, nonlinear video effects or mapping onto textures can be used. The surface format option may be relevant for DirectX and Vulkan in the future: https://microsoft.github.io/DirectX-Specs/d3d/ProtectedResources.html https://www.khronos.org/registry/vulkan/specs/1.1-khr-extensions/html/chap12.html#memory-protected-memory Change-Id: I2d155f0e68b830276690b4833b22a2bc452cdcad Reviewed-by: Elvis Lee Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/kernel/qsurfaceformat.cpp | 9 +++++++++ src/gui/kernel/qsurfaceformat.h | 3 ++- .../opengl/platform/egl/qeglplatformcontext.cpp | 11 +++++++++++ .../eglfs_kms/qeglfskmsgbmwindow.cpp | 16 +++++++++++++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp index 647ed8eacaf..e62f87b1671 100644 --- a/src/gui/kernel/qsurfaceformat.cpp +++ b/src/gui/kernel/qsurfaceformat.cpp @@ -152,6 +152,9 @@ public: the monitoring of the loss of context, such as, Windows with WGL, or Linux/X11 (xcb) with GLX, will monitor the status in every call to \l{QOpenGLContext::makeCurrent()}{makeCurrent()}. See \l{QOpenGLContext::isValid()}{isValid()} for more information on this. + \value ProtectedContent Enables access to protected content. This allows the GPU to operate on protected + resources (surfaces, buffers, textures), for example DRM-protected video content. + Currently only implemented for EGL. */ /*! @@ -351,6 +354,9 @@ void QSurfaceFormat::setSamples(int numSamples) Sets the format options to \a options. + To verify that an option was respected, compare the actual format to the + requested format after surface/context creation. + \sa options(), testOption() */ void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options) @@ -366,6 +372,9 @@ void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options) Sets the format option \a option if \a on is true; otherwise, clears the option. + To verify that an option was respected, compare the actual format to the + requested format after surface/context creation. + \sa setOptions(), options(), testOption() */ void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on) diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h index b12c2b5f1d7..dfe55a338d6 100644 --- a/src/gui/kernel/qsurfaceformat.h +++ b/src/gui/kernel/qsurfaceformat.h @@ -57,7 +57,8 @@ public: StereoBuffers = 0x0001, DebugContext = 0x0002, DeprecatedFunctions = 0x0004, - ResetNotification = 0x0008 + ResetNotification = 0x0008, + ProtectedContent = 0x0010 }; Q_ENUM(FormatOption) Q_DECLARE_FLAGS(FormatOptions, FormatOption) diff --git a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp index 47e0b890d88..5727b94aa22 100644 --- a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp +++ b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp @@ -155,6 +155,17 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform } } +#ifdef EGL_EXT_protected_content + if (format.testOption(QSurfaceFormat::ProtectedContent)) { + if (q_hasEglExtension(m_eglDisplay, "EGL_EXT_protected_content")) { + contextAttrs.append(EGL_PROTECTED_CONTENT_EXT); + contextAttrs.append(EGL_TRUE); + } else { + m_format.setOption(QSurfaceFormat::ProtectedContent, false); + } + } +#endif + // Special Options for OpenVG surfaces if (m_format.renderableType() == QSurfaceFormat::OpenVG) { contextAttrs.append(EGL_ALPHA_MASK_SIZE); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp index 426fb8f4e9f..3a0222db928 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp @@ -67,7 +67,21 @@ void QEglFSKmsGbmWindow::resetSurface() } if (createPlatformWindowSurface) { - m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast(m_window), nullptr); + QVector contextAttributes; +#ifdef EGL_EXT_protected_content + if (platformFormat.testOption(QSurfaceFormat::ProtectedContent)) { + if (q_hasEglExtension(display, "EGL_EXT_protected_content")) { + contextAttributes.append(EGL_PROTECTED_CONTENT_EXT); + contextAttributes.append(EGL_TRUE); + qCDebug(qLcEglfsKmsDebug, "Enabled EGL_PROTECTED_CONTENT_EXT for eglCreatePlatformWindowSurfaceEXT"); + } else { + m_format.setOption(QSurfaceFormat::ProtectedContent, false); + } + } +#endif + contextAttributes.append(EGL_NONE); + + m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast(m_window), contextAttributes.constData()); } else { qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr);