Commit b2bf5270 authored by hyatt@apple.com's avatar hyatt@apple.com

2008-09-21 David Hyatt <hyatt@apple.com>

        Rename FrameView's repaintRectangle method to repaintContentRectangle.  Make
        both it and ScrollView's updateContents method be off-limits to everyone in
        WebCore except for RenderView.

        Make repaintViewRectangle the only possible method for WebCore code to do
        an invalidation.  This ensures that all invalidates triggered by WebCore
        cross-platform code that cross ownerElement() boundaries are transform-aware.

        Make sure that iframes/frames contained inside objects that have transforms
        or reflections are not allowed to blit (this was already true for transparency).

        It is not possible to make a test for any of this, since iframe scrolling
        still doesn't work on Mac (since the invalidates are not being done
        through WebCore's cross-platform invalidation code but are instead going
        through NSScrollView's setNeedsDisplay still).

        Reviewed by Oliver Hunt

        * editing/SelectionController.cpp:
        (WebCore::SelectionController::recomputeCaretRect):
        (WebCore::SelectionController::invalidateCaretRect):
        (WebCore::SelectionController::focusedOrActiveStateChanged):
        * page/FrameView.cpp:
        (WebCore::FrameView::repaintContentRectangle):
        (WebCore::FrameView::endDeferredRepaints):
        * page/FrameView.h:
        * platform/ScrollView.h:
        * rendering/RenderBox.cpp:
        (WebCore::RenderBox::paintFillLayerExtended):
        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::enclosingPositionedAncestor):
        (WebCore::RenderLayer::requiresSlowRepaints):
        * rendering/RenderLayer.h:
        (WebCore::RenderLayer::hasTransform):
        * rendering/RenderView.cpp:
        (WebCore::RenderView::paintBoxDecorations):
        (WebCore::RenderView::repaintViewRectangle):
        (WebCore::RenderView::setSelection):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36758 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a09818a7
2008-09-21 David Hyatt <hyatt@apple.com>
Rename FrameView's repaintRectangle method to repaintContentRectangle. Make
both it and ScrollView's updateContents method be off-limits to everyone in
WebCore except for RenderView.
Make repaintViewRectangle the only possible method for WebCore code to do
an invalidation. This ensures that all invalidates triggered by WebCore
cross-platform code that cross ownerElement() boundaries are transform-aware.
Make sure that iframes/frames contained inside objects that have transforms
or reflections are not allowed to blit (this was already true for transparency).
It is not possible to make a test for any of this, since iframe scrolling
still doesn't work on Mac (since the invalidates are not being done
through WebCore's cross-platform invalidation code but are instead going
through NSScrollView's setNeedsDisplay still).
Reviewed by Oliver Hunt
* editing/SelectionController.cpp:
(WebCore::SelectionController::recomputeCaretRect):
(WebCore::SelectionController::invalidateCaretRect):
(WebCore::SelectionController::focusedOrActiveStateChanged):
* page/FrameView.cpp:
(WebCore::FrameView::repaintContentRectangle):
(WebCore::FrameView::endDeferredRepaints):
* page/FrameView.h:
* platform/ScrollView.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintFillLayerExtended):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::enclosingPositionedAncestor):
(WebCore::RenderLayer::requiresSlowRepaints):
* rendering/RenderLayer.h:
(WebCore::RenderLayer::hasTransform):
* rendering/RenderView.cpp:
(WebCore::RenderView::paintBoxDecorations):
(WebCore::RenderView::repaintViewRectangle):
(WebCore::RenderView::setSelection):
2008-09-21 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
......
......@@ -799,8 +799,10 @@ bool SelectionController::recomputeCaretRect()
if (oldRect == newRect)
return false;
v->updateContents(repaintRectForCaret(oldRect), false);
v->updateContents(repaintRectForCaret(newRect), false);
if (RenderView* view = static_cast<RenderView*>(m_frame->document()->renderer())) {
view->repaintViewRectangle(repaintRectForCaret(oldRect), false);
view->repaintViewRectangle(repaintRectForCaret(newRect), false);
}
return true;
}
......@@ -809,9 +811,7 @@ void SelectionController::invalidateCaretRect()
if (!isCaret())
return;
FrameView* v = m_sel.start().node()->document()->view();
if (!v)
return;
Document* d = m_sel.start().node()->document();
bool caretRectChanged = recomputeCaretRect();
......@@ -828,8 +828,10 @@ void SelectionController::invalidateCaretRect()
// away after clicking.
m_needsLayout = true;
if (!caretRectChanged)
v->updateContents(caretRepaintRect(), false);
if (!caretRectChanged) {
if (RenderView* view = static_cast<RenderView*>(d->renderer()))
view->repaintViewRectangle(caretRepaintRect(), false);
}
}
void SelectionController::paintCaret(GraphicsContext *p, const IntRect &rect)
......@@ -1106,8 +1108,8 @@ void SelectionController::focusedOrActiveStateChanged()
// Because RenderObject::selectionBackgroundColor() and
// RenderObject::selectionForegroundColor() check if the frame is active,
// we have to update places those colors were painted.
if (m_frame->view())
m_frame->view()->updateContents(enclosingIntRect(m_frame->selectionRect()));
if (RenderView* view = static_cast<RenderView*>(m_frame->document()->renderer()))
view->repaintViewRectangle(enclosingIntRect(m_frame->selectionRect()));
// Caret appears in the active frame.
if (activeAndFocused)
......
......@@ -714,8 +714,10 @@ void FrameView::setContentsPos(int x, int y)
const unsigned cRepaintRectUnionThreshold = 25;
void FrameView::repaintRectangle(const IntRect& r, bool immediate)
void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
{
ASSERT(!m_frame->document()->ownerElement());
if (d->m_deferringRepaints && !immediate) {
IntRect visibleContent = enclosingIntRect(visibleContentRect());
visibleContent.intersect(r);
......@@ -755,11 +757,11 @@ void FrameView::endDeferredRepaints()
ASSERT(d->m_deferringRepaints > 0);
if (--d->m_deferringRepaints == 0) {
if (d->m_repaintCount >= cRepaintRectUnionThreshold)
repaintRectangle(d->m_repaintRect, false);
repaintContentRectangle(d->m_repaintRect, false);
else {
unsigned size = d->m_repaintRects.size();
for (unsigned i = 0; i < size; i++)
repaintRectangle(d->m_repaintRects[i], false);
repaintContentRectangle(d->m_repaintRects[i], false);
d->m_repaintRects.clear();
}
}
......
......@@ -49,6 +49,8 @@ template <typename T> class Timer;
class FrameView : public ScrollView {
public:
friend class RenderView;
FrameView(Frame*);
// On the Mac, FrameViews always get their size from the underlying NSView,
......@@ -91,8 +93,7 @@ public:
void setNeedsLayout();
bool needsFullRepaint() const;
void repaintRectangle(const IntRect&, bool immediate);
void resetScrollbars();
void clear();
......@@ -167,6 +168,8 @@ private:
void dispatchScheduledEvents();
void performPostLayoutTasks();
void repaintContentRectangle(const IntRect&, bool immediate);
unsigned m_refCount;
IntSize m_size;
IntSize m_margins;
......
......@@ -90,10 +90,7 @@ namespace WebCore {
void removeChild(Widget*);
virtual void resizeContents(int w, int h);
void updateContents(const IntRect&, bool now = false);
void updateWindowRect(const IntRect&, bool now = false);
void update();
// Event coordinates are assumed to be in the coordinate space of a window that contains
// the entire widget hierarchy. It is up to the platform to decide what the precise definition
// of containing window is. (For example on Mac it is the containing NSWindow.)
......@@ -142,6 +139,11 @@ namespace WebCore {
IntPoint screenToContents(const IntPoint&) const;
#endif
protected:
void updateContents(const IntRect&, bool now = false);
void updateWindowRect(const IntRect&, bool now = false);
void update();
#if PLATFORM(MAC) && defined __OBJC__
public:
NSView* documentView() const;
......
......@@ -809,6 +809,7 @@ void RenderBox::paintFillLayerExtended(const PaintInfo& paintInfo, const Color&
} else
isTransparent = view()->frameView()->isTransparent();
// FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
if (isTransparent)
view()->frameView()->setUseSlowRepaints(); // The parent must show behind the child.
}
......
......@@ -438,7 +438,7 @@ RenderLayer *RenderLayer::stackingContext() const
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
{
RenderLayer* curr = parent();
for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned() && !curr->m_object->hasTransform();
for ( ; curr && !curr->m_object->isRenderView() && !curr->m_object->isPositioned() && !curr->m_object->isRelPositioned() && !curr->hasTransform();
curr = curr->parent()) { }
return curr;
}
......@@ -451,6 +451,15 @@ RenderLayer* RenderLayer::enclosingTransformedAncestor() const
return curr;
}
bool RenderLayer::requiresSlowRepaints() const
{
if (isTransparent() || hasReflection() || hasTransform())
return true;
if (!parent())
return false;
return parent()->requiresSlowRepaints();
}
bool RenderLayer::isTransparent() const
{
#if ENABLE(SVG)
......
......@@ -169,6 +169,8 @@ public:
bool isOverflowOnly() const { return m_isOverflowOnly; }
bool requiresSlowRepaints() const;
bool isTransparent() const;
RenderLayer* transparentAncestor();
void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer);
......@@ -313,6 +315,7 @@ public:
void setStaticX(int staticX) { m_staticX = staticX; }
void setStaticY(int staticY) { m_staticY = staticY; }
bool hasTransform() const { return m_object->hasTransform(); }
AffineTransform* transform() const { return m_transform.get(); }
void destroy(RenderArena*);
......
......@@ -155,12 +155,15 @@ void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
// Check to see if we are enclosed by a transparent layer. If so, we cannot blit
// when scrolling, and we need to use slow repaints.
// Check to see if we are enclosed by a layer that requires complex painting rules. If so, we cannot blit
// when scrolling, and we need to use slow repaints. Examples of layers that require this are transparent layers,
// layers with reflections, or transformed layers.
// FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being inside
// a transform, transparency layer, etc.
Element* elt;
for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
RenderLayer* layer = elt->renderer()->enclosingLayer();
if (layer->isTransparent() || layer->transparentAncestor()) {
if (layer->requiresSlowRepaints()) {
frameView()->setUseSlowRepaints();
break;
}
......@@ -172,7 +175,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
// This code typically only executes if the root element's visibility has been set to hidden.
// Only fill with the base background color (typically white) if we're the root document,
// since iframes/frames with no background in the child document should show the parent's background.
if (view()->isTransparent())
if (view()->isTransparent()) // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
frameView()->setUseSlowRepaints(); // The parent must show behind the child.
else {
Color baseColor = frameView()->baseBackgroundColor();
......@@ -198,7 +201,7 @@ void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
// or even invisible.
Element* elt = document()->ownerElement();
if (!elt)
m_frameView->repaintRectangle(ur, immediate);
m_frameView->repaintContentRectangle(ur, immediate);
else if (RenderObject* obj = elt->renderer()) {
IntRect vr = viewRect();
IntRect r = intersection(ur, vr);
......@@ -393,9 +396,9 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
(m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
(m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
m_frameView->updateContents(oldInfo->rect());
repaintViewRectangle(oldInfo->rect());
if (newInfo) {
m_frameView->updateContents(newInfo->rect());
repaintViewRectangle(newInfo->rect());
newSelectedObjects.remove(obj);
delete newInfo;
}
......@@ -407,7 +410,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
SelectionInfo* newInfo = i->second;
m_frameView->updateContents(newInfo->rect());
repaintViewRectangle(newInfo->rect());
delete newInfo;
}
......@@ -418,9 +421,9 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
BlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
BlockSelectionInfo* oldInfo = i->second;
if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
m_frameView->updateContents(oldInfo->rects());
repaintViewRectangle(oldInfo->rects());
if (newInfo) {
m_frameView->updateContents(newInfo->rects());
repaintViewRectangle(newInfo->rects());
newSelectedBlocks.remove(block);
delete newInfo;
}
......@@ -432,7 +435,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
BlockSelectionInfo* newInfo = i->second;
m_frameView->updateContents(newInfo->rects());
repaintViewRectangle(newInfo->rects());
delete newInfo;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment