[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.22-985-g3c00f00
eric at webkit.org
eric at webkit.org
Wed Mar 17 18:35:34 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 96b2e359c15303e5ad61e654203b84d8f72451bc
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Mar 12 07:07:06 2010 +0000
2010-03-11 Benjamin Poulain <benjamin.poulain at nokia.com>
Reviewed by Adam Treat.
Do not render the full frame when there is some elements with fixed positioning
https://bugs.webkit.org/show_bug.cgi?id=33150
The frame view take into acount the list of fixed object when scrolling
the view. If the number of object is lower than a certain threshold, the pixel
are blitted, and the invalidated area updated.
* page/FrameView.cpp:
(WebCore::FrameView::FrameView):
(WebCore::FrameView::useSlowRepaints):
(WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
(WebCore::FrameView::addFixedObject):
(WebCore::FrameView::removeFixedObject):
(WebCore::FrameView::scrollContentsFastPath):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::scrollContents):
(WebCore::ScrollView::scrollContentsFastPath):
* platform/ScrollView.h:
* rendering/RenderBlock.h:
(WebCore::RenderBlock::positionedObjects):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::styleWillChange):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleWillChange):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55890 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4cf6bf6..fe1bbe3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2010-03-11 Benjamin Poulain <benjamin.poulain at nokia.com>
+
+ Reviewed by Adam Treat.
+
+ Do not render the full frame when there is some elements with fixed positioning
+ https://bugs.webkit.org/show_bug.cgi?id=33150
+
+ The frame view take into acount the list of fixed object when scrolling
+ the view. If the number of object is lower than a certain threshold, the pixel
+ are blitted, and the invalidated area updated.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::FrameView):
+ (WebCore::FrameView::useSlowRepaints):
+ (WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
+ (WebCore::FrameView::addFixedObject):
+ (WebCore::FrameView::removeFixedObject):
+ (WebCore::FrameView::scrollContentsFastPath):
+ * page/FrameView.h:
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::scrollContents):
+ (WebCore::ScrollView::scrollContentsFastPath):
+ * platform/ScrollView.h:
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::positionedObjects):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleWillChange):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::styleWillChange):
+
2010-03-11 Aaron Boodman <aa at chromium.org>
Kill WebDocument::applicationID() (part 1).
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 2e9908a..0d9d07f 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -108,6 +108,7 @@ FrameView::FrameView(Frame* frame)
: m_frame(frame)
, m_canHaveScrollbars(true)
, m_slowRepaintObjectCount(0)
+ , m_fixedObjectCount(0)
, m_layoutTimer(this, &FrameView::layoutTimerFired)
, m_layoutRoot(0)
, m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
@@ -799,12 +800,12 @@ String FrameView::mediaType() const
bool FrameView::useSlowRepaints() const
{
- return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
}
bool FrameView::useSlowRepaintsIfNotOverlapped() const
{
- return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
}
void FrameView::setUseSlowRepaints()
@@ -828,6 +829,77 @@ void FrameView::removeSlowRepaintObject()
setCanBlitOnScroll(!useSlowRepaints());
}
+void FrameView::addFixedObject()
+{
+ if (!m_fixedObjectCount && platformWidget())
+ setCanBlitOnScroll(false);
+ ++m_fixedObjectCount;
+}
+
+void FrameView::removeFixedObject()
+{
+ ASSERT(m_fixedObjectCount > 0);
+ --m_fixedObjectCount;
+ if (!m_fixedObjectCount)
+ setCanBlitOnScroll(!useSlowRepaints());
+}
+
+bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+ const size_t fixedObjectThreshold = 5;
+
+ ListHashSet<RenderBox*>* positionedObjects = 0;
+ if (RenderView* root = m_frame->contentRenderer())
+ positionedObjects = root->positionedObjects();
+
+ if (!positionedObjects || positionedObjects->isEmpty()) {
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+ return true;
+ }
+
+ // Get the rects of the fixed objects visible in the rectToScroll
+ Vector<IntRect, fixedObjectThreshold> subRectToUpdate;
+ bool updateInvalidatedSubRect = true;
+ ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
+ for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
+ RenderBox* renderBox = *it;
+ if (renderBox->style()->position() != FixedPosition)
+ continue;
+ IntRect topLevelRect;
+ IntRect updateRect = renderBox->paintingRootRect(topLevelRect);
+ updateRect.move(-scrollX(), -scrollY());
+ updateRect.intersect(rectToScroll);
+ if (!updateRect.isEmpty()) {
+ if (subRectToUpdate.size() >= fixedObjectThreshold) {
+ updateInvalidatedSubRect = false;
+ break;
+ }
+ subRectToUpdate.append(updateRect);
+ }
+ }
+
+ // Scroll the view
+ if (updateInvalidatedSubRect) {
+ // 1) scroll
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+ // 2) update the area of fixed objects that has been invalidated
+ size_t fixObjectsCount = subRectToUpdate.size();
+ for (size_t i = 0; i < fixObjectsCount; ++i) {
+ IntRect updateRect = subRectToUpdate[i];
+ IntRect scrolledRect = updateRect;
+ scrolledRect.move(scrollDelta);
+ updateRect.unite(scrolledRect);
+ updateRect.intersect(rectToScroll);
+ hostWindow()->invalidateContentsAndWindow(updateRect, false);
+ }
+ return true;
+ }
+
+ // the number of fixed objects exceed the threshold, we cannot use the fast path
+ return false;
+}
+
void FrameView::setIsOverlapped(bool isOverlapped)
{
if (isOverlapped == m_isOverlapped)
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 1d5a312..15058a6 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -149,6 +149,9 @@ public:
void addSlowRepaintObject();
void removeSlowRepaintObject();
+ void addFixedObject();
+ void removeFixedObject();
+
void beginDeferredRepaints();
void endDeferredRepaints();
void checkStopDelayingDeferredRepaints();
@@ -203,6 +206,9 @@ public:
bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
void invalidateScrollCorner();
+protected:
+ virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
private:
FrameView(Frame*);
@@ -272,6 +278,7 @@ private:
bool m_isOverlapped;
bool m_contentIsOpaque;
unsigned m_slowRepaintObjectCount;
+ unsigned m_fixedObjectCount;
int m_borderX, m_borderY;
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 4fd5cfd..c2a0adf 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -510,8 +510,9 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
}
if (canBlitOnScroll()) { // The main frame can just blit the WebView window
- // FIXME: Find a way to scroll subframes with this faster path
- hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
+ // FIXME: Find a way to scroll subframes with this faster path
+ if (!scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect))
+ hostWindow()->invalidateContentsForSlowScroll(updateRect, false);
} else {
// We need to go ahead and repaint the entire backing store. Do it now before moving the
// windowed plugins.
@@ -525,6 +526,12 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
hostWindow()->invalidateWindow(IntRect(), true);
}
+bool ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+ return true;
+}
+
IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
{
IntPoint viewPoint = convertFromContainingWindow(windowPoint);
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 111d6b6..f5bb169 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -249,6 +249,9 @@ protected:
IntRect scrollCornerRect() const;
virtual void updateScrollCorner();
virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+
+ // Scroll the content by blitting the pixels
+ virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
private:
RefPtr<Scrollbar> m_horizontalScrollbar;
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 510a311..184f983 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -74,6 +74,7 @@ public:
void insertPositionedObject(RenderBox*);
void removePositionedObject(RenderBox*);
void removePositionedObjects(RenderBlock*);
+ ListHashSet<RenderBox*>* positionedObjects() const { return m_positionedObjects; }
void addPercentHeightDescendant(RenderBox*);
static void removePercentHeightDescendant(RenderBox*);
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 1d8fb12..1c0e837 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -146,6 +146,16 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl
removeFloatingOrPositionedChildFromBlockLists();
}
}
+ if (FrameView *frameView = view()->frameView()) {
+ bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
+ bool oldStyleIsFixed = style() && style()->position() == FixedPosition;
+ if (newStyleIsFixed != oldStyleIsFixed) {
+ if (newStyleIsFixed)
+ frameView->addFixedObject();
+ else
+ frameView->removeFixedObject();
+ }
+ }
RenderBoxModelObject::styleWillChange(diff, newStyle);
}
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 3f39c15..8212dca 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1652,9 +1652,6 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
s_affectsParentBlock = false;
if (view()->frameView()) {
- // FIXME: A better solution would be to only invalidate the fixed regions when scrolling. It's overkill to
- // prevent the entire view from blitting on a scroll.
-
bool shouldBlitOnFixedBackgroundImage = false;
#if ENABLE(FAST_MOBILE_SCROLLING)
// On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
@@ -1664,10 +1661,8 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
shouldBlitOnFixedBackgroundImage = true;
#endif
- bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition
- || (!shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage()));
- bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition
- || (!shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage()));
+ bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
+ bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
if (oldStyleSlowScroll != newStyleSlowScroll) {
if (oldStyleSlowScroll)
view()->frameView()->removeSlowRepaintObject();
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list