summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-05-19 16:18:21 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-05-19 19:03:23 +0200
commit3d34c9b78ee96b20c5b99358fa574ce057e9ef47 (patch)
tree84088f8cd33171237e96ce1e862e5f90b17ac5a4
parentdd43611b970909e74465023180b754e6d48add93 (diff)
Full translucent background support in xcb and xlib backend.
Make sure to pick an alpha visual also for non-GL surface types, and to ask for alpha in the window format if the WA_TranslucentBackground attribute is set. Reviewed-by: Janusz Lewandowski (cherry picked from commit 6241e39cff9311c943430ff2f31236b13618f2ac)
-rw-r--r--src/gui/kernel/qwidget_qpa.cpp11
-rw-r--r--src/opengl/qgl_qpa.cpp2
-rw-r--r--src/opengl/qwindowsurface_gl.cpp18
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp11
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp8
-rw-r--r--src/plugins/platforms/xlib/qxlibwindowsurface.cpp14
7 files changed, 55 insertions, 12 deletions
diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp
index 001810e0f4..960073c054 100644
--- a/src/gui/kernel/qwidget_qpa.cpp
+++ b/src/gui/kernel/qwidget_qpa.cpp
@@ -731,12 +731,19 @@ QPlatformWindowFormat QWidget::platformWindowFormat() const
{
Q_D(const QWidget);
+ QPlatformWindowFormat format;
+
QTLWExtra *extra = d->maybeTopData();
if (extra){
- return extra->platformWindowFormat;
+ format = extra->platformWindowFormat;
} else {
- return QPlatformWindowFormat::defaultFormat();
+ format = QPlatformWindowFormat::defaultFormat();
}
+
+ if (testAttribute(Qt::WA_TranslucentBackground))
+ format.setAlpha(true);
+
+ return format;
}
void QWidgetPrivate::createSysExtra()
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 994344c6eb..9da650f98d 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -150,6 +150,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
if (shareContext) {
winFormat.setSharedContext(shareContext->d_func()->platformContext);
}
+ if (widget->testAttribute(Qt::WA_TranslucentBackground))
+ winFormat.setAlpha(true);
winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
winFormat.setWindowSurface(false);
widget->setPlatformWindowFormat(winFormat);
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 49b3dc2dae..ff5744678d 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -542,19 +542,27 @@ void QGLWindowSurface::beginPaint(const QRegion &)
d_ptr->did_paint = true;
updateGeometry();
- if (!context())
- return;
-
int clearFlags = 0;
- if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
+ QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
+
+ if (!ctx)
+ return;
+
+ if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- else if (context()->format().alpha())
+ else if (ctx->format().alpha())
clearFlags = GL_COLOR_BUFFER_BIT;
if (clearFlags) {
+ if (d_ptr->fbo)
+ d_ptr->fbo->bind();
+
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(clearFlags);
+
+ if (d_ptr->fbo)
+ d_ptr->fbo->release();
}
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3365c22c39..0dd29eb8b2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -113,7 +113,8 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+ || tlw->platformWindowFormat().alpha())
{
#if defined(XCB_USE_GLX)
XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
index 38c01f9cfd..88a54dc316 100644
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
@@ -54,6 +54,7 @@
#include <stdio.h>
#include <qdebug.h>
+#include <qpainter.h>
class QXcbShmImage : public QXcbObject
{
@@ -189,6 +190,16 @@ QPaintDevice *QXcbWindowSurface::paintDevice()
void QXcbWindowSurface::beginPaint(const QRegion &region)
{
m_image->preparePaint(region);
+
+ if (m_image->image()->hasAlphaChannel()) {
+ QPainter p(m_image->image());
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = region.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
+ }
}
void QXcbWindowSurface::endPaint(const QRegion &)
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
index 4efcb1101c..50ea7b58e4 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -81,9 +81,10 @@ QXlibWindow::QXlibWindow(QWidget *window)
int w = window->width();
int h = window->height();
- if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) ) {
#if !defined(QT_NO_OPENGL)
+ if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
+ && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+ || window->platformWindowFormat().alpha()) {
#if !defined(QT_OPENGL_ES_2)
XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
#else
@@ -117,8 +118,9 @@ QXlibWindow::QXlibWindow(QWidget *window)
} else {
qFatal("no window!");
}
+ } else
#endif //!defined(QT_NO_OPENGL)
- } else {
+ {
mDepth = mScreen->depth();
mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
mVisual = mScreen->defaultVisual();
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp b/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
index 78fe387bb8..a917f452e8 100644
--- a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
@@ -49,6 +49,8 @@
#include "qxlibscreen.h"
#include "qxlibdisplay.h"
+#include "qpainter.h"
+
# include <sys/ipc.h>
# include <sys/shm.h>
# include <X11/extensions/XShm.h>
@@ -108,7 +110,7 @@ void QXlibWindowSurface::resizeShmImage(int width, int height)
Q_ASSERT(shm_attach_status == True);
- shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, QImage::Format_RGB32 );
+ shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
#endif
painted = false;
}
@@ -213,6 +215,16 @@ void QXlibWindowSurface::beginPaint(const QRegion &region)
{
Q_UNUSED(region);
resizeBuffer(size());
+
+ if (shm_img.hasAlphaChannel()) {
+ QPainter p(&shm_img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = region.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
+ }
}
void QXlibWindowSurface::endPaint(const QRegion &region)