widgets: Fix painting to a fully transparent top level widget
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>
Mon, 2 Apr 2012 09:59:04 +0000 (11:59 +0200)
committerQt by Nokia <qt-info@nokia.com>
Sun, 15 Apr 2012 04:14:00 +0000 (06:14 +0200)
QWS used to have a line to change the composite mode from SourceOver
to Source for the top level widget. This wasn't used with QPA and I
removed the internal DontSetCompositionMode in qtbase. It turns out that
the QWS way is the most efficient one to initialize the background of
the widget.

The alternative is to have the QPlatformBackingStore::beginPaint
always clear the entire to be painted area and then paint the background
of the widget. The difference of painting each pixel once or twice is
noticable on embedded platforms and in the range of one to two fps.

Reproduce the issue with:
echo "QWidget {background: transparent}" > style.css
./examples/widgets/wiggly/wiggly -stylesheet style.css

Task-number: QTBUG-24526
Change-Id: Ica4c980bb3bf6eb87ddb5b510ac7493292d01543
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
src/gui/painting/qplatformbackingstore_qpa.cpp
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget_p.h

index ff7d91c..485190d 100644 (file)
@@ -114,9 +114,6 @@ QWindow* QPlatformBackingStore::window() const
     This function is called before painting onto the surface begins,
     with the \a region in which the painting will occur.
 
-    \note A platform providing a backing store with an alpha channel
-    needs to properly initialize the region to be painted.
-
     \sa endPaint(), paintDevice()
 */
 
index f02a67d..662c9b7 100644 (file)
@@ -2137,7 +2137,15 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int
 
     if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
         const QBrush bg = q->palette().brush(QPalette::Window);
-        fillRegion(painter, rgn, bg);
+        if (!(flags & DontSetCompositionMode)) {
+            //copy alpha straight in
+            QPainter::CompositionMode oldMode = painter->compositionMode();
+            painter->setCompositionMode(QPainter::CompositionMode_Source);
+            fillRegion(painter, rgn, bg);
+            painter->setCompositionMode(oldMode);
+        } else {
+            fillRegion(painter, rgn, bg);
+        }
     }
 
     if (q->autoFillBackground())
@@ -5229,6 +5237,8 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
     else
         flags |= DontSubtractOpaqueChildren;
 
+    flags |= DontSetCompositionMode;
+
     if (target->devType() == QInternal::Printer) {
         QPainter p(target);
         render_helper(&p, targetOffset, paintRegion, renderFlags);
index 8107b6c..d3fcdce 100644 (file)
@@ -284,7 +284,8 @@ public:
         DrawInvisible = 0x08,
         DontSubtractOpaqueChildren = 0x10,
         DontDrawOpaqueChildren = 0x20,
-        DontDrawNativeChildren = 0x40
+        DontDrawNativeChildren = 0x40,
+        DontSetCompositionMode = 0x80
     };
 
     enum CloseMode {