Changeset 16988 in webkit


Ignore:
Timestamp:
Oct 11, 2006 8:04:01 AM (18 years ago)
Author:
antti
Message:

LayoutTests:

Reviewed by Hyatt.


Test for http://bugs.webkit.org/show_bug.cgi?id=4377

  • fast/layers/layer-visibility-expected.checksum: Added.
  • fast/layers/layer-visibility-expected.png: Added.
  • fast/layers/layer-visibility-expected.txt: Added.
  • fast/layers/layer-visibility.html: Added.

WebCore:

Reviewed by Hyatt.


http://bugs.webkit.org/show_bug.cgi?id=4377


Respect css visibility semantics for layers too

  • rendering/RenderContainer.cpp: (WebCore::RenderContainer::removeChildNode): (WebCore::RenderContainer::appendChildNode): (WebCore::RenderContainer::insertChildNode):
  • rendering/RenderLayer.cpp: (WebCore::RenderLayer::RenderLayer): (WebCore::RenderLayer::updateLayerPositions): (WebCore::RenderLayer::setHasVisibleContent): (WebCore::RenderLayer::dirtyVisibleContentStatus): (WebCore::RenderLayer::childVisibilityChanged): (WebCore::RenderLayer::dirtyVisibleDescendantStatus): (WebCore::RenderLayer::updateVisibilityStatus): (WebCore::RenderLayer::addChild): (WebCore::RenderLayer::removeChild): (WebCore::RenderLayer::updateZOrderLists): (WebCore::RenderLayer::collectLayers):
  • rendering/RenderLayer.h: (WebCore::RenderLayer::hasVisibleContent):
  • rendering/RenderObject.cpp: (WebCore::RenderObject::setStyle):
Location:
trunk
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r16978 r16988  
     12006-10-11  Antti Koivisto  <koivisto@iki.fi>
     2
     3        Reviewed by Hyatt.
     4       
     5        Test for http://bugs.webkit.org/show_bug.cgi?id=4377
     6
     7        * fast/layers/layer-visibility-expected.checksum: Added.
     8        * fast/layers/layer-visibility-expected.png: Added.
     9        * fast/layers/layer-visibility-expected.txt: Added.
     10        * fast/layers/layer-visibility.html: Added.
     11
    1122006-10-10  Oliver Hunt  <ohunt@apple.com>
    213
  • trunk/WebCore/ChangeLog

    r16987 r16988  
     12006-10-11  Antti Koivisto  <koivisto@iki.fi>
     2
     3        Reviewed by Hyatt.
     4       
     5        http://bugs.webkit.org/show_bug.cgi?id=4377
     6       
     7        Respect css visibility semantics for layers too
     8
     9        * rendering/RenderContainer.cpp:
     10        (WebCore::RenderContainer::removeChildNode):
     11        (WebCore::RenderContainer::appendChildNode):
     12        (WebCore::RenderContainer::insertChildNode):
     13        * rendering/RenderLayer.cpp:
     14        (WebCore::RenderLayer::RenderLayer):
     15        (WebCore::RenderLayer::updateLayerPositions):
     16        (WebCore::RenderLayer::setHasVisibleContent):
     17        (WebCore::RenderLayer::dirtyVisibleContentStatus):
     18        (WebCore::RenderLayer::childVisibilityChanged):
     19        (WebCore::RenderLayer::dirtyVisibleDescendantStatus):
     20        (WebCore::RenderLayer::updateVisibilityStatus):
     21        (WebCore::RenderLayer::addChild):
     22        (WebCore::RenderLayer::removeChild):
     23        (WebCore::RenderLayer::updateZOrderLists):
     24        (WebCore::RenderLayer::collectLayers):
     25        * rendering/RenderLayer.h:
     26        (WebCore::RenderLayer::hasVisibleContent):
     27        * rendering/RenderObject.cpp:
     28        (WebCore::RenderObject::setStyle):
     29
    1302006-10-10  Maciej Stachowiak  <mjs@apple.com>
    231
  • trunk/WebCore/rendering/RenderContainer.cpp

    r16721 r16988  
    178178
    179179    if (!documentBeingDestroyed()) {
    180         // Keep our layer hierarchy updated.
    181         oldChild->removeLayers(enclosingLayer());
     180        // if we remove visible child from an invisible parent, we don't know the layer visibility any more
     181        RenderLayer* layer = 0;
     182        if (m_style->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->layer()) {
     183            layer = enclosingLayer();
     184            layer->dirtyVisibleContentStatus();
     185        }
     186
     187         // Keep our layer hierarchy updated.
     188        if (oldChild->firstChild() || oldChild->layer()) {
     189            if (!layer) layer = enclosingLayer();           
     190            oldChild->removeLayers(layer);
     191        }
    182192       
    183193        // If oldChild is the start or end of the selection, then clear the selection to
     
    386396    // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
    387397    // and don't have a layer attached to ourselves.
     398    RenderLayer* layer = 0;
    388399    if (newChild->firstChild() || newChild->layer()) {
    389         RenderLayer* layer = enclosingLayer();
     400        layer = enclosingLayer();
    390401        newChild->addLayers(layer, newChild);
     402    }
     403
     404    // if the new child is visible but this object was not, tell the layer it has some visible content
     405    // that needs to be drawn and layer visibility optimization can't be used
     406    if (style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->layer()) {
     407        if (!layer) layer = enclosingLayer();
     408        layer->setHasVisibleContent(true);
    391409    }
    392410   
     
    427445    child->setParent(this);
    428446   
    429     // Keep our layer hierarchy updated.
    430     RenderLayer* layer = enclosingLayer();
    431     child->addLayers(layer, child);
     447    // Keep our layer hierarchy updated.  Optimize for the common case where we don't have any children
     448    // and don't have a layer attached to ourselves.
     449    RenderLayer* layer = 0;
     450    if (child->firstChild() || child->layer()) {
     451        layer = enclosingLayer();
     452        child->addLayers(layer, child);
     453    }
     454
     455    // if the new child is visible but this object was not, tell the layer it has some visible content
     456    // that needs to be drawn and layer visibility optimization can't be used
     457    if (style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->layer()) {
     458        if (!layer) layer = enclosingLayer();
     459        layer->setHasVisibleContent(true);
     460    }
    432461
    433462    child->setNeedsLayoutAndMinMaxRecalc();
  • trunk/WebCore/rendering/RenderLayer.cpp

    r16975 r16988  
    142142m_repaintOverflowOnResize(false),
    143143m_overflowStatusDirty(true),
     144m_visibleContentStatusDirty( true ),
     145m_hasVisibleContent( false ),
     146m_visibleDescendantStatusDirty( false ),
     147m_hasVisibleDescendant( false ),
    144148m_marquee(0)
    145149{
     150    if (!object->firstChild() && object->style()) {
     151        m_visibleContentStatusDirty = false;
     152        m_hasVisibleContent = object->style()->visibility() == VISIBLE;
     153    }
    146154}
    147155
     
    183191    positionOverflowControls();
    184192
    185     // FIXME: Child object could override visibility.
    186     if (m_object->style()->visibility() == VISIBLE) {
     193    updateVisibilityStatus();
     194       
     195    if (m_hasVisibleContent) {
    187196        int x, y;
    188197        m_object->absolutePosition(x, y);
     
    216225    if (m_marquee)
    217226        m_marquee->updateMarqueePosition();
     227}
     228
     229void RenderLayer::setHasVisibleContent(bool b)
     230{
     231    if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
     232        return;
     233    m_visibleContentStatusDirty = false;
     234    m_hasVisibleContent = b;
     235    if (parent())
     236        parent()->childVisibilityChanged(m_hasVisibleContent);
     237}
     238
     239void RenderLayer::dirtyVisibleContentStatus()
     240{
     241    m_visibleContentStatusDirty = true;
     242    if (parent())
     243        parent()->dirtyVisibleDescendantStatus();
     244}
     245
     246void RenderLayer::childVisibilityChanged(bool newVisibility)
     247{
     248    if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty)
     249        return;
     250    if (newVisibility) {
     251        RenderLayer* l = this;
     252        while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) {
     253            l->m_hasVisibleDescendant = true;
     254            l = l->parent();
     255        }
     256    } else
     257        dirtyVisibleDescendantStatus();
     258}
     259
     260void RenderLayer::dirtyVisibleDescendantStatus()
     261{
     262    RenderLayer* l = this;
     263    while (l && !l->m_visibleDescendantStatusDirty) {
     264        l->m_visibleDescendantStatusDirty = true;
     265        l = l->parent();
     266    }
     267}
     268
     269void RenderLayer::updateVisibilityStatus()
     270{
     271    if (m_visibleDescendantStatusDirty) {
     272        m_hasVisibleDescendant = false;
     273        for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
     274            child->updateVisibilityStatus();       
     275            if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
     276                m_hasVisibleDescendant = true;
     277                break;
     278            }
     279        }
     280        m_visibleDescendantStatusDirty = false;
     281    }
     282
     283    if (m_visibleContentStatusDirty) {
     284        if (m_object->style()->visibility() == VISIBLE)
     285            m_hasVisibleContent = true;
     286        else {
     287            // layer may be hidden but still have some visible content, check for this
     288            m_hasVisibleContent = false;
     289            RenderObject* r = m_object->firstChild();
     290            while (r) {
     291                if (r->style()->visibility() == VISIBLE) {
     292                    m_hasVisibleContent = true;
     293                    break;
     294                }
     295                if (r->firstChild() && !r->firstChild()->layer())
     296                    r = r->firstChild();
     297                else if (r->nextSibling() && !r->nextSibling()->layer())
     298                    r = r->nextSibling();
     299                else {
     300                    while (r && (!r->nextSibling() || r->nextSibling()->layer())) {
     301                        r = r->parent();
     302                        if (r==m_object)
     303                            r = 0;
     304                    }
     305                    if (r)
     306                        r = r->nextSibling();
     307                }
     308            }
     309        }   
     310        m_visibleContentStatusDirty = false;
     311    }
    218312}
    219313
     
    445539            stackingContext->dirtyZOrderLists();
    446540    }
     541   
     542    child->updateVisibilityStatus();
     543    if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
     544        childVisibilityChanged(true);
    447545}
    448546
     
    474572    oldChild->setNextSibling(0);
    475573    oldChild->setParent(0);
     574   
     575    oldChild->updateVisibilityStatus();
     576    if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
     577        childVisibilityChanged(false);
    476578   
    477579    return oldChild;
     
    18131915    if (!isStackingContext() || !m_zOrderListsDirty)
    18141916        return;
    1815    
     1917       
    18161918    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
    18171919        child->collectLayers(m_posZOrderList, m_negZOrderList);
     
    18441946void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
    18451947{
    1846     // FIXME: A child render object or layer could override visibility.  Don't remove this
    1847     // optimization though until RenderObject's nodeAtPoint is patched to understand what to do
    1848     // when visibility is overridden by a child.
    1849     if (renderer()->style()->visibility() != VISIBLE)
    1850         return;
    1851 
     1948    updateVisibilityStatus();
     1949       
    18521950    // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
    1853     if (!isOverflowOnly()) {
     1951    if (m_hasVisibleContent && !isOverflowOnly()) {
    18541952        // Determine which buffer the child should be in.
    18551953        Vector<RenderLayer*>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
     
    18651963    // Recur into our children to collect more layers, but only if we don't establish
    18661964    // a stacking context.
    1867     if (!isStackingContext())
     1965    if (m_hasVisibleDescendant && !isStackingContext())
    18681966        for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
    18691967            child->collectLayers(posBuffer, negBuffer);
  • trunk/WebCore/rendering/RenderLayer.h

    r16879 r16988  
    273273    void updateOverflowList();
    274274    Vector<RenderLayer*>* overflowList() const { return m_overflowList; }
     275   
     276    bool hasVisibleContent() const { return m_hasVisibleContent; }
     277    void setHasVisibleContent(bool b);
     278    void dirtyVisibleContentStatus();
    275279
    276280    // Gets the nearest enclosing positioned ancestor layer (also includes
     
    340344
    341345    void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
     346   
     347    void childVisibilityChanged(bool newVisibility);
     348    void dirtyVisibleDescendantStatus();
     349    void updateVisibilityStatus();
     350       
    342351protected:   
    343352    RenderObject* m_object;
     
    410419    bool m_horizontalOverflow : 1;
    411420    bool m_verticalOverflow : 1;
     421    bool m_visibleContentStatusDirty : 1;
     422    bool m_hasVisibleContent : 1;
     423    bool m_visibleDescendantStatusDirty : 1;
     424    bool m_hasVisibleDescendant : 1;
    412425   
    413426    Marquee* m_marquee; // Used by layers with overflow:marquee
  • trunk/WebCore/rendering/RenderObject.cpp

    r16975 r16988  
    20852085                    layer()->dirtyZOrderLists();
    20862086            }
     2087            // keep layer hierarchy visibility bits up to date if visibility changes
     2088            if (m_style->visibility() != style->visibility()) {
     2089                RenderLayer* l = enclosingLayer();
     2090                if (style->visibility() == VISIBLE && l)
     2091                    l->setHasVisibleContent(true);
     2092                else if (l && l->hasVisibleContent() &&
     2093                    (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE))
     2094                    l->dirtyVisibleContentStatus();
     2095            }           
    20872096        }
    20882097
Note: See TracChangeset for help on using the changeset viewer.