+2007-02-23 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Mitz.
+
+ - 12.5% speedup on BenchJS test 6
+
+ It turns out that calling documentVisibleRect on an NSScrollView is pretty expensive,
+ and calling visibleRect even more so. Take measures to call them less often.
+
+ * platform/mac/ScrollViewMac.mm:
+ (WebCore::ScrollView::visibleContentRect): Use documentVisibleRect when possible.
+ (WebCore::ScrollView::updateContents): Use visibleContentRect to be able to use
+ documentVisibleRect when possible.
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::repaintViewRectangle): Don't get or intersect with viewRect
+ if we don't have a parent frame, since the ScrollView will do that anyway. Also,
+ don't get contentX and contentY separately since they are in the viewRect already.
+ (WebCore::RenderView::viewRect): Use visibleContentRect instead of getting each
+ coordinate individually, to avoid calling documentVisibleRect repeatedly.
+
2007-02-23 Maciej Stachowiak <mjs@apple.com>
Reviewed by Mitz.
FloatRect ScrollView::visibleContentRect() const
{
+ NSScrollView *view = (NSScrollView *)getView();
+
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- if (NSView *docView = getDocumentView())
- return [docView visibleRect];
+ if ([view isKindOfClass:[NSScrollView class]])
+ return [view documentVisibleRect];
+ else
+ return [view visibleRect];
END_BLOCK_OBJC_EXCEPTIONS;
+
return FloatRect();
}
BEGIN_BLOCK_OBJC_EXCEPTIONS;
NSView *view = getView();
-
if ([view isKindOfClass:[NSScrollView class]])
view = getDocumentView();
+ NSRect visibleRect = visibleContentRect();
+
// Checking for rect visibility is an important optimization for the case of
// Select All of a large document. AppKit does not do this check, and so ends
// up building a large complicated NSRegion if we don't perform the check.
- NSRect dirtyRect = NSIntersectionRect(rect, [view visibleRect]);
+ NSRect dirtyRect = NSIntersectionRect(rect, visibleRect);
if (!NSIsEmptyRect(dirtyRect)) {
[view setNeedsDisplayInRect:dirtyRect];
if (now) {
if (printing() || ur.width() == 0 || ur.height() == 0)
return;
- IntRect vr = viewRect();
- if (m_frameView && ur.intersects(vr)) {
- // We always just invalidate the root view, since we could be an iframe that is clipped out
- // or even invisible.
+ if (!m_frameView)
+ return;
+
+ // We always just invalidate the root view, since we could be an iframe that is clipped out
+ // or even invisible.
+ Element* elt = element()->document()->ownerElement();
+ if (!elt)
+ m_frameView->repaintRectangle(ur, immediate);
+ else if (RenderObject* obj = elt->renderer()) {
+ IntRect vr = viewRect();
IntRect r = intersection(ur, vr);
- Element* elt = element()->document()->ownerElement();
- if (!elt)
- m_frameView->repaintRectangle(r, immediate);
- else if (RenderObject* obj = elt->renderer()) {
- // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
- // rectangle.
- r.move(-m_frameView->contentsX(), -m_frameView->contentsY());
-
- // FIXME: Hardcoded offsets here are not good.
- int yFrameOffset = m_frameView->hasBorder() ? 2 : 0;
- int xFrameOffset = m_frameView->hasBorder() ? 1 : 0;
- r.move(obj->borderLeft() + obj->paddingLeft() + xFrameOffset,
- obj->borderTop() + obj->paddingTop() + yFrameOffset);
- obj->repaintRectangle(r, immediate);
- }
+
+ // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
+ // rectangle.
+ r.move(-vr.x(), -vr.y());
+
+ // FIXME: Hardcoded offsets here are not good.
+ int yFrameOffset = m_frameView->hasBorder() ? 2 : 0;
+ int xFrameOffset = m_frameView->hasBorder() ? 1 : 0;
+ r.move(obj->borderLeft() + obj->paddingLeft() + xFrameOffset,
+ obj->borderTop() + obj->paddingTop() + yFrameOffset);
+ obj->repaintRectangle(r, immediate);
}
}
if (printing())
return IntRect(0, 0, m_width, m_height);
if (m_frameView)
- return IntRect(m_frameView->contentsX(),
- m_frameView->contentsY(),
- m_frameView->visibleWidth(),
- m_frameView->visibleHeight());
+ return enclosingIntRect(m_frameView->visibleContentRect());
return IntRect();
}