summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Fraser <simon.fraser@apple.com>2013-04-23 14:54:53 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-30 15:04:13 +0200
commit648159cd3e311e08836fe1af5d1f614b992ea2ea (patch)
tree2bb7887cb9d2a8f2772ca23a7af0b2716be77a79
parent23fc33e202162bdbe39173744407cc0b98eab66a (diff)
downloadqtwebkit-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.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBlock.cpp4
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp41
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.h6
-rw-r--r--Source/WebCore/rendering/RenderView.cpp14
-rw-r--r--Source/WebCore/rendering/RenderView.h5
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;