Lighthouse xcb and xlib: Add support for transparency of GLX windows.

Merge-request: 1231
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
(cherry picked from commit a3b627e1c5ce03a2500ab35c64729b1995639dcc)
This commit is contained in:
Janusz Lewandowski 2011-05-19 16:21:40 +02:00 committed by Samuel Rødal
parent 463e31fd58
commit dd43611b97
10 changed files with 78 additions and 25 deletions

View File

@ -5,3 +5,11 @@ HEADERS += \
SOURCES += \
$$PWD/qglxconvenience.cpp
CONFIG += xrender
xrender {
LIBS += -lXrender
} else {
DEFINES += QT_NO_XRENDER
}

View File

@ -43,6 +43,10 @@
#include <QtCore/QVector>
#ifndef QT_NO_XRENDER
#include <X11/extensions/Xrender.h>
#endif
enum {
XFocusOut = FocusOut,
XFocusIn = FocusIn,
@ -84,14 +88,15 @@ QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit
spec[i++] = GLX_ALPHA_SIZE; spec[i++] = (format.alphaBufferSize() == -1) ? 1 : format.alphaBufferSize();
}
spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.accum()) {
spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.alpha()) {
spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.alpha()) {
spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
}
}
} else {
spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_COLOR_INDEX_BIT; //I'm really not sure if this works....
spec[i++] = GLX_BUFFER_SIZE; spec[i++] = 8;
@ -136,8 +141,17 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QPlatformWindow
if (reducedFormat.alpha()) {
int alphaSize;
glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
if (alphaSize > 0)
break;
if (alphaSize > 0) {
XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig);
#if !defined(QT_NO_XRENDER)
XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual);
if (pictFormat->direct.alphaMask > 0)
break;
#else
if (visual->depth == 32)
break;
#endif
}
} else {
break; // Just choose the first in the list if there's no alpha requested
}

View File

@ -132,10 +132,12 @@ void QWaylandXCompositeGLXContext::geometryChanged()
Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
a.colormap = cmap;
mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
XMapWindow(mGlxIntegration->xDisplay(), mXWindow);

View File

@ -131,13 +131,17 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //XCB_USE_GLX
if (visualInfo) {
m_depth = visualInfo->depth;
m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.colormap = cmap;
m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
printf("created GL window: %d\n", m_window);
} else {
@ -147,6 +151,8 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
{
m_window = xcb_generate_id(xcb_connection());
m_depth = m_screen->screen()->root_depth;
m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root

View File

@ -44,6 +44,7 @@
#include <QtGui/QPlatformWindow>
#include <QtGui/QPlatformWindowFormat>
#include <QtGui/QImage>
#include <xcb/xcb.h>
#include <xcb/sync.h>
@ -74,6 +75,8 @@ public:
QPlatformGLContext *glContext() const;
xcb_window_t window() const { return m_window; }
uint depth() const { return m_depth; }
QImage::Format format() const { return m_format; }
void handleExposeEvent(const xcb_expose_event_t *event);
void handleClientMessageEvent(const xcb_client_message_event_t *event);
@ -99,6 +102,9 @@ private:
xcb_window_t m_window;
QPlatformGLContext *m_context;
uint m_depth;
QImage::Format m_format;
xcb_sync_int64_t m_syncValue;
xcb_sync_counter_t m_syncCounter;

View File

@ -58,7 +58,7 @@
class QXcbShmImage : public QXcbObject
{
public:
QXcbShmImage(QXcbScreen *connection, const QSize &size);
QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format);
~QXcbShmImage() { destroy(); }
QImage *image() { return &m_qimage; }
@ -81,7 +81,7 @@ private:
QRegion m_dirty;
};
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
: QXcbObject(screen->connection())
, m_gc(0)
, m_gc_window(0)
@ -91,7 +91,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
size.width(),
size.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
screen->depth(),
depth,
0,
~0,
0);
@ -111,7 +111,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, screen->format());
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
void QXcbShmImage::destroy()
@ -232,9 +232,10 @@ void QXcbWindowSurface::resize(const QSize &size)
QWindowSurface::resize(size);
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
QXcbWindow* win = static_cast<QXcbWindow *>(window()->platformWindow());
delete m_image;
m_image = new QXcbShmImage(screen, size);
m_image = new QXcbShmImage(screen, size, win->depth(), win->format());
Q_XCB_NOOP(connection());
m_syncingResize = true;

View File

@ -150,7 +150,7 @@ bool QXlibIntegration::hasOpenGL() const
{
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
QXlibScreen *screen = static_cast<const QXlibScreen *>(mScreens.at(0));
QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
return glXQueryExtension(screen->display()->nativeDisplay(), 0, 0) != 0;
#else
static bool eglHasbeenInitialized = false;

View File

@ -102,18 +102,27 @@ QXlibWindow::QXlibWindow(QWidget *window)
visualInfo = XGetVisualInfo(mScreen->display()->nativeDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //!defined(QT_OPENGL_ES_2)
if (visualInfo) {
Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(),mScreen->rootWindow(),visualInfo->visual,AllocNone);
mDepth = visualInfo->depth;
mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
mVisual = visualInfo->visual;
Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber());
a.border_pixel = BlackPixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber());
a.colormap = cmap;
x_window = XCreateWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),x, y, w, h,
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
} else {
qFatal("no window!");
}
#endif //!defined(QT_NO_OPENGL)
} else {
mDepth = mScreen->depth();
mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
mVisual = mScreen->defaultVisual();
x_window = XCreateSimpleWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),
x, y, w, h, 0 /*border_width*/,
mScreen->blackPixel(), mScreen->whitePixel());

View File

@ -122,6 +122,10 @@ public:
Window xWindow() const;
GC graphicsContext() const;
inline uint depth() const { return mDepth; }
QImage::Format format() const { return mFormat; }
Visual* visual() const { return mVisual; }
protected:
QVector<Atom> getNetWmState() const;
void setMWMHints(const QXlibMWMHints &mwmhints);
@ -135,6 +139,10 @@ private:
Window x_window;
GC gc;
uint mDepth;
QImage::Format mFormat;
Visual* mVisual;
GC createGC();
QPlatformGLContext *mGLContext;

View File

@ -80,20 +80,19 @@ void QXlibShmImageInfo::destroy()
void QXlibWindowSurface::resizeShmImage(int width, int height)
{
QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
#ifdef DONT_USE_MIT_SHM
shm_img = QImage(width, height, QImage::Format_RGB32);
shm_img = QImage(width, height, win->format());
#else
QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
if (image_info)
image_info->destroy();
else
image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
Visual *visual = screen->defaultVisual();
XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), visual, 24, ZPixmap, 0,
XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0,
&image_info->shminfo, width, height);
@ -160,11 +159,11 @@ void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPo
#ifdef DONT_USE_MIT_SHM
// just convert the image every time...
if (!shm_img.isNull()) {
Visual *visual = DefaultVisual(screen->display(), screen->xScreenNumber());
QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
QImage image = shm_img;
//img.convertToFormat(
XImage *xi = XCreateImage(screen->display(), visual, 24, ZPixmap,
XImage *xi = XCreateImage(screen->display(), win->visual(), win->depth(), ZPixmap,
0, (char *) image.scanLine(0), image.width(), image.height(),
32, image.bytesPerLine());