[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/KDE/4.1/kdelibs/khtml
From:       Germain Garand <germain () ebooksfrance ! org>
Date:       2008-09-15 4:31:12
Message-ID: 1221453072.659736.19400.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 861089 by ggarand:

automatically merged revision 861057:
.avoid NVidia+Qt4 buffer clearing problems, by making our widgets
 have a private buffer.

.for the same reason, always fully clear our shared opacity buffers - or
 we might get artifacts on NVidia cards such as on
 www.codetch.com/screenshots/

 M  +4 -1      misc/paintbuffer.h  
 M  +16 -2     rendering/render_layer.cpp  
 M  +2 -0      rendering/render_layer.h  
 M  +37 -14    rendering/render_replaced.cpp  
 M  +2 -1      rendering/render_replaced.h  


--- branches/KDE/4.1/kdelibs/khtml/misc/paintbuffer.h #861088:861089
@@ -86,7 +86,10 @@
     BufferedPainter(QPixmap* px, QPainter*& p, const QRegion &rr, bool \
replacePainter) {  QRect br = rr.boundingRect();
          m_rect = br;
-         bool doFill = !px->hasAlphaChannel();
+         bool doFill = 1 || !px->hasAlphaChannel(); // shared pixmaps aren't \
properly cleared +                                                    // with Qt 4 + \
NVidia proprietary driver. +                                                    // So \
we can't use this optimisation until +                                                \
// we can detect this defect.   if (doFill)
              px->fill(Qt::transparent);
          m_painter.begin(px);
--- branches/KDE/4.1/kdelibs/khtml/rendering/render_layer.cpp #861088:861089
@@ -112,6 +112,8 @@
         m_visibleContentStatusDirty = false;
         m_hasVisibleContent = object->style()->visibility() == VISIBLE;
     }
+    m_buffer[0] = 0;
+    m_buffer[1] = 0;
 }
 
 RenderLayer::~RenderLayer()
@@ -120,6 +122,8 @@
     // our destructor doesn't have to do anything.
     delete m_hBar;
     delete m_vBar;
+    delete m_buffer[0];
+    delete m_buffer[1];
     delete m_scrollMediator;
     delete m_posZOrderList;
     delete m_negZOrderList;
@@ -945,12 +949,22 @@
        return;
 
     if (m_hBar) {
+        if (!m_buffer[0] || m_buffer[0]->size() != m_hBar->size()) {
+            delete m_buffer[0];
+            m_buffer[0] = new QPixmap( m_hBar->size() );
+        }
 	QPoint p = m_hBar->m_kwp->absolutePos();
-	RenderWidget::paintWidget(pI, m_hBar, p.x(), p.y());
+	RenderWidget::paintWidget(pI, m_hBar, p.x(), p.y(), m_buffer );
     }
     if (m_vBar) {
+        if (!m_buffer[1] || m_buffer[1]->size() != m_vBar->size()) {
+            delete m_buffer[1];
+            m_buffer[1] = new QPixmap( m_vBar->size() );
+        }
+        QPixmap* tmp[1];
+        tmp[0] = m_buffer[1];
         QPoint p = m_vBar->m_kwp->absolutePos();
-	RenderWidget::paintWidget(pI, m_vBar, p.x(), p.y());
+	RenderWidget::paintWidget(pI, m_vBar, p.x(), p.y(), tmp);
     }
 }
 
--- branches/KDE/4.1/kdelibs/khtml/rendering/render_layer.h #861088:861089
@@ -315,6 +315,8 @@
     // For layers with overflow, we have a pair of scrollbars.
     ScrollBarWidget* m_hBar;
     ScrollBarWidget* m_vBar;
+    QPixmap* m_buffer[2];
+
     RenderScrollMediator* m_scrollMediator;
 
     // For layers that establish stacking contexts, m_posZOrderList holds a sorted \
                list of all the
--- branches/KDE/4.1/kdelibs/khtml/rendering/render_replaced.cpp #861088:861089
@@ -188,6 +188,8 @@
 {
     m_widget = 0;
     m_underMouse = 0;
+    m_buffer[0] = 0;
+    m_buffer[1] = 0;
     // a widget doesn't support being anonymous
     assert(!isAnonymous());
     m_view  = node->document()->view();
@@ -238,6 +240,8 @@
         if (m_ownsWidget)
             m_widget->deleteLater();
     }
+    delete m_buffer[0];
+    delete m_buffer[1];
 }
 
 class QWidgetResizeEvent : public QEvent
@@ -637,8 +641,24 @@
     else
         m_view->addChild( m_widget, xPos, -500000 +yPos);
     m_widget->show();
-    if (khtmlw)
-        paintWidget(paintInfo, m_widget, xPos, yPos);
+    if (khtmlw) {
+        if ( KHTMLView* v = qobject_cast<KHTMLView*>(m_widget) ) {
+            // our buffers are dedicated to scrollbars.
+            if (v->verticalScrollBar()->isVisible() && (!m_buffer[0] || \
v->verticalScrollBar()->size() != m_buffer[0]->size())) { +                delete \
m_buffer[0]; +                m_buffer[0] = new QPixmap( \
v->verticalScrollBar()->size() ); +            }
+            if (v->horizontalScrollBar()->isVisible() && (!m_buffer[1] || \
v->horizontalScrollBar()->size() != m_buffer[1]->size())) { +                delete \
m_buffer[1]; +                m_buffer[1] = new QPixmap( \
v->horizontalScrollBar()->size() ); +            }
+        } else if (!m_buffer[0] || (m_widget->size() != m_buffer[0]->size())) {
+            assert(!m_buffer[1]);
+            delete m_buffer[0];
+            m_buffer[0] = new QPixmap( m_widget->size() );
+        }
+        paintWidget(paintInfo, m_widget, xPos, yPos, m_buffer);
+    }
 }
 
 static void setInPaintEventFlag(QWidget* w, bool b = true, bool recurse=true)
@@ -663,7 +683,7 @@
       }
 }
 
-static void copyWidget(const QRect& r, QPainter *p, QWidget *widget, int tx, int ty, \
bool buffered = false) +static void copyWidget(const QRect& r, QPainter *p, QWidget \
*widget, int tx, int ty, bool buffered = false, QPixmap* buffer = 0)  {
     if (r.isNull() || r.isEmpty() )
         return;
@@ -688,11 +708,14 @@
     if (buffered) {
         if (!widget->size().isValid())
             return;
-        pm = PaintBuffer::grab(widget->size());
-        // Qt 4.4 regression #1:
-        // QPainter::CompositionMode_Source is severly broken (cf. kde #160518)
+        // TT says Qt 4's widget painting hits an NVidia RenderAccel bug/shortcoming
+        // resulting in pixmap buffers being unsuitable for reuse by more than one \
widget.  //
-        if (1 || !pm->hasAlphaChannel()) {
+        // Until a turnaround exist in Qt, we can't reliably use shared buffers.
+        // ###  pm = PaintBuffer::grab(widget->size());
+        assert( buffer );
+        pm = buffer;
+        if (!pm->hasAlphaChannel()) {
             pm->fill(Qt::transparent);
         } else {
             QPainter pp(pm);
@@ -701,7 +724,7 @@
         }
         d = pm;
     }
-    // Qt 4.4 regression #2: 
+    // Qt 4.4 regression #1: 
     // can't let a painter active on the view as Qt thinks it is opened on the \
                *pixmap*
     // and prints "paint device can only be painted by one painter at a time" \
warnings.  //
@@ -733,16 +756,16 @@
         // transfer results
         QPoint off(r.x(), r.y());
         p->drawPixmap(thePoint+off, static_cast<QPixmap&>(*d), r);
-        PaintBuffer::release(pm);
+        // ### PaintBuffer::release(pm);
     }
 }
 
-void RenderWidget::paintWidget(PaintInfo& pI, QWidget *widget, int tx, int ty)
+void RenderWidget::paintWidget(PaintInfo& pI, QWidget *widget, int tx, int ty, \
QPixmap* buffer[])  {
     QPainter* const p = pI.p;
     allowWidgetPaintEvents = true;
 
-    // Qt 4.4 regression #3: 
+    // Qt 4.4 regression #2: 
     //    can't use QWidget::render to directly paint widgets on the view anymore.
     //    Results are unreliable for subrects, leaving blank squares. (cf. kde \
#158607)  //
@@ -760,7 +783,7 @@
             vbr &= r;
             vbr.translate( -of );
             if (vbr.isValid() && !vbr.isEmpty())
-                copyWidget(vbr, p, v->verticalScrollBar(), tx+of.x(), ty+of.y(), \
buffered); +                copyWidget(vbr, p, v->verticalScrollBar(), tx+of.x(), \
ty+of.y(), buffered, buffer[0]);  }
         if (v->horizontalScrollBar()->isVisible()) {
             QRect hbr = v->horizontalScrollBar()->rect();
@@ -769,13 +792,13 @@
             hbr &= r;
             hbr.translate( -of );
             if (hbr.isValid() && !hbr.isEmpty())
-                copyWidget(hbr, p, v->horizontalScrollBar(), tx+ of.x(), ty+ of.y(), \
buffered); +                copyWidget(hbr, p, v->horizontalScrollBar(), tx+ of.x(), \
ty+ of.y(), buffered, buffer[1]);  }
         QRect vr = (r & v->viewport()->rect());
         if (vr.isValid() && !vr.isEmpty())
             v->render(p, vr, thePoint);
     } else {
-        copyWidget(r, p, widget, tx, ty, buffered);
+        copyWidget(r, p, widget, tx, ty, buffered, buffer[0]);
     }
     allowWidgetPaintEvents = false;
 }
--- branches/KDE/4.1/kdelibs/khtml/rendering/render_replaced.h #861088:861089
@@ -101,7 +101,7 @@
     void cancelPendingResize();
     bool needsMask() const { return m_needsMask; }
 
-    static void paintWidget(PaintInfo& pI, QWidget *widget, int tx, int ty);
+    static void paintWidget(PaintInfo& pI, QWidget *widget, int tx, int ty, QPixmap* \
buffer[] = 0);  virtual bool handleEvent(const DOM::EventImpl& ev);
     bool isRedirectedWidget() const;
     bool isDisabled() const { return m_widget && !m_widget->isEnabled(); }
@@ -147,6 +147,7 @@
     QWidget *m_widget;
     KHTMLView* m_view;
     QPointer<QWidget> m_underMouse;
+    QPixmap *m_buffer[2];
 
     //Because we mess with normal detach due to ref/deref,
     //we need to keep track of the arena ourselves


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic