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)
This commit is contained in:
Samuel Rødal 2011-05-19 16:18:21 +02:00
parent dd43611b97
commit 3d34c9b78e
7 changed files with 55 additions and 12 deletions

View File

@ -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()

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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());

View File

@ -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 &)

View File

@ -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();

View File

@ -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)