Changeset View
Changeset View
Standalone View
Standalone View
src/waylandintegration.cpp
Show First 20 Lines • Show All 110 Lines • ▼ Show 20 Line(s) | 110 | { | |||
---|---|---|---|---|---|
111 | globalWaylandIntegration->requestPointerAxisDiscrete(axis, delta); | 111 | globalWaylandIntegration->requestPointerAxisDiscrete(axis, delta); | ||
112 | } | 112 | } | ||
113 | 113 | | |||
114 | void WaylandIntegration::requestKeyboardKeycode(int keycode, bool state) | 114 | void WaylandIntegration::requestKeyboardKeycode(int keycode, bool state) | ||
115 | { | 115 | { | ||
116 | globalWaylandIntegration->requestKeyboardKeycode(keycode, state); | 116 | globalWaylandIntegration->requestKeyboardKeycode(keycode, state); | ||
117 | } | 117 | } | ||
118 | 118 | | |||
119 | WaylandIntegration::EGLStruct WaylandIntegration::egl() | ||||
120 | { | ||||
121 | return globalWaylandIntegration->egl(); | ||||
122 | } | ||||
123 | | ||||
119 | QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::screens() | 124 | QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::screens() | ||
120 | { | 125 | { | ||
121 | return globalWaylandIntegration->screens(); | 126 | return globalWaylandIntegration->screens(); | ||
122 | } | 127 | } | ||
123 | 128 | | |||
124 | QVariant WaylandIntegration::streams() | 129 | QVariant WaylandIntegration::streams() | ||
125 | { | 130 | { | ||
126 | return globalWaylandIntegration->streams(); | 131 | return globalWaylandIntegration->streams(); | ||
127 | } | 132 | } | ||
128 | 133 | | |||
129 | WaylandIntegration::WaylandIntegration * WaylandIntegration::waylandIntegration() | 134 | WaylandIntegration::WaylandIntegration * WaylandIntegration::waylandIntegration() | ||
130 | { | 135 | { | ||
131 | return globalWaylandIntegration; | 136 | return globalWaylandIntegration; | ||
132 | } | 137 | } | ||
133 | 138 | | |||
134 | static const char * formatGLError(GLenum err) | 139 | const char * WaylandIntegration::formatGLError(GLenum err) | ||
135 | { | 140 | { | ||
136 | switch(err) { | 141 | switch(err) { | ||
137 | case GL_NO_ERROR: | 142 | case GL_NO_ERROR: | ||
138 | return "GL_NO_ERROR"; | 143 | return "GL_NO_ERROR"; | ||
139 | case GL_INVALID_ENUM: | 144 | case GL_INVALID_ENUM: | ||
140 | return "GL_INVALID_ENUM"; | 145 | return "GL_INVALID_ENUM"; | ||
141 | case GL_INVALID_VALUE: | 146 | case GL_INVALID_VALUE: | ||
142 | return "GL_INVALID_VALUE"; | 147 | return "GL_INVALID_VALUE"; | ||
▲ Show 20 Lines • Show All 243 Lines • ▼ Show 20 Line(s) | 390 | if (m_streamInput && m_fakeInput) { | |||
386 | if (state) { | 391 | if (state) { | ||
387 | m_fakeInput->requestKeyboardKeyPress(keycode); | 392 | m_fakeInput->requestKeyboardKeyPress(keycode); | ||
388 | } else { | 393 | } else { | ||
389 | m_fakeInput->requestKeyboardKeyRelease(keycode); | 394 | m_fakeInput->requestKeyboardKeyRelease(keycode); | ||
390 | } | 395 | } | ||
391 | } | 396 | } | ||
392 | } | 397 | } | ||
393 | 398 | | |||
399 | WaylandIntegration::EGLStruct WaylandIntegration::WaylandIntegrationPrivate::egl() | ||||
400 | { | ||||
401 | return m_egl; | ||||
402 | } | ||||
403 | | ||||
394 | QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::WaylandIntegrationPrivate::screens() | 404 | QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::WaylandIntegrationPrivate::screens() | ||
395 | { | 405 | { | ||
396 | return m_outputMap; | 406 | return m_outputMap; | ||
397 | } | 407 | } | ||
398 | 408 | | |||
399 | QVariant WaylandIntegration::WaylandIntegrationPrivate::streams() | 409 | QVariant WaylandIntegration::WaylandIntegrationPrivate::streams() | ||
400 | { | 410 | { | ||
401 | Stream stream; | 411 | Stream stream; | ||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Line(s) | 566 | { | |||
586 | gbm_import_fd_data importInfo = {gbmHandle, width, height, stride, format}; | 596 | gbm_import_fd_data importInfo = {gbmHandle, width, height, stride, format}; | ||
587 | gbm_bo *imported = gbm_bo_import(m_gbmDevice, GBM_BO_IMPORT_FD, &importInfo, GBM_BO_USE_SCANOUT); | 597 | gbm_bo *imported = gbm_bo_import(m_gbmDevice, GBM_BO_IMPORT_FD, &importInfo, GBM_BO_USE_SCANOUT); | ||
588 | if (!imported) { | 598 | if (!imported) { | ||
589 | qCWarning(XdgDesktopPortalKdeWaylandIntegration) << "Failed to process buffer: Cannot import passed GBM fd - " << strerror(errno); | 599 | qCWarning(XdgDesktopPortalKdeWaylandIntegration) << "Failed to process buffer: Cannot import passed GBM fd - " << strerror(errno); | ||
590 | close(gbmHandle); | 600 | close(gbmHandle); | ||
591 | return; | 601 | return; | ||
592 | } | 602 | } | ||
593 | 603 | | |||
594 | // bind context to render thread | 604 | if (m_stream->recordFrame(imported, width, height, stride)) { | ||
595 | eglMakeCurrent(m_egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, m_egl.context); | | |||
596 | | ||||
597 | // create EGL image from imported BO | | |||
598 | EGLImageKHR image = eglCreateImageKHR(m_egl.display, nullptr, EGL_NATIVE_PIXMAP_KHR, imported, nullptr); | | |||
599 | | ||||
600 | // We can already close gbm handle | | |||
601 | gbm_bo_destroy(imported); | | |||
602 | close(gbmHandle); | | |||
603 | | ||||
604 | if (image == EGL_NO_IMAGE_KHR) { | | |||
605 | qCWarning(XdgDesktopPortalKdeWaylandIntegration) << "Failed to process buffer: Error creating EGLImageKHR - " << formatGLError(glGetError()); | | |||
606 | return; | | |||
607 | } | | |||
608 | | ||||
609 | // create GL 2D texture for framebuffer | | |||
610 | GLuint texture; | | |||
611 | glGenTextures(1, &texture); | | |||
612 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | | |||
613 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | | |||
614 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | | |||
615 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | | |||
616 | glBindTexture(GL_TEXTURE_2D, texture); | | |||
617 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); | | |||
618 | | ||||
619 | // bind framebuffer to copy pixels from | | |||
620 | GLuint framebuffer; | | |||
621 | glGenFramebuffers(1, &framebuffer); | | |||
622 | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); | | |||
623 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); | | |||
624 | const GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); | | |||
625 | if (status != GL_FRAMEBUFFER_COMPLETE) { | | |||
626 | qCWarning(XdgDesktopPortalKdeWaylandIntegration) << "Failed to process buffer: glCheckFramebufferStatus failed - " << formatGLError(glGetError()); | | |||
627 | glDeleteTextures(1, &texture); | | |||
628 | glDeleteFramebuffers(1, &framebuffer); | | |||
629 | eglDestroyImageKHR(m_egl.display, image); | | |||
630 | return; | | |||
631 | } | | |||
632 | | ||||
633 | auto capture = new QImage(QSize(width, height), QImage::Format_RGBA8888); | | |||
634 | glViewport(0, 0, width, height); | | |||
635 | glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, capture->bits()); | | |||
636 | | ||||
637 | if (m_stream->recordFrame(capture->bits())) { | | |||
638 | m_lastFrameTime = QDateTime::currentDateTime(); | 605 | m_lastFrameTime = QDateTime::currentDateTime(); | ||
639 | } | 606 | } | ||
640 | 607 | | |||
641 | glDeleteTextures(1, &texture); | 608 | gbm_bo_destroy(imported); | ||
642 | glDeleteFramebuffers(1, &framebuffer); | 609 | close(gbmHandle); | ||
643 | eglDestroyImageKHR(m_egl.display, image); | | |||
644 | | ||||
645 | delete capture; | | |||
646 | } | 610 | } | ||
647 | 611 | | |||
648 | void WaylandIntegration::WaylandIntegrationPrivate::setupRegistry() | 612 | void WaylandIntegration::WaylandIntegrationPrivate::setupRegistry() | ||
649 | { | 613 | { | ||
650 | m_queue = new KWayland::Client::EventQueue(this); | 614 | m_queue = new KWayland::Client::EventQueue(this); | ||
651 | m_queue->setup(m_connection); | 615 | m_queue->setup(m_connection); | ||
652 | 616 | | |||
653 | m_registry = new KWayland::Client::Registry(this); | 617 | m_registry = new KWayland::Client::Registry(this); | ||
Show All 16 Lines |