[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9
eric at webkit.org
eric at webkit.org
Thu Feb 4 21:27:09 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 4644ecca4204b7e9f8de9df8175f5ae6160dd132
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Jan 25 12:37:37 2010 +0000
2010-01-25 Benjamin Poulain <benjamin.poulain at nokia.com>
Reviewed by Antti Koivisto.
Do not render the full frame when there is some elements with fixed positioning
https://bugs.webkit.org/show_bug.cgi?id=33150
Do not render the full frame when there is some elements with fixed positioning
https://bugs.webkit.org/show_bug.cgi?id=33150
* page/FrameView.cpp:
(WebCore::FrameView::useSlowRepaints):
(WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
(WebCore::FrameView::registerFixedPositionedObject):
(WebCore::FrameView::unregisterFixedPositionedObject):
(WebCore::FrameView::scrollContentsFastPath):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::scrollContents):
(WebCore::ScrollView::scrollContentsFastPath):
* platform/ScrollView.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::styleWillChange):
(WebCore::RenderObject::destroy):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d5c8773..3c49245 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-25 Benjamin Poulain <benjamin.poulain at nokia.com>
+
+ Reviewed by Antti Koivisto.
+
+ Do not render the full frame when there is some elements with fixed positioning
+ https://bugs.webkit.org/show_bug.cgi?id=33150
+
+ Do not render the full frame when there is some elements with fixed positioning
+ https://bugs.webkit.org/show_bug.cgi?id=33150
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::useSlowRepaints):
+ (WebCore::FrameView::useSlowRepaintsIfNotOverlapped):
+ (WebCore::FrameView::registerFixedPositionedObject):
+ (WebCore::FrameView::unregisterFixedPositionedObject):
+ (WebCore::FrameView::scrollContentsFastPath):
+ * page/FrameView.h:
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::scrollContents):
+ (WebCore::ScrollView::scrollContentsFastPath):
+ * platform/ScrollView.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::styleWillChange):
+ (WebCore::RenderObject::destroy):
+
2010-01-24 Pavel Feldman <pfeldman at chromium.org>
Reviewed by Timothy Hatcher.
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 21666ae..efc6c69 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -784,12 +784,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_fixedPositionedObjects.isEmpty()) || m_isOverlapped || !m_contentIsOpaque;
}
bool FrameView::useSlowRepaintsIfNotOverlapped() const
{
- return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && !m_fixedPositionedObjects.isEmpty()) || !m_contentIsOpaque;
}
void FrameView::setUseSlowRepaints()
@@ -813,6 +813,73 @@ void FrameView::removeSlowRepaintObject()
setCanBlitOnScroll(!useSlowRepaints());
}
+
+void FrameView::registerFixedPositionedObject(RenderObject* object)
+{
+ if (platformWidget() && m_fixedPositionedObjects.isEmpty())
+ setCanBlitOnScroll(false);
+ m_fixedPositionedObjects.add(object);
+}
+
+void FrameView::unregisterFixedPositionedObject(RenderObject* object)
+{
+ bool wasEmpty = m_fixedPositionedObjects.isEmpty();
+ m_fixedPositionedObjects.remove(object);
+ if (platformWidget() && !wasEmpty && m_fixedPositionedObjects.isEmpty())
+ setCanBlitOnScroll(!useSlowRepaints());
+}
+
+void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+ const size_t fixedObjectNumberThreshold = 5;
+
+ if (m_fixedPositionedObjects.isEmpty())
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+ else {
+ Vector<RenderObject*, fixedObjectNumberThreshold> fixedObjectsInViewport;
+
+ bool updateInvalidatedSubRect = true;
+ // Get a list of fixed objects that are not in transformations
+ HashSet<RenderObject*>::const_iterator end = m_fixedPositionedObjects.end();
+ HashSet<RenderObject*>::const_iterator it = m_fixedPositionedObjects.begin();
+ for (; it != end; ++it) {
+ RenderObject* obj = *it;
+ // make sure the parent layer has not been transformed
+ if (obj->containingBlock() == obj->view()) {
+ if (fixedObjectsInViewport.size() >= fixedObjectNumberThreshold) {
+ updateInvalidatedSubRect = false;
+ break;
+ }
+ fixedObjectsInViewport.append(obj);
+ }
+ }
+
+ // scroll the content
+ if (updateInvalidatedSubRect) {
+ // 1) scroll
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+
+ // 2) update the area of fixed objets that has been invalidated
+ size_t fixObjectsCount = fixedObjectsInViewport.size();
+ for (size_t i = 0; i < fixObjectsCount; ++i) {
+ IntRect topLevelRect;
+ IntRect updateRect = fixedObjectsInViewport[i]->paintingRootRect(topLevelRect);
+ updateRect.move(-scrollX(), -scrollY());
+ IntRect scrolledRect = updateRect;
+ scrolledRect.move(scrollDelta);
+ updateRect.unite(scrolledRect);
+ updateRect.intersect(rectToScroll);
+ hostWindow()->repaint(updateRect, true, false, true);
+ }
+ } else {
+ // the number of fixed objects exceed the threshold, so we repaint everything.
+ IntRect updateRect = clipRect;
+ updateRect.intersect(rectToScroll);
+ hostWindow()->repaint(updateRect, true, false, true);
+ }
+ }
+}
+
void FrameView::setIsOverlapped(bool isOverlapped)
{
if (isOverlapped == m_isOverlapped)
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index b27ffd8..c3de05b 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -145,6 +145,11 @@ public:
void addSlowRepaintObject();
void removeSlowRepaintObject();
+ // Methods to manage the objects that are fixed
+ // in the view when scrolling
+ void registerFixedPositionedObject(RenderObject* object);
+ void unregisterFixedPositionedObject(RenderObject* object);
+
void beginDeferredRepaints();
void endDeferredRepaints();
void checkStopDelayingDeferredRepaints();
@@ -199,6 +204,9 @@ public:
bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
void invalidateScrollCorner();
+protected:
+ virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
private:
FrameView(Frame*);
@@ -268,6 +276,7 @@ private:
bool m_isOverlapped;
bool m_contentIsOpaque;
unsigned m_slowRepaintObjectCount;
+ HashSet<RenderObject*> m_fixedPositionedObjects;
int m_borderX, m_borderY;
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index e4291cc..0156680 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -513,7 +513,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
if (canBlitOnScroll()) { // The main frame can just blit the WebView window
// FIXME: Find a way to blit subframes without blitting overlapping content
- hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect);
+ scrollContentsFastPath(-scrollDelta, scrollViewRect, clipRect);
} else {
// We need to go ahead and repaint the entire backing store. Do it now before moving the
// windowed plugins.
@@ -528,6 +528,11 @@ void ScrollView::scrollContents(const IntSize& scrollDelta)
hostWindow()->paint();
}
+void ScrollView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+{
+ hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
+}
+
IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
{
IntPoint viewPoint = convertFromContainingWindow(windowPoint);
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index a7173a7..6ca2581 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 void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
private:
RefPtr<Scrollbar> m_horizontalScrollbar;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index 5ddb882..c6c015a 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -1647,10 +1647,8 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
} else
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.
-
+ FrameView* frameView = view()->frameView();
+ if (frameView) {
bool shouldBlitOnFixedBackgroundImage = false;
#if ENABLE(FAST_MOBILE_SCROLLING)
// On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
@@ -1660,15 +1658,32 @@ 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();
+ frameView->removeSlowRepaintObject();
if (newStyleSlowScroll)
- view()->frameView()->addSlowRepaintObject();
+ frameView->addSlowRepaintObject();
+ }
+
+ bool newStyleHasTransform = newStyle && (newStyle->hasTransformRelatedProperty());
+ if (!newStyleHasTransform) {
+ bool newStyleHasFixedPosition = newStyle && (newStyle->position() == FixedPosition);
+ bool oldStyleHasFixedPosition = m_style && (m_style->position() == FixedPosition);
+
+ if (oldStyleHasFixedPosition != newStyleHasFixedPosition) {
+ if (newStyleHasFixedPosition)
+ frameView->registerFixedPositionedObject(this);
+ else
+ frameView->unregisterFixedPositionedObject(this);
+ } else {
+ // if previously had a fix position, but had a transform, which has been removed
+ bool oldStyleHasTransform = m_style && (m_style->hasTransformRelatedProperty());
+ if (oldStyleHasTransform && newStyleHasFixedPosition)
+ frameView->registerFixedPositionedObject(this);
+ }
}
}
}
@@ -1931,6 +1946,13 @@ bool RenderObject::isSelectionBorder() const
void RenderObject::destroy()
{
+ // unregister from the view if the object had a fixed position
+ if (m_style && m_style->position() == FixedPosition) {
+ FrameView* frameView = document()->view();
+ if (frameView)
+ frameView->unregisterFixedPositionedObject(this);
+ }
+
// Destroy any leftover anonymous children.
RenderObjectChildList* children = virtualChildren();
if (children)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list