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

List:       kde-commits
Subject:    branches/KDE/4.0/kdelibs/khtml
From:       Germain Garand <germain () ebooksfrance ! org>
Date:       2008-03-12 8:35:05
Message-ID: 1205310905.426434.483.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 784718 by ggarand:

automatically merged revision 783804:
Tighten our paint prevention timings to provide
more responsiveness while keeping smooth page transitions.

Proper balance is not easy to achieve, as preventing the
"white flash" is just part of the equation.
Layout stability, allowing early readability, is another important
term - as is bandwidth. Engines with aggressive timings would get an
unpleasnt, jerky feeling we want to avoid.

We'll use subtly progressive timings to get a good compromise.

 M  +54 -18    khtmlview.cpp  
 M  +6 -1      xml/dom_docimpl.cpp  
 M  +3 -2      xml/dom_docimpl.h  


--- branches/KDE/4.0/kdelibs/khtml/khtmlview.cpp #784717:784718
@@ -116,9 +116,18 @@
 using namespace DOM;
 using namespace khtml;
 
+#ifndef NDEBUG
+static const int sFirstLayoutDelay = 760;
+static const int sParsingLayoutsInterval = 420;
+static const int sLayoutAttemptDelay = 400;
+#else
+static const int sFirstLayoutDelay = 540;
+static const int sParsingLayoutsInterval = 360;
+static const int sLayoutAttemptDelay = 340;
+#endif
+static const int sLayoutAttemptIncrement = 20;
+static const int sParsingLayoutsIncrement = 60;
 
-
-
 class KHTMLViewPrivate {
     friend class KHTMLView;
 public:
@@ -228,11 +237,14 @@
         scrollSuspended = false;
         scrollSuspendPreActivate = false;
         complete = false;
-        firstRelayout = true;
+        firstLayout = true;
         needsFullRepaint = true;
         dirtyLayout = false;
         layoutSchedulingEnabled = true;
         painting = false;
+        layoutCounter = 0;
+        layoutAttemptCounter = 0;
+        scheduledLayoutCounter = 0;
         updateRegion = QRegion();
         m_dialogsAllowed = true;
 #ifndef KHTML_NO_CARET
@@ -357,13 +369,16 @@
     bool scrollSuspended			:1;
     bool scrollSuspendPreActivate		:1;
     bool complete				:1;
-    bool firstRelayout				:1;
+    bool firstLayout				:1;
     bool layoutSchedulingEnabled		:1;
     bool needsFullRepaint			:1;
     bool painting				:1;
     bool possibleTripleClick			:1;
     bool dirtyLayout                           :1;
     bool m_dialogsAllowed			:1;
+    int layoutCounter;
+    int layoutAttemptCounter;
+    int scheduledLayoutCounter;
     QRegion updateRegion;
     QHash<void*, QWidget*> visibleWidgets;
 #ifndef KHTML_NO_CARET
@@ -921,6 +936,7 @@
         if ( !canvas ) return;
 
         d->layoutSchedulingEnabled=false;
+        d->dirtyLayout = true;
 
         // the reference object for the overflow property on canvas
         RenderObject * ref = 0;
@@ -954,7 +970,7 @@
                 QScrollArea::setVerticalScrollBarPolicy(d->vpolicy);
             }
         }
-        d->needsFullRepaint = d->firstRelayout;
+        d->needsFullRepaint = d->firstLayout;
         if (_height !=  visibleHeight() || _width != visibleWidth()) {;
             d->needsFullRepaint = true;
             _height = visibleHeight();
@@ -964,13 +980,14 @@
         canvas->layout();
 
         emit finishedLayout();
-        if (d->firstRelayout) {
-            // make sure firstRelayout is set to false now in case this layout
+        if (d->firstLayout) {
+            // make sure firstLayout is set to false now in case this layout
             // wasn't scheduled
-            d->firstRelayout = false;
+            d->firstLayout = false;
             verticalScrollBar()->setEnabled( true );
             horizontalScrollBar()->setEnabled( true );
         }
+        d->layoutCounter++;
 #ifndef KHTML_NO_CARET
         hideCaret();
         if ((m_part->isCaretMode() || m_part->isEditable())
@@ -3599,7 +3616,7 @@
         emit zoomView( - e->delta() );
         e->accept();
     }
-    else if (d->firstRelayout)
+    else if (d->firstLayout)
     {
         e->accept();
     }
@@ -3753,7 +3770,7 @@
 
 void KHTMLView::scrollContentsBy( int dx, int dy )
 {
-    if ( !d->firstRelayout && !d->complete && m_part->xmlDocImpl() &&
+    if ( !d->firstLayout && !d->complete && m_part->xmlDocImpl() &&
           d->layoutSchedulingEnabled) {
         // contents scroll while we are not complete: we need to check our layout \
                *now*
         khtml::RenderCanvas* root = static_cast<khtml::RenderCanvas *>( \
m_part->xmlDocImpl()->renderer() ); @@ -3839,10 +3856,18 @@
         killTimer( d->scrollingFromWheelTimerId );
         d->scrollingFromWheelTimerId = 0;
     } else if ( e->timerId() == d->layoutTimerId ) {
-        d->dirtyLayout = true;
+        if (d->firstLayout && d->layoutAttemptCounter < 4 
+                           && (!m_part->xmlDocImpl() || \
!m_part->xmlDocImpl()->readyForLayout())) { +            d->layoutAttemptCounter++;
+            killTimer(d->layoutTimerId);
+            d->layoutTimerId = 0;
+            scheduleRelayout();
+            return;
+        }
         layout();
-        if (d->firstRelayout) {
-            d->firstRelayout = false;
+        d->scheduledLayoutCounter++;
+        if (d->firstLayout) {
+            d->firstLayout = false;
             verticalScrollBar()->setEnabled( true );
             horizontalScrollBar()->setEnabled( true );
         }
@@ -3909,7 +3934,6 @@
 
     if (d->dirtyLayout && !d->visibleWidgets.isEmpty()) {
         QWidget* w;
-        d->dirtyLayout = false;
 
         QRect visibleRect(contentsX(), contentsY(), visibleWidth(), \
visibleHeight());  QList<RenderWidget*> toRemove;
@@ -3929,6 +3953,7 @@
             if ( (w = d->visibleWidgets.take(r) ) )
                 w->move( 0, -500000);
     }
+    d->dirtyLayout = false;
 
     emit repaintAccessKeys();
     if (d->emitCompletedAfterRepaint) {
@@ -3946,8 +3971,19 @@
     if (!d->layoutSchedulingEnabled || d->layoutTimerId)
         return;
 
-    d->layoutTimerId = startTimer( m_part->xmlDocImpl() && \
                m_part->xmlDocImpl()->parsing()
-                             ? 1000 : 0 );
+    int time = 0;
+    if (d->firstLayout) {
+        // Any repaint happening while we have no content blanks the viewport \
("white flash"). +        // Hence the need to delay the first layout as much as we \
can. +        // Only if the document gets stuck for too long in incomplete state \
will we allow the blanking.  +        time = d->layoutAttemptCounter ? 
+               sLayoutAttemptDelay + sLayoutAttemptIncrement*d->layoutAttemptCounter \
: sFirstLayoutDelay; +    } else if (m_part->xmlDocImpl() && \
m_part->xmlDocImpl()->parsing()) { +        // Delay between successive layouts in \
parsing mode. +        // Increment reflects the decaying importance of visual \
feedback over time. +        time = qMin(2000, sParsingLayoutsInterval + \
d->scheduledLayoutCounter*sParsingLayoutsIncrement); +    }
+    d->layoutTimerId = startTimer( time );
 }
 
 void KHTMLView::unscheduleRelayout()
@@ -3975,7 +4011,7 @@
 //     kDebug() << "parsing " << parsing;
 //     kDebug() << "complete " << d->complete;
 
-    int time = parsing ? 300 : (!asap ? ( !d->complete ? 100 : 20 ) : 0);
+    int time = parsing && !d->firstLayout ? 150 : (!asap ? ( !d->complete ? 80 : 20 \
) : 0);  
 #ifdef DEBUG_FLICKER
     QPainter p;
@@ -4021,7 +4057,7 @@
 //         kDebug() << "requesting repaint now";
         // do it now
         killTimer(d->repaintTimerId);
-        d->repaintTimerId = startTimer( 20 );
+        d->repaintTimerId = startTimer( 0 );
         d->emitCompletedAfterRepaint = pendingAction ?
             KHTMLViewPrivate::CSActionPending : KHTMLViewPrivate::CSFull;
     }
--- branches/KDE/4.0/kdelibs/khtml/xml/dom_docimpl.cpp #784717:784718
@@ -1365,7 +1365,7 @@
     m_tokenizer->begin();
 }
 
-HTMLElementImpl* DocumentImpl::body()
+HTMLElementImpl* DocumentImpl::body() const
 {
     NodeImpl *de = documentElement();
     if (!de)
@@ -2104,6 +2104,11 @@
         renderer()->setNeedsLayoutAndMinMaxRecalc();
 }
 
+bool DocumentImpl::readyForLayout() const
+{
+    return renderer() && haveStylesheetsLoaded() && (!isHTMLDocument() || (body() && \
body()->renderer())); +}
+
 void DocumentImpl::recalcStyleSelector()
 {
     if ( !m_render || !attached() ) return;
--- branches/KDE/4.0/kdelibs/khtml/xml/dom_docimpl.h #784717:784718
@@ -237,7 +237,7 @@
      * This method returns true if all top-level stylesheets have loaded (including
      * any \@imports that they may be loading).
      */
-    bool haveStylesheetsLoaded() { return m_pendingStylesheets <= 0 || \
m_ignorePendingStylesheets; } +    bool haveStylesheetsLoaded() const { return \
m_pendingStylesheets <= 0 || m_ignorePendingStylesheets; }  
     /**
      * Increments the number of pending sheets.  The \<link\> elements
@@ -265,6 +265,7 @@
      */
     void updateStyleSelector(bool shallow=false);
 
+    bool readyForLayout() const;
     void recalcStyleSelector();
     void rebuildStyleSelector();
 
@@ -514,7 +515,7 @@
 
     bool isURLAllowed(const QString& url) const;
 
-    HTMLElementImpl* body();
+    HTMLElementImpl* body() const;
 
     DOMString toString() const;
 


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

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