QPlatformOpenGLContext *EglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QPlatformOpenGLContext *pctx = egl_device_integration()->createPlatformOpenGLContext(context); if (pctx) return pctx; // If there is a "root" window into which raster and QOpenGLWidget content is // composited, all other contexts must share with its context. QOpenGLContext *compositingContext = OpenGLCompositor::instance()->context(); EGLDisplay dpy = context->screen() ? static_cast<EglFSScreen *>(context->screen()->handle())->display() : display(); QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); QVariant nativeHandle = context->nativeHandle(); EglFSContext *ctx; QSurfaceFormat adjustedFormat = egl_device_integration()->surfaceFormatFor(context->format()); if (nativeHandle.isNull()) { EGLConfig config = EglFSIntegration::chooseConfig(dpy, adjustedFormat); ctx = new EglFSContext(adjustedFormat, share, dpy, &config, QVariant()); } else { ctx = new EglFSContext(adjustedFormat, share, dpy, 0, nativeHandle); } nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy)); context->setNativeHandle(nativeHandle); return ctx; }
QPlatformOffscreenSurface *EglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { EGLDisplay dpy = surface->screen() ? static_cast<EglFSScreen *>(surface->screen()->handle())->display() : display(); QSurfaceFormat fmt = egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); if (egl_device_integration()->supportsPBuffers()) return new EGLPbuffer(dpy, fmt, surface); else return new EglFSOffscreenWindow(dpy, fmt, surface); // Never return null. Multiple QWindows are not supported by this plugin. }
EglFSOffscreenWindow::~EglFSOffscreenWindow() { if (m_surface != EGL_NO_SURFACE) eglDestroySurface(m_display, m_surface); if (m_window) egl_device_integration()->destroyNativeWindow(m_window); }
EGLConfig EglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) { class Chooser : public EglConfigChooser { public: Chooser(EGLDisplay display) : EglConfigChooser(display) { } bool filterConfig(EGLConfig config) const Q_DECL_OVERRIDE { return egl_device_integration()->filterConfig(display(), config) && EglConfigChooser::filterConfig(config); } };
QPlatformBackingStore *EglFSIntegration::createPlatformBackingStore(QWindow *window) const { QPlatformBackingStore *pbs = egl_device_integration()->createPlatformBackingStore(window); if (pbs) return pbs; OpenGLCompositorBackingStore *bs = new OpenGLCompositorBackingStore(window); if (!window->handle()) window->create(); static_cast<EglFSWindow *>(window->handle())->setBackingStore(bs); return bs; }
bool EglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const { // We assume that devices will have more and not less capabilities if (egl_device_integration()->hasCapability(cap)) return true; switch (cap) { case ThreadedPixmaps: return true; case OpenGL: return true; case ThreadedOpenGL: return true; case WindowManagement: return false; case RasterGLSurface: return true; default: return QPlatformIntegration::hasCapability(cap); } }
QPlatformWindow *EglFSIntegration::createPlatformWindow(QWindow *window) const { QWindowSystemInterface::flushWindowSystemEvents(); QPlatformWindow *w = egl_device_integration()->createPlatformWindow(window); if (!w) { w = new EglFSWindow(window); static_cast<EglFSWindow *>(w)->create(); } // Activate only the compositor window for the primary screen in order to // make keyboard input work if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen()) w->requestActivateWindow(); return w; }
EglFSOffscreenWindow::EglFSOffscreenWindow(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 = egl_device_integration()->createNativeOffscreenWindow(format); if (!m_window) { qCWarning(lcDeviceIntegration, "EglFSOffscreenWindow: Failed to create native window"); return; } EGLConfig config = EglUtils::configFromGLFormat(m_display, m_format); m_surface = eglCreateWindowSurface(m_display, config, m_window, 0); if (m_surface != EGL_NO_SURFACE) m_format = EglUtils::glFormatFromConfig(m_display, config); }
void *EglFSIntegration::nativeResourceForIntegration(const QByteArray &resource) { void *result = 0; switch (resourceType(resource)) { case EglDisplay: result = display(); break; case NativeDisplay: result = reinterpret_cast<void*>(nativeDisplay()); break; case WaylandDisplay: result = egl_device_integration()->wlDisplay(); break; default: break; } return result; }