100 QVideoFrameFormat::PixelFormat qtFormat, QSize frameSize,
101 std::shared_ptr<
void> parentKeepAlive)
103 Qt::HANDLE eglDisplay = eglContext.eglDisplay();
104 QOpenGLContext *glContext = eglContext.glContext();
106 QOpenGLFunctions functions(glContext);
108 auto *desc = QVideoTextureHelper::textureDescription(qtFormat);
109 int nPlanes = desc->nplanes;
110 Q_ASSERT(planes.size() == nPlanes);
112 rhi.makeThreadLocalNativeContextCurrent();
114 EGLImage images[4] = {};
115 std::array<GLuint, 4> glTextures{};
116 functions.glGenTextures(nPlanes, glTextures.data());
118 auto releaseTextures = qScopeGuard([&] {
119 for (EGLImage img : images | views::filter_nonnull)
120 eglDestroyImage(eglDisplay, img);
122 functions.glDeleteTextures(nPlanes, glTextures.data());
125 for (
int i = 0; i < nPlanes; ++i) {
128 QSize planeSize = desc->rhiPlaneSize(frameSize, i, &rhi);
129 constexpr uint32_t maxAttrCount = 18;
130 EGLAttrib img_attr[maxAttrCount] = {
131 EGL_LINUX_DRM_FOURCC_EXT,
132 (EGLint)qToUnderlying(plane.drmFormat),
137 EGL_DMA_BUF_PLANE0_FD_EXT,
139 EGL_DMA_BUF_PLANE0_OFFSET_EXT,
140 (EGLint)plane.offset,
141 EGL_DMA_BUF_PLANE0_PITCH_EXT,
144 uint32_t img_attr_idx = 12;
145 if (plane.modifier != DmaBufFormatModifierInvalid) {
146 img_attr[img_attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
147 img_attr[img_attr_idx++] = plane.modifier & 0xFFFFFFFF;
148 img_attr[img_attr_idx++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
149 img_attr[img_attr_idx++] = plane.modifier >> 32;
151 img_attr[img_attr_idx++] = EGL_NONE;
152 Q_ASSERT(img_attr_idx <= maxAttrCount);
153 images[i] = eglCreateImage(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT,
nullptr,
156 const GLenum error = eglGetError();
157 if (error == EGL_BAD_MATCH) {
158 qWarning() <<
"eglCreateImage failed for plane" << i
159 <<
"with error code EGL_BAD_MATCH, disabling hardware acceleration. "
160 "This could indicate an EGL implementation issue."
162 << eglQueryString(eglDisplay, EGL_VENDOR);
164 return q23::unexpected{ FailureSeverity::unrecoverable };
167 qWarning() <<
"eglCreateImage failed for plane" << i <<
"with error code" << error;
168 return q23::unexpected{ FailureSeverity::recoverable };
171 functions.glActiveTexture(GL_TEXTURE0 + i);
172 functions.glBindTexture(GL_TEXTURE_2D, glTextures[i]);
174 QEglImageFunctions::instance().glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, images[i]);
175 GLenum error = glGetError();
177 qWarning() <<
"eglImageTargetTexture2D failed for plane" << i <<
"with error code"
179 <<
"(the driver may not support importing this dma-buf as a GL texture)";
180 return q23::unexpected{ FailureSeverity::recoverable };
184 releaseTextures.dismiss();
186 for (
int i = 0; i < nPlanes; ++i) {
187 functions.glActiveTexture(GL_TEXTURE0 + i);
188 functions.glBindTexture(GL_TEXTURE_2D, 0);
189 eglDestroyImage(eglDisplay, images[i]);
192 return std::make_unique<DmaBufTextureHandles>(rhi, glContext, nPlanes, glTextures,
193 std::move(parentKeepAlive));