QT_BEGIN_NAMESPACE /* In some cases pbuffers are not available. Triggering QtGui's built-in fallback for a hidden QWindow is not suitable for eglfs since this would be treated as an attempt to create multiple top-level, native windows. Therefore this class is provided as an alternative to QEGLPbuffer. This class requires the hooks to implement createNativeOffscreenWindow(). */ QEglFSOffscreenWindow::QEglFSOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) , m_format(format) , m_display(display) , m_surface(EGL_NO_SURFACE) , m_window(0) { m_window = qt_egl_device_integration()->createNativeOffscreenWindow(format); if (!m_window) { qWarning("QEglFSOffscreenWindow: Failed to create native window"); return; } EGLConfig config = q_configFromGLFormat(m_display, m_format); m_surface = eglCreateWindowSurface(m_display, config, m_window, 0); if (m_surface != EGL_NO_SURFACE) m_format = q_glFormatFromConfig(m_display, config); }
QT_BEGIN_NAMESPACE QNitpickerGLContext::QNitpickerGLContext(QOpenGLContext *context) : QPlatformOpenGLContext() { if (qnglc_verbose) PDBG("called"); if (!eglBindAPI(EGL_OPENGL_API)) qFatal("eglBindAPI() failed"); _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (_egl_display == EGL_NO_DISPLAY) qFatal("eglGetDisplay() failed"); int major = -1; int minor = -1; if (!eglInitialize(_egl_display, &major, &minor)) qFatal("eglInitialize() failed"); if (qnglc_verbose) PDBG("eglInitialize() returned major: %d, minor: %d", major, minor); _egl_config = q_configFromGLFormat(_egl_display, context->format(), false, EGL_PBUFFER_BIT); if (_egl_config == 0) qFatal("Could not find a matching EGL config"); _format = q_glFormatFromConfig(_egl_display, _egl_config); _egl_context = eglCreateContext(_egl_display, _egl_config, EGL_NO_CONTEXT, 0); if (_egl_context == EGL_NO_CONTEXT) qFatal("eglCreateContext() failed"); }
QT_BEGIN_NAMESPACE QKmsContext::QKmsContext(QOpenGLContext *context, QKmsDevice *device) : m_device(device) { EGLDisplay display = m_device->eglDisplay(); EGLConfig config = q_configFromGLFormat(display, QKmsScreen::tweakFormat(context->format())); m_format = q_glFormatFromConfig(display, config); //Initialize EGLContext static EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, context->format().majorVersion(), EGL_NONE }; eglBindAPI(EGL_OPENGL_ES_API); EGLContext share = EGL_NO_CONTEXT; if (context->shareContext()) share = static_cast<QKmsContext *>(context->shareContext()->handle())->eglContext(); m_eglContext = eglCreateContext(display, config, share, contextAttribs); if (m_eglContext == EGL_NO_CONTEXT) { qWarning("QKmsContext::QKmsContext(): eglError: %x, this: %p", eglGetError(), this); m_eglContext = 0; } }
void QWaylandBrcmEglWindow::createEglSurfaces() { QSize size(geometry().size()); m_count = window()->format().swapBehavior() == QSurfaceFormat::TripleBuffer ? 3 : 2; m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), brcmFixFormat(window()->format()), true, EGL_PIXMAP_BIT); m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(), m_eglConfig); EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM; EGLint rt; eglGetConfigAttrib(m_eglIntegration->eglDisplay(), m_eglConfig, EGL_RENDERABLE_TYPE, &rt); if (rt & EGL_OPENGL_ES_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM; } if (rt & EGL_OPENGL_ES2_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM; } if (rt & EGL_OPENVG_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM; pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM; } if (rt & EGL_OPENGL_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM; } memset(m_globalImages, 0, 5 * m_count * sizeof(EGLint)); for (int i = 0; i < m_count; ++i) { m_eglIntegration->eglCreateGlobalImageBRCM(size.width(), size.height(), pixel_format, 0, size.width() * 4, &m_globalImages[5*i]); m_globalImages[5*i+2] = size.width(); m_globalImages[5*i+3] = size.height(); m_globalImages[5*i+4] = pixel_format; EGLint attrs[] = { EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB, EGL_VG_ALPHA_FORMAT, pixel_format & EGL_PIXEL_FORMAT_ARGB_8888_PRE_BRCM ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE, EGL_NONE }; m_eglSurfaces[i] = eglCreatePixmapSurface(m_eglIntegration->eglDisplay(), m_eglConfig, (EGLNativePixmapType)&m_globalImages[5*i], attrs); if (m_eglSurfaces[i] == EGL_NO_SURFACE) qFatal("eglCreatePixmapSurface failed: %x, global image id: %d %d\n", eglGetError(), m_globalImages[5*i], m_globalImages[5*i+1]); m_buffers[i] = new QWaylandBrcmBuffer(mDisplay, m_eglIntegration->waylandBrcm(), size, &m_globalImages[5*i], 5); } }
void QEglFSWindow::create() { if (m_flags.testFlag(Created)) return; QEGLPlatformWindow::create(); m_flags = Created; if (window()->type() == Qt::Desktop) return; // Stop if there is already a window backed by a native window and surface. Additional // raster windows will not have their own native window, surface and context. Instead, // they will be composited onto the root window's surface. QEglFSScreen *screen = this->screen(); if (screen->primarySurface() != EGL_NO_SURFACE) { if (isRaster() && screen->compositingWindow()) return; #if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK) // We can have either a single OpenGL window or multiple raster windows. // Other combinations cannot work. qFatal("EGLFS: OpenGL windows cannot be mixed with others."); #endif return; } m_flags |= HasNativeWindow; setGeometry(QRect()); // will become fullscreen QWindowSystemInterface::handleExposeEvent(window(), geometry()); EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display(); QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat()); m_config = QEglFSIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, m_config, platformFormat); resetSurface(); screen->setPrimarySurface(m_surface); if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); context->setFormat(window()->requestedFormat()); context->setScreen(window()->screen()); if (!context->create()) qFatal("EGLFS: Failed to create compositing context"); screen->setRootContext(context); screen->setRootWindow(this); } }
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config) { clearEgl(); QJNIEnvironmentPrivate env; m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object()); m_androidSurfaceObject = QJNIObjectPrivate(); m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL); m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat()); if (m_eglSurface == EGL_NO_SURFACE) { EGLint error = eglGetError(); eglTerminate(m_eglDisplay); qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); } }
void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share) { if (!nativeHandle.canConvert<QEGLNativeContext>()) { qWarning("QEGLPlatformContext: Requires a QEGLNativeContext"); return; } QEGLNativeContext handle = nativeHandle.value<QEGLNativeContext>(); EGLContext context = handle.context(); if (!context) { qWarning("QEGLPlatformContext: No EGLContext given"); return; } // A context belonging to a given EGLDisplay cannot be used with another one. if (handle.display() != m_eglDisplay) { qWarning("QEGLPlatformContext: Cannot adopt context from different display"); return; } // Figure out the EGLConfig. EGLint value = 0; eglQueryContext(m_eglDisplay, context, EGL_CONFIG_ID, &value); EGLint n = 0; EGLConfig cfg; const EGLint attribs[] = { EGL_CONFIG_ID, value, EGL_NONE }; if (eglChooseConfig(m_eglDisplay, attribs, &cfg, 1, &n) && n == 1) { m_eglConfig = cfg; m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig); } else { qWarning("QEGLPlatformContext: Failed to get framebuffer configuration for context"); } // Fetch client API type. value = 0; eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value); if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) { m_api = value; eglBindAPI(m_api); } else { qWarning("QEGLPlatformContext: Failed to get client API type"); m_api = EGL_OPENGL_ES_API; } m_eglContext = context; m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; updateFormatFromGL(); }
QWaylandBrcmGLContext::QWaylandBrcmGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) : QPlatformOpenGLContext() , m_eglDisplay(eglDisplay) , m_config(q_configFromGLFormat(m_eglDisplay, brcmFixFormat(format), true)) , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) { EGLContext shareEGLContext = share ? static_cast<QWaylandBrcmGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; eglBindAPI(EGL_OPENGL_ES_API); QVector<EGLint> eglContextAttrs; eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(format.majorVersion() == 1 ? 1 : 2); eglContextAttrs.append(EGL_NONE); m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData()); }
EGLSurface QWaylandEglWindow::eglSurface() const { if (!m_waylandEglWindow) { const_cast<QWaylandEglWindow *>(this)->createDecoration(); QMargins margins = frameMargins(); QSize sizeWithMargins = geometry().size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); m_waylandEglWindow = wl_egl_window_create(mSurface, sizeWithMargins.width(), sizeWithMargins.height()); } if (!m_eglSurface) { m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); const_cast<QWaylandEglWindow *>(this)->m_format = q_glFormatFromConfig(m_eglIntegration->eglDisplay(),m_eglConfig); EGLNativeWindowType window = (EGLNativeWindowType) m_waylandEglWindow; m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0); } return m_eglSurface; }
void QEglFSWindow::create() { if (m_window) return; setWindowState(Qt::WindowFullScreen); if (window()->type() == Qt::Desktop) { QRect rect(QPoint(), m_sfc->screenSize()); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); return; } EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display(); QSurfaceFormat platformFormat = m_sfc->surfaceFormatFor(window()->requestedFormat()); m_config = QEglFSIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, m_config); resetSurface(); }
void QEglFSWindow::create() { if (m_window) return; if (window()->windowType() == Qt::Desktop) { QRect rect(QPoint(), hooks->screenSize()); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); return; } EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display(); QSurfaceFormat platformFormat = hooks->surfaceFormatFor(window()->requestedFormat()); EGLConfig config = q_configFromGLFormat(display, platformFormat); m_format = q_glFormatFromConfig(display, config); m_window = hooks->createNativeWindow(hooks->screenSize(), m_format); m_surface = eglCreateWindowSurface(display, config, m_window, NULL); if (m_surface == EGL_NO_SURFACE) { eglTerminate(display); qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", eglGetError()); } }
QT_BEGIN_NAMESPACE /*! \class QEGLPbuffer \brief A pbuffer-based implementation of QPlatformOffscreenSurface for EGL. \since 5.2 \internal \ingroup qpa To use this implementation in the platform plugin simply reimplement QPlatformIntegration::createPlatformOffscreenSurface() and return a new instance of this class. */ QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) , m_format(format) , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT); if (config) { const EGLint attributes[] = { EGL_WIDTH, offscreenSurface->size().width(), EGL_HEIGHT, offscreenSurface->size().height(), EGL_LARGEST_PBUFFER, EGL_FALSE, EGL_NONE }; m_pbuffer = eglCreatePbufferSurface(m_display, config, attributes); if (m_pbuffer != EGL_NO_SURFACE) m_format = q_glFormatFromConfig(m_display, config); } }
QT_BEGIN_NAMESPACE QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) , m_format(format) , m_display(display) , m_pbuffer(EGL_NO_SURFACE) { EGLConfig config = q_configFromGLFormat(m_display, m_format, false, EGL_PBUFFER_BIT); if (config) { const EGLint attributes[] = { EGL_WIDTH, offscreenSurface->size().width(), EGL_HEIGHT, offscreenSurface->size().height(), EGL_LARGEST_PBUFFER, EGL_FALSE, EGL_NONE }; m_pbuffer = eglCreatePbufferSurface(m_display, config, attributes); if (m_pbuffer != EGL_NO_SURFACE) m_format = q_glFormatFromConfig(m_display, config); } }
QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) : QPlatformOpenGLContext(), m_glContext(glContext), m_currentEglSurface(EGL_NO_SURFACE) { qGLContextDebug() << Q_FUNC_INFO; QSurfaceFormat format = m_glContext->format(); // Set current rendering API EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); if (eglResult != EGL_TRUE) qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); // Get colour channel sizes from window format int alphaSize = format.alphaBufferSize(); int redSize = format.redBufferSize(); int greenSize = format.greenBufferSize(); int blueSize = format.blueBufferSize(); // Check if all channels are don't care if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { // Set colour channels based on depth of window's screen QQnxScreen *screen = static_cast<QQnxScreen*>(glContext->screen()->handle()); int depth = screen->depth(); if (depth == 32) { // SCREEN_FORMAT_RGBA8888 alphaSize = 8; redSize = 8; greenSize = 8; blueSize = 8; } else { // SCREEN_FORMAT_RGB565 alphaSize = 0; redSize = 5; greenSize = 6; blueSize = 5; } } else { // Choose best match based on supported pixel formats if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) { // SCREEN_FORMAT_RGB565 alphaSize = 0; redSize = 5; greenSize = 6; blueSize = 5; } else { // SCREEN_FORMAT_RGBA8888 alphaSize = 8; redSize = 8; greenSize = 8; blueSize = 8; } } // Update colour channel sizes in window format format.setAlphaBufferSize(alphaSize); format.setRedBufferSize(redSize); format.setGreenBufferSize(greenSize); format.setBlueBufferSize(blueSize); // Select EGL config based on requested window format m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format); if (m_eglConfig == 0) qFatal("QQnxGLContext: failed to find EGL config"); QQnxGLContext *glShareContext = static_cast<QQnxGLContext*>(m_glContext->shareHandle()); m_eglShareContext = glShareContext ? glShareContext->m_eglContext : EGL_NO_CONTEXT; m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext, contextAttrs(format)); if (m_eglContext == EGL_NO_CONTEXT) { checkEGLError("eglCreateContext"); qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError()); } // Query/cache window format of selected EGL config m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig); }
void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share) { m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig); // m_format now has the renderableType() resolved (it cannot be Default anymore) // but does not yet contain version, profile, options. m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; QVector<EGLint> contextAttrs; contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); contextAttrs.append(format.majorVersion()); const bool hasKHRCreateContext = q_hasEglExtension(m_eglDisplay, "EGL_KHR_create_context"); if (hasKHRCreateContext) { contextAttrs.append(EGL_CONTEXT_MINOR_VERSION_KHR); contextAttrs.append(format.minorVersion()); int flags = 0; // The debug bit is supported both for OpenGL and OpenGL ES. if (format.testOption(QSurfaceFormat::DebugContext)) flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; // The fwdcompat bit is only for OpenGL 3.0+. if (m_format.renderableType() == QSurfaceFormat::OpenGL && format.majorVersion() >= 3 && !format.testOption(QSurfaceFormat::DeprecatedFunctions)) flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; if (flags) { contextAttrs.append(EGL_CONTEXT_FLAGS_KHR); contextAttrs.append(flags); } // Profiles are OpenGL only and mandatory in 3.2+. The value is silently ignored for < 3.2. if (m_format.renderableType() == QSurfaceFormat::OpenGL) { contextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); contextAttrs.append(format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); } } contextAttrs.append(EGL_NONE); switch (m_format.renderableType()) { case QSurfaceFormat::OpenVG: m_api = EGL_OPENVG_API; break; #ifdef EGL_VERSION_1_4 case QSurfaceFormat::OpenGL: m_api = EGL_OPENGL_API; break; #endif // EGL_VERSION_1_4 default: m_api = EGL_OPENGL_ES_API; break; } eglBindAPI(m_api); m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData()); if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) { m_shareContext = 0; m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, 0, contextAttrs.constData()); } if (m_eglContext == EGL_NO_CONTEXT) { qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError()); return; } static const bool printConfig = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEBUG"); if (printConfig) { qDebug() << "Created context for format" << format << "with config:"; q_printEglConfig(m_eglDisplay, m_eglConfig); } // Cannot just call updateFormatFromGL() since it relies on virtuals. Defer it to initialize(). }
void QEglFSKmsEglDeviceWindow::resetSurface() { qCDebug(qLcEglfsKmsDebug, "Creating stream"); EGLDisplay display = screen()->display(); EGLint streamAttribs[3]; int streamAttribCount = 0; int fifoLength = qEnvironmentVariableIntValue("QT_QPA_EGLFS_STREAM_FIFO_LENGTH"); if (fifoLength > 0) { streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR; streamAttribs[streamAttribCount++] = fifoLength; } streamAttribs[streamAttribCount++] = EGL_NONE; m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs); if (m_egl_stream == EGL_NO_STREAM_KHR) { qWarning("resetSurface: Couldn't create EGLStream for native window"); return; } qCDebug(qLcEglfsKmsDebug, "Created stream %p on display %p", m_egl_stream, display); EGLint count; if (m_integration->m_funcs->query_stream(display, m_egl_stream, EGL_STREAM_FIFO_LENGTH_KHR, &count)) { if (count > 0) qCDebug(qLcEglfsKmsDebug, "Using EGLStream FIFO mode with %d frames", count); else qCDebug(qLcEglfsKmsDebug, "Using EGLStream mailbox mode"); } else { qCDebug(qLcEglfsKmsDebug, "Could not query number of EGLStream FIFO frames"); } if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) { qWarning("No output layers found"); return; } qCDebug(qLcEglfsKmsDebug, "Output has %d layers", count); QVector<EGLOutputLayerEXT> layers; layers.resize(count); EGLint actualCount; if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) { qWarning("Failed to get layers"); return; } QEglFSKmsEglDeviceScreen *cur_screen = static_cast<QEglFSKmsEglDeviceScreen *>(screen()); Q_ASSERT(cur_screen); QKmsOutput &output(cur_screen->output()); const uint32_t wantedId = !output.wants_plane ? output.crtc_id : output.plane_id; qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", wantedId); EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT; for (int i = 0; i < actualCount; ++i) { EGLAttrib id; if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id); if (id == EGLAttrib(wantedId)) layer = layers[i]; } else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], (int) id); if (id == EGLAttrib(wantedId)) layer = layers[i]; } else { qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]); } } QByteArray reqLayerIndex = qgetenv("QT_QPA_EGLFS_LAYER_INDEX"); if (!reqLayerIndex.isEmpty()) { int idx = reqLayerIndex.toInt(); if (idx >= 0 && idx < layers.count()) { qCDebug(qLcEglfsKmsDebug, "EGLOutput layer index override = %d", idx); layer = layers[idx]; } } if (layer == EGL_NO_OUTPUT_LAYER_EXT) { qWarning("resetSurface: Couldn't get EGLOutputLayer for native window"); return; } qCDebug(qLcEglfsKmsDebug, "Using layer %p", layer); if (!m_integration->m_funcs->stream_consumer_output(display, m_egl_stream, layer)) qWarning("resetSurface: Unable to connect stream"); m_config = QEglFSDeviceIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); m_format = q_glFormatFromConfig(display, m_config); qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; const int w = cur_screen->rawGeometry().width(); const int h = cur_screen->rawGeometry().height(); qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); const EGLint stream_producer_attribs[] = { EGL_WIDTH, w, EGL_HEIGHT, h, EGL_NONE }; m_surface = m_integration->m_funcs->create_stream_producer_surface(display, m_config, m_egl_stream, stream_producer_attribs); if (m_surface == EGL_NO_SURFACE) return; qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface); }