Wayland: put context & drawing objects into the drm surface
authorJesse Barnes <jbarnes@virtuousgeek.org>
Wed, 27 Oct 2010 21:38:03 +0000 (14:38 -0700)
committerJørgen Lind <jorgen.lind@nokia.com>
Tue, 25 Jan 2011 17:59:06 +0000 (18:59 +0100)
Even GL widgets will allocate window surfaces, so share everything
there.  This still leaves a hole when we mix GL widgets and the raster
back end (the created platform GL context won't have a DRM buffer to use
for its objects & context), but that won't work right now anyway...

src/plugins/platforms/wayland/qwaylandintegration.cpp
src/plugins/platforms/wayland/qwaylandwindowsurface.cpp
src/plugins/platforms/wayland/qwaylandwindowsurface.h

index 9ac22e8..6842dbf 100644 (file)
@@ -510,42 +510,21 @@ public:
     QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
 
 private:
-    EGLContext mContext;
     QPlatformWindowFormat mFormat;
     QWaylandDisplay *mDisplay;
     QWaylandWindow *mWindow;
-    GLuint mFbo, mRbo;
 };
 
 QWaylandGLContext::QWaylandGLContext(QWaylandDisplay *wd, QWaylandWindow *window, const QPlatformWindowFormat &format)
     : QPlatformGLContext()
-    , mContext(0)
     , mFormat(format)
     , mDisplay(wd)
     , mWindow(window)
 {
-    EGLDisplay eglDisplay;
-    static const EGLint contextAttribs[] = {
-       EGL_CONTEXT_CLIENT_VERSION, 2,
-       EGL_NONE
-    };
-
-    eglBindAPI(EGL_OPENGL_ES_API);
-    eglDisplay = mDisplay->eglDisplay();
-    mContext = eglCreateContext(eglDisplay, NULL,
-                               EGL_NO_CONTEXT, contextAttribs);
-    eglMakeCurrent(eglDisplay, NULL, NULL, mContext);
-
-    glGenFramebuffers(1, &mFbo);
-    glGenRenderbuffers(1, &mRbo);
 }
 
 QWaylandGLContext::~QWaylandGLContext()
 {
-    if (mContext)
-        eglDestroyContext(mDisplay->eglDisplay(), mContext);
-    glDeleteFramebuffers(1, &mFbo);
-    glDeleteRenderbuffers(1, &mRbo);
 }
 
 void QWaylandGLContext::makeCurrent()
@@ -553,21 +532,20 @@ void QWaylandGLContext::makeCurrent()
     QWaylandDrmBuffer *mBuffer = (QWaylandDrmBuffer *)mWindow->getBuffer();
     QRect geometry = mWindow->geometry();
 
-    eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
     if (!mBuffer)
        return;
-    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
-    glBindRenderbuffer(GL_RENDERBUFFER, mRbo);
+
+    eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mBuffer->mContext);
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mBuffer->mFbo);
+    glBindRenderbuffer(GL_RENDERBUFFER, mBuffer->mRbo);
     glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mBuffer->mImage);
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                                GL_RENDERBUFFER, mRbo);
+                                GL_RENDERBUFFER, mBuffer->mRbo);
 }
 
 void QWaylandGLContext::doneCurrent()
 {
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glBindRenderbuffer(GL_RENDERBUFFER, 0);
-    eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
 }
 
 void QWaylandGLContext::swapBuffers()
index 6e7fa89..4ae04be 100644 (file)
@@ -201,6 +201,10 @@ QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display,
     Q_UNUSED(format);
 
     EGLint name, stride;
+    static const EGLint contextAttribs[] = {
+       EGL_CONTEXT_CLIENT_VERSION, 2,
+       EGL_NONE
+    };
     EGLint imageAttribs[] = {
        EGL_WIDTH,                      0,
        EGL_HEIGHT,                     0,
@@ -209,9 +213,16 @@ QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display,
        EGL_NONE
     };
 
+    eglBindAPI(EGL_OPENGL_ES_API);
+    mContext = eglCreateContext(mDisplay->eglDisplay(), NULL,
+                               EGL_NO_CONTEXT, contextAttribs);
+    eglMakeCurrent(mDisplay->eglDisplay(), 0, 0, mContext);
+
     imageAttribs[1] = size.width();
     imageAttribs[3] = size.height();
     mImage = eglCreateDRMImageMESA(mDisplay->eglDisplay(), imageAttribs);
+    glGenFramebuffers(1, &mFbo);
+    glGenRenderbuffers(1, &mRbo);
     glGenTextures(1, &mTexture);
     glBindTexture(GL_TEXTURE_2D, mTexture);
     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
@@ -225,9 +236,12 @@ QWaylandDrmBuffer::QWaylandDrmBuffer(QWaylandDisplay *display,
 
 QWaylandDrmBuffer::~QWaylandDrmBuffer(void)
 {
+    glDeleteFramebuffers(1, &mFbo);
+    glDeleteRenderbuffers(1, &mRbo);
     glDeleteTextures(1, &mTexture);
     eglDestroyImageKHR(mDisplay->eglDisplay(), mImage);
     wl_buffer_destroy(mBuffer);
+    eglDestroyContext(mDisplay->eglDisplay(), mContext);
 }
 
 
@@ -237,7 +251,12 @@ QWaylandDrmWindowSurface::QWaylandDrmWindowSurface(QWidget *window,
     , mBuffer(0)
     , mDisplay(display)
 {
+    QWaylandWindow *ww = (QWaylandWindow *) window->platformWindow();
+    QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
+
     mPaintDevice = new QWaylandPaintDevice(display, window);
+    mBuffer = new QWaylandDrmBuffer(mDisplay, window->size(), format);
+    ww->attach(mBuffer);
 }
 
 QWaylandDrmWindowSurface::~QWaylandDrmWindowSurface()
index a033531..c8ccdb1 100644 (file)
@@ -93,11 +93,13 @@ public:
     QWaylandDrmBuffer(QWaylandDisplay *display,
                       const QSize &size, QImage::Format format);
     ~QWaylandDrmBuffer();
+    EGLContext mContext;
     EGLImageKHR mImage;
     GLuint mTexture;
     QWaylandDisplay *mDisplay;
     QGLFramebufferObject *pdev;
     QSize mSize;
+    GLuint mFbo, mRbo;
 };
 
 class QWaylandDrmWindowSurface : public QWindowSurface