diff options
author | Simon Fraser <simon.fraser@apple.com> | 2013-04-23 14:54:53 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-04-30 15:04:13 +0200 |
commit | 648159cd3e311e08836fe1af5d1f614b992ea2ea (patch) | |
tree | 2bb7887cb9d2a8f2772ca23a7af0b2716be77a79 | |
parent | 23fc33e202162bdbe39173744407cc0b98eab66a (diff) | |
download | qtwebkit-648159cd3e311e08836fe1af5d1f614b992ea2ea.tar.gz |
Late-loading stylesheets can cause composited layers to be blank
https://bugs.webkit.org/show_bug.cgi?id=103773
Reviewed by Tim Horton.
Early painting can be short-circuited in RenderBlock::paintContents() if we know a stylesheet
is pending, which is done to avoid a flash of unstyled content (FOUC). When the stylesheet
finally loaded, Document::styleResolverChanged() would try to repaint everything by calling
repaint() on the RenderView(). In a composited world, however, this repaint() doesn't repaint
composited layers.
This was particularly prevalent on this specific URL because it failed to load
a CSS file from typekit.com, so Document::styleResolverChanged()
just did the repaint and returned (rather than doing a recalc style as would
happen for correctly loaded stylesheets).
Fix by making a way to repaint all compositing layers, and calling it
from Document::styleResolverChanged().
No tests because this is timing-dependant.
* dom/Document.cpp:
(WebCore::Document::styleResolverChanged): Call repaintViewAndCompositedLayers().
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintContents): Fix the comment.
* rendering/RenderLayerCompositor.cpp: Convert repaintCompositedLayersAbsoluteRect()
and associated recursiveRepaintLayerRect() to allow the rect to be null, which indicates
that we should just repaint the entire layer, and improve their names.
(WebCore::RenderLayerCompositor::repaintCompositedLayers):
(WebCore::RenderLayerCompositor::recursiveRepaintLayer):
* rendering/RenderLayerCompositor.h:
* rendering/RenderView.cpp:
(WebCore::RenderView::repaintRectangleInViewAndCompositedLayers): repaintCompositedLayersAbsoluteRect()
was renamed to repaintCompositedLayers().
(WebCore::RenderView::repaintViewAndCompositedLayers):
* rendering/RenderView.h:
(RenderView): repaintViewRectangle() and repaintRectangleInViewAndCompositedLayers() should not
be virtual. Add repaintViewAndCompositedLayers().
Change-Id: I86401d25d06128db33a5e5db099144d6b05850ef
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@136277 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/WebCore/dom/Document.cpp | 2 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderBlock.cpp | 4 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderLayerCompositor.cpp | 41 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderLayerCompositor.h | 6 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderView.cpp | 14 | ||||
-rw-r--r-- | Source/WebCore/rendering/RenderView.h | 5 |
6 files changed, 49 insertions, 23 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index c1c2b7b5d..ec7ca673e 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -3179,7 +3179,7 @@ void Document::styleResolverChanged(StyleResolverUpdateFlag updateFlag) if (didLayoutWithPendingStylesheets() && !m_styleSheetCollection->hasPendingSheets()) { m_pendingSheetLayout = IgnoreLayoutWithPendingSheets; if (renderer()) - renderer()->repaint(); + renderView()->repaintViewAndCompositedLayers(); } if (!stylesheetChangeRequiresStyleRecalc) diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp index 4265ecdf3..058e90431 100644 --- a/Source/WebCore/rendering/RenderBlock.cpp +++ b/Source/WebCore/rendering/RenderBlock.cpp @@ -2925,8 +2925,8 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC. - // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document - // will do a full repaint(). + // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document + // will do a full repaint. if (document()->didLayoutWithPendingStylesheets() && !isRenderView()) return; diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp index 870bf1ddf..3ddfe4538 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.cpp +++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp @@ -1340,16 +1340,20 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com } -void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect) +void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect) { - recursiveRepaintLayerRect(rootRenderLayer(), absRect); + recursiveRepaintLayer(rootRenderLayer(), absRect); } -void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect) +void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect) { // FIXME: This method does not work correctly with transforms. - if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor()) - layer->setBackingNeedsRepaintInRect(rect); + if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor()) { + if (rect) + layer->setBackingNeedsRepaintInRect(*rect); + else + layer->setBackingNeedsRepaint(); + } #if !ASSERT_DISABLED LayerListMutationDetector mutationChecker(layer); @@ -1360,9 +1364,12 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const size_t listSize = negZOrderList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = negZOrderList->at(i); - IntRect childRect(rect); - curLayer->convertToPixelSnappedLayerCoords(layer, childRect); - recursiveRepaintLayerRect(curLayer, childRect); + if (rect) { + IntRect childRect(*rect); + curLayer->convertToPixelSnappedLayerCoords(layer, childRect); + recursiveRepaintLayer(curLayer, &childRect); + } else + recursiveRepaintLayer(curLayer); } } @@ -1370,9 +1377,12 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const size_t listSize = posZOrderList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = posZOrderList->at(i); - IntRect childRect(rect); - curLayer->convertToPixelSnappedLayerCoords(layer, childRect); - recursiveRepaintLayerRect(curLayer, childRect); + if (rect) { + IntRect childRect(*rect); + curLayer->convertToPixelSnappedLayerCoords(layer, childRect); + recursiveRepaintLayer(curLayer, &childRect); + } else + recursiveRepaintLayer(curLayer); } } } @@ -1380,9 +1390,12 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const size_t listSize = normalFlowList->size(); for (size_t i = 0; i < listSize; ++i) { RenderLayer* curLayer = normalFlowList->at(i); - IntRect childRect(rect); - curLayer->convertToPixelSnappedLayerCoords(layer, childRect); - recursiveRepaintLayerRect(curLayer, childRect); + if (rect) { + IntRect childRect(*rect); + curLayer->convertToPixelSnappedLayerCoords(layer, childRect); + recursiveRepaintLayer(curLayer, &childRect); + } else + recursiveRepaintLayer(curLayer); } } } diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h index 4d828f1a5..5193411a2 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.h +++ b/Source/WebCore/rendering/RenderLayerCompositor.h @@ -144,8 +144,8 @@ public: // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const; - // Repaint parts of all composited layers that intersect the given absolute rectangle. - void repaintCompositedLayersAbsoluteRect(const IntRect&); + // Repaint parts of all composited layers that intersect the given absolute rectangle (or the entire layer if the pointer is null). + void repaintCompositedLayers(const IntRect* = 0); // Returns true if the given layer needs it own backing store. bool requiresOwnBackingStore(const RenderLayer*, const RenderLayer* compositingAncestorLayer) const; @@ -257,7 +257,7 @@ private: void clearBackingForLayerIncludingDescendants(RenderLayer*); // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect. - void recursiveRepaintLayerRect(RenderLayer*, const IntRect&); + void recursiveRepaintLayer(RenderLayer*, const IntRect* = 0); void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed); void addToOverlapMapRecursive(OverlapMap&, RenderLayer*, RenderLayer* ancestorLayer = 0); diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp index 1457b6be2..bdb9c8069 100644 --- a/Source/WebCore/rendering/RenderView.cpp +++ b/Source/WebCore/rendering/RenderView.cpp @@ -435,8 +435,20 @@ void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur, repaintViewRectangle(ur, immediate); #if USE(ACCELERATED_COMPOSITING) + if (compositor()->inCompositingMode()) { + IntRect repaintRect = pixelSnappedIntRect(ur); + compositor()->repaintCompositedLayers(&repaintRect); + } +#endif +} + +void RenderView::repaintViewAndCompositedLayers() +{ + repaint(); + +#if USE(ACCELERATED_COMPOSITING) if (compositor()->inCompositingMode()) - compositor()->repaintCompositedLayersAbsoluteRect(pixelSnappedIntRect(ur)); + compositor()->repaintCompositedLayers(); #endif } diff --git a/Source/WebCore/rendering/RenderView.h b/Source/WebCore/rendering/RenderView.h index d63f8df86..99ab1c1a3 100644 --- a/Source/WebCore/rendering/RenderView.h +++ b/Source/WebCore/rendering/RenderView.h @@ -78,10 +78,11 @@ public: FrameView* frameView() const { return m_frameView; } virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE; - virtual void repaintViewRectangle(const LayoutRect&, bool immediate = false) const; + void repaintViewRectangle(const LayoutRect&, bool immediate = false) const; // Repaint the view, and all composited layers that intersect the given absolute rectangle. // FIXME: ideally we'd never have to do this, if all repaints are container-relative. - virtual void repaintRectangleInViewAndCompositedLayers(const LayoutRect&, bool immediate = false); + void repaintRectangleInViewAndCompositedLayers(const LayoutRect&, bool immediate = false); + void repaintViewAndCompositedLayers(); virtual void paint(PaintInfo&, const LayoutPoint&); virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE; |