Changeset View
Changeset View
Standalone View
Standalone View
plugins/platforms/drm/egl_stream_backend.cpp
Show All 25 Lines | |||||
26 | #include "logging.h" | 26 | #include "logging.h" | ||
27 | #include "logind.h" | 27 | #include "logind.h" | ||
28 | #include "options.h" | 28 | #include "options.h" | ||
29 | #include "scene.h" | 29 | #include "scene.h" | ||
30 | #include "screens.h" | 30 | #include "screens.h" | ||
31 | #include "wayland_server.h" | 31 | #include "wayland_server.h" | ||
32 | #include <kwinglplatform.h> | 32 | #include <kwinglplatform.h> | ||
33 | #include <QOpenGLContext> | 33 | #include <QOpenGLContext> | ||
34 | #include <KWayland/Server/surface_interface.h> | 34 | #include <KWaylandServer/surface_interface.h> | ||
35 | #include <KWayland/Server/buffer_interface.h> | 35 | #include <KWaylandServer/buffer_interface.h> | ||
36 | #include <KWayland/Server/eglstream_controller_interface.h> | 36 | #include <KWaylandServer/eglstream_controller_interface.h> | ||
37 | #include <KWayland/Server/display.h> | 37 | #include <KWaylandServer/display.h> | ||
38 | #include <KWayland/Server/resource.h> | 38 | #include <KWaylandServer/resource.h> | ||
39 | #include <wayland-server-core.h> | 39 | #include <wayland-server-core.h> | ||
40 | 40 | | |||
41 | namespace KWin | 41 | namespace KWin | ||
42 | { | 42 | { | ||
43 | 43 | | |||
44 | typedef EGLStreamKHR (*PFNEGLCREATESTREAMATTRIBNV)(EGLDisplay, EGLAttrib *); | 44 | typedef EGLStreamKHR (*PFNEGLCREATESTREAMATTRIBNV)(EGLDisplay, EGLAttrib *); | ||
45 | typedef EGLBoolean (*PFNEGLGETOUTPUTLAYERSEXT)(EGLDisplay, EGLAttrib *, EGLOutputLayerEXT *, EGLint, EGLint *); | 45 | typedef EGLBoolean (*PFNEGLGETOUTPUTLAYERSEXT)(EGLDisplay, EGLAttrib *, EGLOutputLayerEXT *, EGLint, EGLint *); | ||
46 | typedef EGLBoolean (*PFNEGLSTREAMCONSUMEROUTPUTEXT)(EGLDisplay, EGLStreamKHR, EGLOutputLayerEXT); | 46 | typedef EGLBoolean (*PFNEGLSTREAMCONSUMEROUTPUTEXT)(EGLDisplay, EGLStreamKHR, EGLOutputLayerEXT); | ||
▲ Show 20 Lines • Show All 158 Lines • ▼ Show 20 Line(s) | 132 | { | |||
205 | pEglStreamConsumerAcquireAttribNV = (PFNEGLSTREAMCONSUMERACQUIREATTRIBNV)eglGetProcAddress("eglStreamConsumerAcquireAttribNV"); | 205 | pEglStreamConsumerAcquireAttribNV = (PFNEGLSTREAMCONSUMERACQUIREATTRIBNV)eglGetProcAddress("eglStreamConsumerAcquireAttribNV"); | ||
206 | pEglStreamConsumerGLTextureExternalKHR = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHR)eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR"); | 206 | pEglStreamConsumerGLTextureExternalKHR = (PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHR)eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR"); | ||
207 | pEglQueryStreamAttribNV = (PFNEGLQUERYSTREAMATTRIBNV)eglGetProcAddress("eglQueryStreamAttribNV"); | 207 | pEglQueryStreamAttribNV = (PFNEGLQUERYSTREAMATTRIBNV)eglGetProcAddress("eglQueryStreamAttribNV"); | ||
208 | pEglStreamConsumerReleaseKHR = (PFNEGLSTREAMCONSUMERRELEASEKHR)eglGetProcAddress("eglStreamConsumerReleaseKHR"); | 208 | pEglStreamConsumerReleaseKHR = (PFNEGLSTREAMCONSUMERRELEASEKHR)eglGetProcAddress("eglStreamConsumerReleaseKHR"); | ||
209 | pEglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL)eglGetProcAddress("eglQueryWaylandBufferWL"); | 209 | pEglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL)eglGetProcAddress("eglQueryWaylandBufferWL"); | ||
210 | return true; | 210 | return true; | ||
211 | } | 211 | } | ||
212 | 212 | | |||
213 | EglStreamBackend::StreamTexture *EglStreamBackend::lookupStreamTexture(KWayland::Server::SurfaceInterface *surface) | 213 | EglStreamBackend::StreamTexture *EglStreamBackend::lookupStreamTexture(KWaylandServer::SurfaceInterface *surface) | ||
214 | { | 214 | { | ||
215 | auto it = m_streamTextures.find(surface); | 215 | auto it = m_streamTextures.find(surface); | ||
216 | return it != m_streamTextures.end() ? | 216 | return it != m_streamTextures.end() ? | ||
217 | &it.value() : | 217 | &it.value() : | ||
218 | nullptr; | 218 | nullptr; | ||
219 | } | 219 | } | ||
220 | 220 | | |||
221 | void EglStreamBackend::attachStreamConsumer(KWayland::Server::SurfaceInterface *surface, | 221 | void EglStreamBackend::attachStreamConsumer(KWaylandServer::SurfaceInterface *surface, | ||
222 | void *eglStream, | 222 | void *eglStream, | ||
223 | wl_array *attribs) | 223 | wl_array *attribs) | ||
224 | { | 224 | { | ||
225 | QVector<EGLAttrib> streamAttribs; | 225 | QVector<EGLAttrib> streamAttribs; | ||
226 | streamAttribs << EGL_WAYLAND_EGLSTREAM_WL << (EGLAttrib)eglStream; | 226 | streamAttribs << EGL_WAYLAND_EGLSTREAM_WL << (EGLAttrib)eglStream; | ||
227 | EGLAttrib *attribArray = (EGLAttrib *)attribs->data; | 227 | EGLAttrib *attribArray = (EGLAttrib *)attribs->data; | ||
228 | for (unsigned int i = 0; i < attribs->size; ++i) { | 228 | for (unsigned int i = 0; i < attribs->size; ++i) { | ||
229 | streamAttribs << attribArray[i]; | 229 | streamAttribs << attribArray[i]; | ||
Show All 13 Lines | 241 | if (st != nullptr) { | |||
243 | st->stream = stream; | 243 | st->stream = stream; | ||
244 | texture = st->texture; | 244 | texture = st->texture; | ||
245 | } else { | 245 | } else { | ||
246 | StreamTexture newSt = { stream, 0 }; | 246 | StreamTexture newSt = { stream, 0 }; | ||
247 | glGenTextures(1, &newSt.texture); | 247 | glGenTextures(1, &newSt.texture); | ||
248 | m_streamTextures.insert(surface, newSt); | 248 | m_streamTextures.insert(surface, newSt); | ||
249 | texture = newSt.texture; | 249 | texture = newSt.texture; | ||
250 | 250 | | |||
251 | connect(surface, &KWayland::Server::Resource::unbound, this, | 251 | connect(surface, &KWaylandServer::Resource::unbound, this, | ||
252 | [surface, this]() { | 252 | [surface, this]() { | ||
253 | const StreamTexture &st = m_streamTextures.take(surface); | 253 | const StreamTexture &st = m_streamTextures.take(surface); | ||
254 | pEglDestroyStreamKHR(eglDisplay(), st.stream); | 254 | pEglDestroyStreamKHR(eglDisplay(), st.stream); | ||
255 | glDeleteTextures(1, &st.texture); | 255 | glDeleteTextures(1, &st.texture); | ||
256 | }); | 256 | }); | ||
257 | } | 257 | } | ||
258 | 258 | | |||
259 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); | 259 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); | ||
Show All 18 Lines | 277 | if (!initRenderingContext()) { | |||
278 | setFailed("Failed to initialize rendering context"); | 278 | setFailed("Failed to initialize rendering context"); | ||
279 | return; | 279 | return; | ||
280 | } | 280 | } | ||
281 | 281 | | |||
282 | initKWinGL(); | 282 | initKWinGL(); | ||
283 | setSupportsBufferAge(false); | 283 | setSupportsBufferAge(false); | ||
284 | initWayland(); | 284 | initWayland(); | ||
285 | 285 | | |||
286 | using namespace KWayland::Server; | 286 | using namespace KWaylandServer; | ||
287 | m_eglStreamControllerInterface = waylandServer()->display()->createEglStreamControllerInterface(); | 287 | m_eglStreamControllerInterface = waylandServer()->display()->createEglStreamControllerInterface(); | ||
288 | connect(m_eglStreamControllerInterface, &EglStreamControllerInterface::streamConsumerAttached, this, | 288 | connect(m_eglStreamControllerInterface, &EglStreamControllerInterface::streamConsumerAttached, this, | ||
289 | &EglStreamBackend::attachStreamConsumer); | 289 | &EglStreamBackend::attachStreamConsumer); | ||
290 | m_eglStreamControllerInterface->create(); | 290 | m_eglStreamControllerInterface->create(); | ||
291 | if (!m_eglStreamControllerInterface->isValid()) { | 291 | if (!m_eglStreamControllerInterface->isValid()) { | ||
292 | setFailed("failed to initialize wayland-eglstream-controller interface"); | 292 | setFailed("failed to initialize wayland-eglstream-controller interface"); | ||
293 | } | 293 | } | ||
294 | } | 294 | } | ||
▲ Show 20 Lines • Show All 318 Lines • ▼ Show 20 Line(s) | 586 | { | |||
613 | glDisable(GL_TEXTURE_EXTERNAL_OES); | 613 | glDisable(GL_TEXTURE_EXTERNAL_OES); | ||
614 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); | 614 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); | ||
615 | glBindRenderbuffer(GL_RENDERBUFFER, 0); | 615 | glBindRenderbuffer(GL_RENDERBUFFER, 0); | ||
616 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | 616 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
617 | glUseProgram(oldProgram); | 617 | glUseProgram(oldProgram); | ||
618 | glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); | 618 | glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); | ||
619 | } | 619 | } | ||
620 | 620 | | |||
621 | bool EglStreamTexture::attachBuffer(KWayland::Server::BufferInterface *buffer) | 621 | bool EglStreamTexture::attachBuffer(KWaylandServer::BufferInterface *buffer) | ||
622 | { | 622 | { | ||
623 | QSize oldSize = m_size; | 623 | QSize oldSize = m_size; | ||
624 | m_size = buffer->size(); | 624 | m_size = buffer->size(); | ||
625 | GLenum oldFormat = m_format; | 625 | GLenum oldFormat = m_format; | ||
626 | m_format = buffer->hasAlphaChannel() ? GL_RGBA : GL_RGB; | 626 | m_format = buffer->hasAlphaChannel() ? GL_RGBA : GL_RGB; | ||
627 | 627 | | |||
628 | EGLint yInverted, wasYInverted = texture()->isYInverted(); | 628 | EGLint yInverted, wasYInverted = texture()->isYInverted(); | ||
629 | if (!pEglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), EGL_WAYLAND_Y_INVERTED_WL, &yInverted)) { | 629 | if (!pEglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), EGL_WAYLAND_Y_INVERTED_WL, &yInverted)) { | ||
630 | yInverted = EGL_TRUE; | 630 | yInverted = EGL_TRUE; | ||
631 | } | 631 | } | ||
632 | texture()->setYInverted(yInverted); | 632 | texture()->setYInverted(yInverted); | ||
633 | updateMatrix(); | 633 | updateMatrix(); | ||
634 | 634 | | |||
635 | return oldSize != m_size || | 635 | return oldSize != m_size || | ||
636 | oldFormat != m_format || | 636 | oldFormat != m_format || | ||
637 | wasYInverted != texture()->isYInverted(); | 637 | wasYInverted != texture()->isYInverted(); | ||
638 | } | 638 | } | ||
639 | 639 | | |||
640 | bool EglStreamTexture::loadTexture(WindowPixmap *pixmap) | 640 | bool EglStreamTexture::loadTexture(WindowPixmap *pixmap) | ||
641 | { | 641 | { | ||
642 | using namespace KWayland::Server; | 642 | using namespace KWaylandServer; | ||
643 | SurfaceInterface *surface = pixmap->surface(); | 643 | SurfaceInterface *surface = pixmap->surface(); | ||
644 | const EglStreamBackend::StreamTexture *st = m_backend->lookupStreamTexture(surface); | 644 | const EglStreamBackend::StreamTexture *st = m_backend->lookupStreamTexture(surface); | ||
645 | if (!pixmap->buffer().isNull() && st != nullptr) { | 645 | if (!pixmap->buffer().isNull() && st != nullptr) { | ||
646 | 646 | | |||
647 | glGenTextures(1, &m_texture); | 647 | glGenTextures(1, &m_texture); | ||
648 | texture()->setWrapMode(GL_CLAMP_TO_EDGE); | 648 | texture()->setWrapMode(GL_CLAMP_TO_EDGE); | ||
649 | texture()->setFilter(GL_LINEAR); | 649 | texture()->setFilter(GL_LINEAR); | ||
650 | 650 | | |||
Show All 11 Lines | |||||
662 | } else { | 662 | } else { | ||
663 | // Not an EGLStream surface | 663 | // Not an EGLStream surface | ||
664 | return AbstractEglTexture::loadTexture(pixmap); | 664 | return AbstractEglTexture::loadTexture(pixmap); | ||
665 | } | 665 | } | ||
666 | } | 666 | } | ||
667 | 667 | | |||
668 | void EglStreamTexture::updateTexture(WindowPixmap *pixmap) | 668 | void EglStreamTexture::updateTexture(WindowPixmap *pixmap) | ||
669 | { | 669 | { | ||
670 | using namespace KWayland::Server; | 670 | using namespace KWaylandServer; | ||
671 | SurfaceInterface *surface = pixmap->surface(); | 671 | SurfaceInterface *surface = pixmap->surface(); | ||
672 | const EglStreamBackend::StreamTexture *st = m_backend->lookupStreamTexture(surface); | 672 | const EglStreamBackend::StreamTexture *st = m_backend->lookupStreamTexture(surface); | ||
673 | if (!pixmap->buffer().isNull() && st != nullptr) { | 673 | if (!pixmap->buffer().isNull() && st != nullptr) { | ||
674 | 674 | | |||
675 | if (attachBuffer(surface->buffer())) { | 675 | if (attachBuffer(surface->buffer())) { | ||
676 | createFbo(); | 676 | createFbo(); | ||
677 | } | 677 | } | ||
678 | surface->resetTrackedDamage(); | 678 | surface->resetTrackedDamage(); | ||
Show All 14 Lines |