didFirstVisuallyNonEmptyLayout dispatched too early
https://bugs.webkit.org/show_bug.cgi?id=64412
Reviewed by Darin Adler and Sam Weinig.
Improve the mechanism that dispatches didFirstVisuallyNonEmptyLayout
- Wait until a threshold of characters and pixels has been exceeded before dispatching.
- Wait until stylesheets are loaded (painting is disabled in this case).
* page/FrameView.cpp:
(WebCore::FrameView::reset):
(WebCore::FrameView::performPostLayoutTasks):
* page/FrameView.h:
(WebCore::FrameView::incrementVisuallyNonEmptyCharacterCount):
(WebCore::FrameView::incrementVisuallyNonEmptyPixelCount):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::RenderImage):
(WebCore::RenderImage::imageChanged):
* rendering/RenderImage.h:
* rendering/RenderText.cpp:
(WebCore::RenderText::RenderText):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@90900 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 454fa40..f94b49f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2011-07-12 Antti Koivisto <antti@apple.com>
+
+ didFirstVisuallyNonEmptyLayout dispatched too early
+ https://bugs.webkit.org/show_bug.cgi?id=64412
+
+ Reviewed by Darin Adler and Sam Weinig.
+
+ Improve the mechanism that dispatches didFirstVisuallyNonEmptyLayout
+
+ - Wait until a threshold of characters and pixels has been exceeded before dispatching.
+ - Wait until stylesheets are loaded (painting is disabled in this case).
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::reset):
+ (WebCore::FrameView::performPostLayoutTasks):
+ * page/FrameView.h:
+ (WebCore::FrameView::incrementVisuallyNonEmptyCharacterCount):
+ (WebCore::FrameView::incrementVisuallyNonEmptyPixelCount):
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::RenderImage):
+ (WebCore::RenderImage::imageChanged):
+ * rendering/RenderImage.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::RenderText):
+
2011-07-12 MORITA Hajime <morrita@google.com>
[Refactoring][ShadowContentElement] Forwarded node list should be a linked-list.
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index a0581d3..de9d7b3 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -227,6 +227,8 @@
m_lastPaintTime = 0;
m_paintBehavior = PaintBehaviorNormal;
m_isPainting = false;
+ m_visuallyNonEmptyCharacterCount = 0;
+ m_visuallyNonEmptyPixelCount = 0;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
m_maintainScrollPositionAnchor = 0;
@@ -2042,8 +2044,13 @@
m_firstLayoutCallbackPending = false;
m_frame->loader()->didFirstLayout();
}
-
- if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) {
+
+ // Ensure that we always send this eventually.
+ if (!m_frame->document()->parsing())
+ m_isVisuallyNonEmpty = true;
+
+ // If the layout was done with pending sheets, we are not in fact visually non-empty yet.
+ if (m_isVisuallyNonEmpty && !m_frame->document()->didLayoutWithPendingStylesheets() && m_firstVisuallyNonEmptyLayoutCallbackPending) {
m_firstVisuallyNonEmptyLayoutCallbackPending = false;
m_frame->loader()->didFirstVisuallyNonEmptyLayout();
}
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index e495420..f828319 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -227,6 +227,8 @@
void updateLayoutAndStyleIfNeededRecursive();
void flushDeferredRepaints();
+ void incrementVisuallyNonEmptyCharacterCount(unsigned);
+ void incrementVisuallyNonEmptyPixelCount(const IntSize&);
void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
void forceLayout(bool allowSubtree = false);
@@ -433,6 +435,8 @@
PaintBehavior m_paintBehavior;
bool m_isPainting;
+ unsigned m_visuallyNonEmptyCharacterCount;
+ unsigned m_visuallyNonEmptyPixelCount;
bool m_isVisuallyNonEmpty;
bool m_firstVisuallyNonEmptyLayoutCallbackPending;
@@ -449,6 +453,29 @@
static double s_deferredRepaintDelayIncrementDuringLoading;
};
+inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
+{
+ if (m_isVisuallyNonEmpty)
+ return;
+ m_visuallyNonEmptyCharacterCount += count;
+ // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout.
+ // The first few hundred characters rarely contain the interesting content of the page.
+ static const unsigned visualCharacterThreshold = 200;
+ if (m_visuallyNonEmptyCharacterCount > visualCharacterThreshold)
+ setIsVisuallyNonEmpty();
+}
+
+inline void FrameView::incrementVisuallyNonEmptyPixelCount(const IntSize& size)
+{
+ if (m_isVisuallyNonEmpty)
+ return;
+ m_visuallyNonEmptyPixelCount += size.width() * size.height();
+ // Use a threshold value to prevent very small amounts of visible content from triggering didFirstVisuallyNonEmptyLayout
+ static const unsigned visualPixelThreshold = 256 * 256;
+ if (m_visuallyNonEmptyPixelCount > visualPixelThreshold)
+ setIsVisuallyNonEmpty();
+}
+
} // namespace WebCore
#endif // FrameView_h
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 849984b..733a219 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -51,10 +51,9 @@
RenderImage::RenderImage(Node* node)
: RenderReplaced(node, IntSize(0, 0))
, m_needsToSetSizeForAltText(false)
+ , m_didIncrementVisuallyNonEmptyPixelCount(false)
{
updateAltText();
-
- view()->frameView()->setIsVisuallyNonEmpty();
}
RenderImage::~RenderImage()
@@ -140,6 +139,11 @@
if (newImage != m_imageResource->imagePtr() || !newImage)
return;
+
+ if (!m_didIncrementVisuallyNonEmptyPixelCount) {
+ view()->frameView()->incrementVisuallyNonEmptyPixelCount(m_imageResource->imageSize(1.0f));
+ m_didIncrementVisuallyNonEmptyPixelCount = true;
+ }
bool imageSizeChanged = false;
diff --git a/Source/WebCore/rendering/RenderImage.h b/Source/WebCore/rendering/RenderImage.h
index 68910ed..7bed7c5 100644
--- a/Source/WebCore/rendering/RenderImage.h
+++ b/Source/WebCore/rendering/RenderImage.h
@@ -98,6 +98,7 @@
String m_altText;
OwnPtr<RenderImageResource> m_imageResource;
bool m_needsToSetSizeForAltText;
+ bool m_didIncrementVisuallyNonEmptyPixelCount;
friend class RenderImageScaleObserver;
};
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index 8d529c0..72f12b1 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -111,10 +111,7 @@
setIsText();
- // FIXME: It would be better to call this only if !m_text->containsOnlyWhitespace().
- // But that might slow things down, and maybe should only be done if visuallyNonEmpty
- // is still false. Not making any change for now, but should consider in the future.
- view()->frameView()->setIsVisuallyNonEmpty();
+ view()->frameView()->incrementVisuallyNonEmptyCharacterCount(m_text.length());
}
#ifndef NDEBUG