Qt 4.8
qwaylandreadbackeglcontext.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
43 
44 #include "../../../eglconvenience/qeglconvenience.h"
45 
46 #include <QtOpenGL/QGLContext>
47 #include <QtOpenGL/private/qglextensions_p.h>
48 
49 #include "qwaylandshmsurface.h"
50 
51 #include <QtCore/QDebug>
52 
53 static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
54 {
55  const int width = img.width();
56  const int height = img.height();
57 
58  if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV
59  || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian))
60  {
61  for (int i = 0; i < height; ++i) {
62  uint *p = (uint *) img.scanLine(i);
63  for (int x = 0; x < width; ++x)
64  p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
65  }
66  } else {
67  for (int i = 0; i < height; ++i) {
68  uint *p = (uint *) img.scanLine(i);
69  for (int x = 0; x < width; ++x)
70  p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff);
71  }
72  }
73 }
74 
76  : mEglIntegration(eglIntegration)
77  , mWindow(window)
78  , mBuffer(0)
79  , mPixmap(0)
80  , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
81  , mPixmapSurface(EGL_NO_SURFACE)
82 {
83  QVector<EGLint> eglContextAttrs;
84  eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
85  eglContextAttrs.append(2);
86  eglContextAttrs.append(EGL_NONE);
87 
88  mContext = eglCreateContext(eglIntegration->eglDisplay(),mConfig,0,eglContextAttrs.constData());
89 
91 }
92 
94 {
95  eglDestroyContext(mEglIntegration->eglDisplay(),mContext);
96 }
97 
99 {
101 
103 
105 }
106 
108 {
110  eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
111 }
112 
114 {
115  eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
116 
117  if (QPlatformGLContext::currentContext() != this) {
118  makeCurrent();
119  }
120 
121  QSize size = mWindow->geometry().size();
122 
123  QImage img(size,QImage::Format_ARGB32);
124  const uchar *constBits = img.bits();
125  void *pixels = const_cast<uchar *>(constBits);
126 
127  glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
128 
129  img = img.mirrored();
131  constBits = img.bits();
132 
133  const uchar *constDstBits = mBuffer->image()->bits();
134  uchar *dstBits = const_cast<uchar *>(constDstBits);
135  memcpy(dstBits,constBits,(img.width()*4) * img.height());
136 
137 
138  mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
139 }
140 
142 {
143  return (void *) eglGetProcAddress(procName.toLatin1().data());
144 }
145 
147 {
149 }
150 
152 {
153  QSize size(mWindow->geometry().size());
154  if (size.isEmpty()) {
155  //QGLWidget wants a context for a window without geometry
156  size = QSize(1,1);
157  }
158 
160 
161  delete mBuffer;
162  if (mPixmap)
163  XFreePixmap(mEglIntegration->xDisplay(),mPixmap);
164 
166  mWindow->attach(mBuffer);
167  mPixmap = XCreatePixmap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),size.width(),size.height(),mEglIntegration->depth());
168  XSync(mEglIntegration->xDisplay(),False);
169 
170  mPixmapSurface = eglCreatePixmapSurface(mEglIntegration->eglDisplay(),mConfig,mPixmap,0);
171  if (mPixmapSurface == EGL_NO_SURFACE) {
172  qDebug() << "Could not make egl surface out of pixmap :(";
173  }
174 }
static const QPlatformGLContext * currentContext()
Returns the last context which called makeCurrent.
QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window)
QPointer< QWidget > widget
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
virtual QRect geometry() const
Returnes the current geometry of a window.
EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
#define GL_UNSIGNED_INT_8_8_8_8_REV
virtual void doneCurrent()
Reimplement in subclass to release current context.
virtual QPlatformWindowFormat platformWindowFormat() const
QWidget has the function qplatformWindowFormat().
The QPlatformWindowFormat class specifies the display format of an OpenGL rendering context and if po...
void swapBuffers()
Reimplement in subclass to native swap buffers calls.
The QString class provides a Unicode character string.
Definition: qstring.h:83
void * getProcAddress(const QString &procName)
Reimplement in subclass to native getProcAddr calls.
QWaylandReadbackEglIntegration * mEglIntegration
Q_CORE_EXPORT void qDebug(const char *,...)
unsigned char uchar
Definition: qglobal.h:994
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
void makeCurrent()
Reimplement in subclass to do makeCurrent on native GL context.
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
virtual void makeCurrent()
Reimplement in subclass to do makeCurrent on native GL context.
QImage mirrored(bool horizontally=false, bool vertically=true) const
Returns a mirror of the image, mirrored in the horizontal and/or the vertical direction depending on ...
Definition: qimage.cpp:4922
void attach(QWaylandBuffer *buffer)
void doneCurrent()
Reimplement in subclass to release current context.
static void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
uchar * bits()
Returns a pointer to the first pixel data.
Definition: qimage.cpp:1946
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
unsigned int GLenum
Definition: main.cpp:50
#define GL_UNSIGNED_BYTE
QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config)
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
#define GL_RGBA
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
void damage(const QRect &rect)
QWaylandReadbackEglWindow * mWindow
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886