diff options
17 files changed, 52 insertions, 66 deletions
diff --git a/examples/qwindow-compositor/qwindowcompositor.cpp b/examples/qwindow-compositor/qwindowcompositor.cpp index 7fe8facc4..8e71ef069 100644 --- a/examples/qwindow-compositor/qwindowcompositor.cpp +++ b/examples/qwindow-compositor/qwindowcompositor.cpp @@ -247,7 +247,7 @@ GLuint QWindowCompositor::composeSurface(QWaylandSurface *surface) if (surface->type() == QWaylandSurface::Shm) { texture = m_textureCache->bindTexture(QOpenGLContext::currentContext(),surface->image()); } else if (surface->type() == QWaylandSurface::Texture) { - texture = surface->texture(QOpenGLContext::currentContext()); + texture = surface->texture(); } functions->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, @@ -272,7 +272,7 @@ void QWindowCompositor::paintChildren(QWaylandSurface *surface, QWaylandSurface if (subSurface->size().isValid()) { GLuint texture = 0; if (subSurface->type() == QWaylandSurface::Texture) { - texture = subSurface->texture(QOpenGLContext::currentContext()); + texture = subSurface->texture(); } else if (surface->type() == QWaylandSurface::Shm ) { texture = m_textureCache->bindTexture(QOpenGLContext::currentContext(),surface->image()); } diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 290febdf9..293ff932e 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -208,13 +208,13 @@ QImage QWaylandSurface::image() const } #ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint QWaylandSurface::texture(QOpenGLContext *context) const +GLuint QWaylandSurface::texture() const { Q_D(const QWaylandSurface); - return d->surface->textureId(context); + return d->surface->textureId(); } #else //QT_COMPOSITOR_WAYLAND_GL -uint QWaylandSurface::texture(QOpenGLContext *) const +uint QWaylandSurface::texture() const { return 0; } diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index fee299fce..18d4e7e75 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -48,7 +48,6 @@ #include <QtGui/QWindow> #include <QtCore/QVariantMap> -#include <QtGui/QOpenGLContext> #ifdef QT_COMPOSITOR_WAYLAND_GL #include <QtGui/qopengl.h> #endif @@ -136,9 +135,9 @@ public: QImage image() const; #ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint texture(QOpenGLContext *context) const; + GLuint texture() const; #else - uint texture(QOpenGLContext *context) const; + uint texture() const; #endif QWindow::Visibility visibility() const; diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp index cc753934b..55765c75c 100644 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp @@ -365,12 +365,11 @@ void QWaylandSurfaceItem::updateTexture() m_damaged = false; QSGTexture *oldTexture = texture; if (m_surface->type() == QWaylandSurface::Texture) { - QOpenGLContext *context = QOpenGLContext::currentContext(); QQuickWindow::CreateTextureOptions opt = 0; if (useTextureAlpha()) { opt |= QQuickWindow::TextureHasAlphaChannel; } - texture = window()->createTextureFromId(m_surface->texture(context), m_surface->size(), opt); + texture = window()->createTextureFromId(m_surface->texture(), m_surface->size(), opt); } else { texture = window()->createTextureFromImage(m_surface->image()); } diff --git a/src/compositor/hardware_integration/qwaylandclientbufferintegration.h b/src/compositor/hardware_integration/qwaylandclientbufferintegration.h index 6451f6156..b3f305001 100644 --- a/src/compositor/hardware_integration/qwaylandclientbufferintegration.h +++ b/src/compositor/hardware_integration/qwaylandclientbufferintegration.h @@ -63,10 +63,14 @@ public: virtual void initializeHardware(QtWayland::Display *waylandDisplay) = 0; - /** Bind the Wayland buffer to the textureId. The correct context is the current context, - so there is no need to do makeCurrent in this function. - **/ - virtual GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) = 0; + // Used when the hardware integration wants to provide its own texture for a given buffer. + // In most cases the compositor creates and manages the texture so this is not needed. + virtual GLuint textureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return 0; } + virtual void destroyTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } + + // Called with the texture bound. + virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0; + virtual bool isYInverted(struct ::wl_resource *) const { return true; } virtual bool setDirectRenderSurface(QWaylandSurface *) {return false;} diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp index ba1175b04..2b410948c 100644 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ b/src/compositor/wayland_wrapper/qwlsurface.cpp @@ -204,14 +204,13 @@ QImage Surface::image() const } #ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint Surface::textureId(QOpenGLContext *context) const +GLuint Surface::textureId() const { const SurfaceBuffer *surfacebuffer = currentSurfaceBuffer(); if (m_compositor->clientBufferIntegration() && type() == QWaylandSurface::Texture && !surfacebuffer->textureCreated()) { - QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - const_cast<SurfaceBuffer *>(surfacebuffer)->createTexture(hwIntegration,context); + const_cast<SurfaceBuffer *>(surfacebuffer)->createTexture(); } return surfacebuffer->texture(); } diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h index 101d8938c..ea2134359 100644 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ b/src/compositor/wayland_wrapper/qwlsurface_p.h @@ -53,7 +53,6 @@ #include <QtCore/QMetaType> #ifdef QT_COMPOSITOR_WAYLAND_GL -#include <QtGui/QOpenGLContext> #include <QtGui/qopengl.h> #endif @@ -102,7 +101,7 @@ public: QImage image() const; #ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint textureId(QOpenGLContext *context) const; + GLuint textureId() const; #endif void sendFrameCallback(); diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index cdc7b33ee..905700318 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -218,12 +218,16 @@ void SurfaceBuffer::destroyTexture() { #ifdef QT_COMPOSITOR_WAYLAND_GL if (m_texture) { - Q_ASSERT(m_guard); /* When QOpenGLSharedResourceGuard is freed, destroyTexture might be reentered - to cause double free. So clear m_texture first. */ + to cause double free. So clear m_texture first. */ m_texture = 0; - m_guard->free(); - m_guard = 0; + if (m_guard) { + m_guard->free(); + m_guard = 0; + } else { + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); + hwIntegration->destroyTextureForBuffer(m_buffer); + } } #endif } @@ -296,11 +300,18 @@ void freeTexture(QOpenGLFunctions *, GLuint id) glDeleteTextures(1, &id); } -void SurfaceBuffer::createTexture(QWaylandClientBufferIntegration *hwIntegration, QOpenGLContext *context) +void SurfaceBuffer::createTexture() { + QWaylandClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); #ifdef QT_COMPOSITOR_WAYLAND_GL - m_texture = hwIntegration->createTextureFromBuffer(m_buffer, context); - m_guard = new QOpenGLSharedResourceGuard(QOpenGLContext::currentContext(), m_texture, freeTexture); + if (!m_texture) + m_texture = hwIntegration->textureForBuffer(m_buffer); + if (!m_texture) { + glGenTextures(1, &m_texture); + m_guard = new QOpenGLSharedResourceGuard(QOpenGLContext::currentContext(), m_texture, freeTexture); + } + glBindTexture(GL_TEXTURE_2D, m_texture); + hwIntegration->bindTextureToBuffer(m_buffer); #else Q_UNUSED(hwIntegration); Q_UNUSED(context); diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 056303e1d..42c26e7da 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE class QWaylandClientBufferIntegration; -class QOpenGLContext; namespace QtWayland { @@ -99,7 +98,7 @@ public: inline bool textureCreated() const { return m_texture; } - void createTexture(QWaylandClientBufferIntegration *hwIntegration, QOpenGLContext *context); + void createTexture(); inline GLuint texture() const; void destroyTexture(); diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp index e5975abc3..a0be625dd 100644 --- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp @@ -124,30 +124,25 @@ void BrcmEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay) } } -GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void BrcmEglIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { Q_D(BrcmEglIntegration); if (!d->valid) { - qWarning("createTextureFromBuffer() failed\n"); - return 0; + qWarning("bindTextureToBuffer failed!"); + return; } BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer); if (!d->eglQueryGlobalImageBRCM(brcmBuffer->handle(), brcmBuffer->handle() + 2)) { qWarning("eglQueryGlobalImageBRCM failed!"); - return 0; + return; } EGLImageKHR image = d->eglCreateImageKHR(d->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)brcmBuffer->handle(), NULL); if (image == EGL_NO_IMAGE_KHR) qWarning("eglCreateImageKHR() failed: %x\n", eglGetError()); - GLuint textureId; - glGenTextures(1, &textureId); - - glBindTexture(GL_TEXTURE_2D, textureId); - d->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -156,8 +151,6 @@ GLuint BrcmEglIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); d->eglDestroyImageKHR(d->egl_display, image); - - return textureId; } bool BrcmEglIntegration::isYInverted(struct ::wl_resource *) const diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h index 7d94e315b..f6486ed4b 100644 --- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h @@ -58,7 +58,7 @@ public: void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void udpateTextureFromBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index bd77db63e..7cc140cd3 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -170,23 +170,18 @@ void WaylandEglClientBufferIntegration::initializeHardware(QtWayland::Display *w qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : ""); } -GLuint WaylandEglClientBufferIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { Q_D(WaylandEglClientBufferIntegration); if (!d->valid) { - qWarning("createTextureFromBuffer() failed\n"); - return 0; + qWarning("bindTextureToBuffer() failed"); + return; } EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, buffer, NULL); - GLuint textureId; - glGenTextures(1,&textureId); - - glBindTexture(GL_TEXTURE_2D, textureId); - d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -195,8 +190,6 @@ GLuint WaylandEglClientBufferIntegration::createTextureFromBuffer(struct ::wl_re glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); d->egl_destroy_image(d->egl_display, image); - - return textureId; } bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h index 2f93e9052..a289baa0d 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h @@ -56,7 +56,7 @@ public: void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; bool setDirectRenderSurface(QWaylandSurface *) Q_DECL_OVERRIDE; diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp index 55b0cc15e..c645b997f 100644 --- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp @@ -91,7 +91,7 @@ void XCompositeEglClientBufferIntegration::initializeHardware(QtWayland::Display new XCompositeHandler(m_compositor->handle(), mDisplay); } -GLuint XCompositeEglClientBufferIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer) { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); @@ -103,7 +103,7 @@ GLuint XCompositeEglClientBufferIntegration::createTextureFromBuffer(struct ::wl bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching); if (!matched || !matching) { qWarning("Could not retrieve a suitable EGL config"); - return 0; + return; } QVector<EGLint> attribList; @@ -121,17 +121,11 @@ GLuint XCompositeEglClientBufferIntegration::createTextureFromBuffer(struct ::wl compositorBuffer->setInvertedY(true); - GLuint textureId; - glGenTextures(1,&textureId); - glBindTexture(GL_TEXTURE_2D, textureId); - if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) { qDebug() << "Failed to bind"; } // eglDestroySurface(mEglDisplay,surface); - - return textureId; } bool XCompositeEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h index 65a574d1e..5497daed4 100644 --- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h @@ -56,7 +56,7 @@ public: void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp index 1df6a4c99..a58827cee 100644 --- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp @@ -112,7 +112,7 @@ void XCompositeGLXClientBufferIntegration::initializeHardware(QtWayland::Display delete glContext; } -GLuint XCompositeGLXClientBufferIntegration::createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *) +void XCompositeGLXClientBufferIntegration::updateTextureFromBuffer(struct ::wl_resource *buffer) { XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer); Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window()); @@ -135,14 +135,10 @@ GLuint XCompositeGLXClientBufferIntegration::createTextureFromBuffer(struct ::wl XFree(configs); - GLuint textureId; - glGenTextures(1,&textureId); - glBindTexture(GL_TEXTURE_2D, textureId); m_glxBindTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT, 0); //Do we need to change the api so that we do bind and release in the painevent? //The specification states that when deleting the texture the color buffer is deleted // m_glxReleaseTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT); - return textureId; } bool XCompositeGLXClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h index be6b02028..5a724eedf 100644 --- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h @@ -61,7 +61,7 @@ public: void initializeHardware(QtWayland::Display *waylandDisplay) Q_DECL_OVERRIDE; - GLuint createTextureFromBuffer(struct ::wl_resource *buffer, QOpenGLContext *context) Q_DECL_OVERRIDE; + void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE; bool isYInverted(struct ::wl_resource *) const Q_DECL_OVERRIDE; QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE; |