Changeset 106281 in webkit


Ignore:
Timestamp:
Jan 30, 2012 1:11:48 PM (12 years ago)
Author:
mihnea@adobe.com
Message:

[CSSRegions]Add support for background-color in region styling
https://bugs.webkit.org/show_bug.cgi?id=71488

Reviewed by David Hyatt.

Source/WebCore:

Based on work by Alexandru Chiculita (Alexandru Chiculita).
Previous patches for region styling were touching RenderObject::style() method. After several attempts to avoid regressions
(including caching of RenderObject::style() pointer in most used methods), we decided to attempt a different approach:
Step1: before each region is repainted, we compute the style for each box that falls into the region
Step2: before paint, we store the box original style
Step3: paint the region contents using the style in region
Step4: after paint is finished, we restore the box original style (and store the box style in region for future region paint)

Tests for region styling are also enabled with this patch.

  • WebCore.exp.in:
  • rendering/RenderFlowThread.cpp:

(WebCore::RenderFlowThread::clearRenderBoxCustomStyle):
(WebCore::RenderFlowThread::setRegionRangeForBox):

  • rendering/RenderFlowThread.h:

():

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::paint):
(WebCore::RenderLayer::hitTest):

  • rendering/RenderObject.cpp:
  • rendering/RenderObject.h:

(WebCore::RenderObject::style):
(RenderObject):

  • rendering/RenderObjectChildList.cpp:

(WebCore::RenderObjectChildList::removeChildNode):

  • rendering/RenderRegion.cpp:

(WebCore::RenderRegion::RenderRegion):
(WebCore::RenderRegion::setRegionBoxesRegionStyle):
(WebCore):
(WebCore::RenderRegion::restoreRegionBoxesOriginalStyle):
(WebCore::RenderRegion::paintReplaced):
(WebCore::RenderRegion::setRenderBoxRegionInfo):
(WebCore::RenderRegion::takeRenderBoxRegionInfo):
(WebCore::RenderRegion::removeRenderBoxRegionInfo):
(WebCore::RenderRegion::renderBoxRegionStyle):
(WebCore::RenderRegion::computeStyleInRegion):
(WebCore::RenderRegion::clearBoxStyleInRegion):

  • rendering/RenderRegion.h:

(RenderRegion):

  • rendering/RenderView.cpp:

(WebCore::RenderView::RenderView):

  • rendering/RenderView.h:

(WebCore):
(RenderView):

LayoutTests:

Enable the region styling tests again.

  • platform/mac-snowleopard/Skipped:
Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r106279 r106281  
     12012-01-30  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSSRegions]Add support for background-color in region styling
     4        https://bugs.webkit.org/show_bug.cgi?id=71488
     5
     6        Reviewed by David Hyatt.
     7
     8        Enable the region styling tests again.
     9
     10        * platform/mac-snowleopard/Skipped:
     11
    1122012-01-30  Joshua Bell  <jsbell@chromium.org>
    213
  • trunk/LayoutTests/platform/mac-snowleopard/Skipped

    r105532 r106281  
    186186# Regression in performance
    187187# https://bugs.webkit.org/show_bug.cgi?id=74141
    188 fast/regions/region-style-block-background-color.html
    189 fast/regions/region-style-block-background-color2.html
    190 fast/regions/region-style-image-background-color.html
    191 fast/regions/region-style-inline-background-color.html
     188#fast/regions/region-style-block-background-color.html
     189#fast/regions/region-style-block-background-color2.html
     190#fast/regions/region-style-image-background-color.html
     191#fast/regions/region-style-inline-background-color.html
    192192
    193193# HiDPI tests have lower-level platform dependencies on Mac
  • trunk/Source/WebCore/ChangeLog

    r106280 r106281  
     12012-01-30  Mihnea Ovidenie  <mihnea@adobe.com>
     2
     3        [CSSRegions]Add support for background-color in region styling
     4        https://bugs.webkit.org/show_bug.cgi?id=71488
     5
     6        Reviewed by David Hyatt.
     7
     8        Based on work by Alexandru Chiculita (achicu@adobe.com).
     9        Previous patches for region styling were touching RenderObject::style() method. After several attempts to avoid regressions
     10        (including caching of RenderObject::style() pointer in most used methods), we decided to attempt a different approach:
     11        Step1: before each region is repainted, we compute the style for each box that falls into the region
     12        Step2: before paint, we store the box original style
     13        Step3: paint the region contents using the style in region
     14        Step4: after paint is finished, we restore the box original style (and store the box style in region for future region paint)
     15
     16        Tests for region styling are also enabled with this patch.
     17
     18        * WebCore.exp.in:
     19        * rendering/RenderFlowThread.cpp:
     20        (WebCore::RenderFlowThread::clearRenderBoxCustomStyle):
     21        (WebCore::RenderFlowThread::setRegionRangeForBox):
     22        * rendering/RenderFlowThread.h:
     23        ():
     24        * rendering/RenderLayer.cpp:
     25        (WebCore::RenderLayer::paint):
     26        (WebCore::RenderLayer::hitTest):
     27        * rendering/RenderObject.cpp:
     28        * rendering/RenderObject.h:
     29        (WebCore::RenderObject::style):
     30        (RenderObject):
     31        * rendering/RenderObjectChildList.cpp:
     32        (WebCore::RenderObjectChildList::removeChildNode):
     33        * rendering/RenderRegion.cpp:
     34        (WebCore::RenderRegion::RenderRegion):
     35        (WebCore::RenderRegion::setRegionBoxesRegionStyle):
     36        (WebCore):
     37        (WebCore::RenderRegion::restoreRegionBoxesOriginalStyle):
     38        (WebCore::RenderRegion::paintReplaced):
     39        (WebCore::RenderRegion::setRenderBoxRegionInfo):
     40        (WebCore::RenderRegion::takeRenderBoxRegionInfo):
     41        (WebCore::RenderRegion::removeRenderBoxRegionInfo):
     42        (WebCore::RenderRegion::renderBoxRegionStyle):
     43        (WebCore::RenderRegion::computeStyleInRegion):
     44        (WebCore::RenderRegion::clearBoxStyleInRegion):
     45        * rendering/RenderRegion.h:
     46        (RenderRegion):
     47        * rendering/RenderView.cpp:
     48        (WebCore::RenderView::RenderView):
     49        * rendering/RenderView.h:
     50        (WebCore):
     51        (RenderView):
     52
    1532012-01-30  Jessie Berlin  <jberlin@apple.com>
    254
  • trunk/Source/WebCore/WebCore.exp.in

    r106271 r106281  
    11931193__ZNK7WebCore12IconDatabase24shouldStopThreadActivityEv
    11941194__ZNK7WebCore12IconDatabase9isEnabledEv
    1195 __ZNK7WebCore12RenderObject13styleInRegionEv
    11961195__ZNK7WebCore12RenderObject14enclosingLayerEv
    11971196__ZNK7WebCore12RenderObject15localToAbsoluteERKNS_10FloatPointEbb
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r105176 r106281  
    743743}
    744744
    745 void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object,
     745void RenderFlowThread::clearRenderBoxCustomStyle(const RenderBox* box,
    746746    const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion,
    747747    const RenderRegion* newStartRegion, const RenderRegion* newEndRegion)
     
    760760
    761761        if (!(insideOldRegionRange && insideNewRegionRange))
    762             region->clearObjectStyleInRegion(object);
     762            region->clearBoxStyleInRegion(box);
    763763
    764764        if (oldEndRegion == region)
     
    799799    }
    800800
    801     clearRenderObjectCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion);
     801    clearRenderBoxCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion);
    802802    range.setRange(startRegion, endRegion);
    803803}
  • trunk/Source/WebCore/rendering/RenderFlowThread.h

    r105176 r106281  
    125125    void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
    126126
    127     void clearRenderObjectCustomStyle(const RenderObject*,
     127    void clearRenderBoxCustomStyle(const RenderBox*,
    128128                                      const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
    129129                                      const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r106247 r106281  
    25912591}
    25922592
    2593 class CurrentRenderRegionMaintainer {
    2594     WTF_MAKE_NONCOPYABLE(CurrentRenderRegionMaintainer);
    2595 public:
    2596     CurrentRenderRegionMaintainer(RenderView* view, RenderRegion* renderRegion)
    2597     : m_view(view)
    2598     , m_renderRegion(view->currentRenderRegion())
    2599     {
    2600         m_view->setCurrentRenderRegion(renderRegion);
    2601     }
    2602     ~CurrentRenderRegionMaintainer()
    2603     {
    2604         m_view->setCurrentRenderRegion(m_renderRegion);
    2605     }
    2606 private:
    2607     RenderView* m_view;
    2608     RenderRegion* m_renderRegion;
    2609 };
    2610 
    26112593void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags)
    26122594{
    2613     CurrentRenderRegionMaintainer renderRegionMaintainer(renderer()->view(), region);
    26142595    OverlapTestRequestMap overlapTestRequests;
    26152596    paintLayer(this, context, damageRect, paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
     
    31133094bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
    31143095{
    3115     CurrentRenderRegionMaintainer renderRegionMaintainer(renderer()->view(), result.region());
    31163096    renderer()->document()->updateLayout();
    31173097   
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r104965 r106281  
    17141714}
    17151715
    1716 RenderStyle* RenderObject::styleInRegion() const
    1717 {
    1718     ASSERT(inRenderFlowThread());
    1719 
    1720     if (!canHaveRegionStyle()
    1721         || !((view() && view()->currentRenderRegion() && view()->currentRenderRegion()->hasCustomRegionStyle())))
    1722         return m_style.get();
    1723 
    1724     RenderStyle* regionStyle = view()->currentRenderRegion()->renderObjectRegionStyle(this);
    1725     if (!regionStyle)
    1726         view()->currentRenderRegion()->computeStyleInRegion(this);
    1727     return view()->currentRenderRegion()->renderObjectRegionStyle(this);
    1728 }
    1729 
    17301716void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
    17311717{
  • trunk/Source/WebCore/rendering/RenderObject.h

    r105532 r106281  
    675675    virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; }
    676676
    677     RenderStyle* style() const;
     677    RenderStyle* style() const { return m_style.get(); }
    678678    RenderStyle* firstLineStyle() const { return document()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
    679679    RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
     
    880880
    881881private:
    882     RenderStyle* styleInRegion() const;
    883882    RenderStyle* firstLineStyleSlowCase() const;
    884883    StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
     
    11091108}
    11101109
    1111 inline RenderStyle* RenderObject::style() const
    1112 {
    1113     return m_style.get();
    1114 }
    1115 
    11161110inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
    11171111{
  • trunk/Source/WebCore/rendering/RenderObjectChildList.cpp

    r104965 r106281  
    118118            oldChild->enclosingRenderFlowThread()->removeRenderBoxRegionInfo(toRenderBox(oldChild));
    119119            if (oldChild->canHaveRegionStyle())
    120                 oldChild->enclosingRenderFlowThread()->clearRenderObjectCustomStyle(oldChild);
     120                oldChild->enclosingRenderFlowThread()->clearRenderBoxCustomStyle(toRenderBox(oldChild));
    121121        }
    122122
  • trunk/Source/WebCore/rendering/RenderRegion.cpp

    r104965 r106281  
    4848    , m_isValid(false)
    4949    , m_hasCustomRegionStyle(false)
     50#ifndef NDEBUG
     51    , m_insideRegionPaint(false)
     52#endif
    5053{
    5154}
     
    9497}
    9598
     99void RenderRegion::setRegionBoxesRegionStyle()
     100{
     101    for (RenderBoxRegionInfoMap::iterator iter = m_renderBoxRegionInfo.begin(), end = m_renderBoxRegionInfo.end(); iter != end; ++iter) {
     102        const RenderBox* box = iter->first;
     103        if (!box->canHaveRegionStyle())
     104            continue;
     105
     106        // Save original box style to be restored later, after paint.
     107        RefPtr<RenderStyle> boxOriginalStyle = box->style();
     108
     109        // Set the style to be used for box as the style computed in region.
     110        (const_cast<RenderBox*>(box))->setStyleInternal(renderBoxRegionStyle(box));
     111
     112        m_renderBoxRegionStyle.set(box, boxOriginalStyle);
     113    }
     114}
     115
     116void RenderRegion::restoreRegionBoxesOriginalStyle()
     117{
     118    for (RenderBoxRegionInfoMap::iterator iter = m_renderBoxRegionInfo.begin(), end = m_renderBoxRegionInfo.end(); iter != end; ++iter) {
     119        const RenderBox* box = iter->first;
     120        RenderBoxRegionStyleMap::iterator it = m_renderBoxRegionStyle.find(box);
     121        if (it == m_renderBoxRegionStyle.end())
     122            continue;
     123
     124        // Restore the box style to the original style and store the box style in region for later use.
     125        RefPtr<RenderStyle> boxRegionStyle = box->style();
     126        (const_cast<RenderBox*>(box))->setStyleInternal(it->second);
     127        m_renderBoxRegionStyle.set(box, boxRegionStyle);
     128    }
     129}
     130
    96131void RenderRegion::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    97132{
     
    99134    if (!m_flowThread || !isValid())
    100135        return;
     136
     137#ifndef NDEBUG
     138    m_insideRegionPaint = true;
     139#endif
     140
     141    setRegionBoxesRegionStyle();
    101142    m_flowThread->paintIntoRegion(paintInfo, this, LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop()));
     143    restoreRegionBoxesOriginalStyle();
     144
     145#ifndef NDEBUG
     146    m_insideRegionPaint = false;
     147#endif
    102148}
    103149
     
    202248        return 0;
    203249
     250#ifndef NDEBUG
     251    ASSERT(!m_insideRegionPaint && "RenderBoxRegionInfo should not be modified inside region paint.");
     252#endif
     253
    204254    OwnPtr<RenderBoxRegionInfo>& boxInfo = m_renderBoxRegionInfo.add(box, nullptr).first->second;
    205255    if (boxInfo)
     
    213263PassOwnPtr<RenderBoxRegionInfo> RenderRegion::takeRenderBoxRegionInfo(const RenderBox* box)
    214264{
     265#ifndef NDEBUG
     266    ASSERT(!m_insideRegionPaint && "RenderBoxRegionInfo should not be modified inside region paint.");
     267#endif
     268
    215269    return m_renderBoxRegionInfo.take(box);
    216270}
     
    218272void RenderRegion::removeRenderBoxRegionInfo(const RenderBox* box)
    219273{
     274#ifndef NDEBUG
     275    ASSERT(!m_insideRegionPaint && "RenderBoxRegionInfo should not be modified inside region paint.");
     276#endif
     277
    220278    m_renderBoxRegionInfo.remove(box);
    221279}
     
    235293}
    236294
    237 RenderStyle* RenderRegion::renderObjectRegionStyle(const RenderObject* renderObject) const
    238 {
    239     RenderObjectRegionStyleMap::const_iterator it = m_renderObjectRegionStyle.find(renderObject);
    240     return (it != m_renderObjectRegionStyle.end()) ? it->second.get() : 0;
    241 }
    242 
    243 void RenderRegion::computeStyleInRegion(const RenderObject* object)
    244 {
    245     ASSERT(object);
    246     ASSERT(object->view());
    247     ASSERT(object->view()->document());
    248     ASSERT(!object->isAnonymous());
    249     ASSERT(object->node() && object->node()->isElementNode());
    250 
    251     Element* element = toElement(object->node());
    252     RefPtr<RenderStyle> renderObjectStyle = object->view()->document()->styleSelector()->styleForElement(element, 0, false, false, this);
    253     m_renderObjectRegionStyle.set(object, renderObjectStyle);
    254 
    255     if (!object->hasBoxDecorations()) {
    256         RenderBox* box = const_cast<RenderBox*>(toRenderBox(object));
    257         RenderStyle* styleInRegion = renderObjectRegionStyle(object);
    258         ASSERT(styleInRegion);
    259 
    260         bool hasBoxDecorations = object->isTableCell() || styleInRegion->hasBackground() || styleInRegion->hasBorder() || styleInRegion->hasAppearance() || styleInRegion->boxShadow();
    261         box->setHasBoxDecorations(hasBoxDecorations);
    262     }
    263 }
    264 
    265 void RenderRegion::clearObjectStyleInRegion(const RenderObject* object)
    266 {
    267     ASSERT(object);
    268     m_renderObjectRegionStyle.remove(object);
     295PassRefPtr<RenderStyle> RenderRegion::renderBoxRegionStyle(const RenderBox* renderBox)
     296{
     297    // The box for which we are asking for style in region should have its info present
     298    // in the region box info map.
     299    ASSERT(m_renderBoxRegionInfo.find(renderBox) != m_renderBoxRegionInfo.end());
     300
     301    RenderBoxRegionStyleMap::iterator it = m_renderBoxRegionStyle.find(renderBox);
     302    if (it != m_renderBoxRegionStyle.end())
     303        return it->second;
     304    return computeStyleInRegion(renderBox);
     305}
     306
     307PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderBox* box)
     308{
     309    ASSERT(box);
     310    ASSERT(box->view());
     311    ASSERT(box->view()->document());
     312    ASSERT(!box->isAnonymous());
     313    ASSERT(box->node() && box->node()->isElementNode());
     314
     315    Element* element = toElement(box->node());
     316    RefPtr<RenderStyle> renderBoxRegionStyle = box->view()->document()->styleSelector()->styleForElement(element, 0, false, false, this);
     317    m_renderBoxRegionStyle.add(box, renderBoxRegionStyle);
     318
     319    if (!box->hasBoxDecorations()) {
     320        bool hasBoxDecorations = box->isTableCell() || renderBoxRegionStyle->hasBackground() || renderBoxRegionStyle->hasBorder() || renderBoxRegionStyle->hasAppearance() || renderBoxRegionStyle->boxShadow();
     321        (const_cast<RenderBox*>(box))->setHasBoxDecorations(hasBoxDecorations);
     322    }
     323
     324    return renderBoxRegionStyle.release();
     325}
     326
     327void RenderRegion::clearBoxStyleInRegion(const RenderBox* box)
     328{
     329    ASSERT(box);
     330    m_renderBoxRegionStyle.remove(box);
    269331}
    270332
  • trunk/Source/WebCore/rendering/RenderRegion.h

    r104965 r106281  
    8181    bool isLastRegion() const;
    8282
    83     RenderStyle* renderObjectRegionStyle(const RenderObject*) const;
    84     void computeStyleInRegion(const RenderObject*);
    85     void clearObjectStyleInRegion(const RenderObject*);
     83    void clearBoxStyleInRegion(const RenderBox*);
    8684private:
    8785    virtual const char* renderName() const { return "RenderRegion"; }
     86
     87    PassRefPtr<RenderStyle> renderBoxRegionStyle(const RenderBox*);
     88    PassRefPtr<RenderStyle> computeStyleInRegion(const RenderBox*);
     89    void setRegionBoxesRegionStyle();
     90    void restoreRegionBoxesOriginalStyle();
    8891
    8992    RenderFlowThread* m_flowThread;
     
    99102    // is unique to the region. For now it just holds logical width information for RenderBlocks, but eventually
    100103    // it will also hold a custom style for any box (for region styling).
    101     HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > m_renderBoxRegionInfo;
     104    typedef HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > RenderBoxRegionInfoMap;
     105    RenderBoxRegionInfoMap m_renderBoxRegionInfo;
    102106
    103     // This map holds information about the region style associated with the render objects that
    104     // are displayed into this region.
    105     typedef HashMap<const RenderObject*, RefPtr<RenderStyle> > RenderObjectRegionStyleMap;
    106     RenderObjectRegionStyleMap m_renderObjectRegionStyle;
     107    typedef HashMap<const RenderBox*, RefPtr<RenderStyle> > RenderBoxRegionStyleMap;
     108    RenderBoxRegionStyleMap m_renderBoxRegionStyle;
    107109
    108110    bool m_isValid;
    109111    bool m_hasCustomRegionStyle;
     112
     113#ifndef NDEBUG
     114    bool m_insideRegionPaint;
     115#endif
    110116};
    111117
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r104965 r106281  
    5959    , m_layoutStateDisableCount(0)
    6060    , m_currentRenderFlowThread(0)
    61     , m_currentRenderRegion(0)
    6261{
    6362    // Clear our anonymous bit, set because RenderObject assumes
  • trunk/Source/WebCore/rendering/RenderView.h

    r105176 r106281  
    3333
    3434class RenderFlowThread;
    35 class RenderRegion;
    3635class RenderWidget;
    3736
     
    188187    RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }
    189188    void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }
    190 
    191     RenderRegion* currentRenderRegion() const { return m_currentRenderRegion; }
    192     void setCurrentRenderRegion(RenderRegion* region) { m_currentRenderRegion = region; }
    193189
    194190    void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
     
    282278    OwnPtr<RenderFlowThreadList> m_renderFlowThreadList;
    283279    RenderFlowThread* m_currentRenderFlowThread;
    284     RenderRegion* m_currentRenderRegion;
    285280    RefPtr<IntervalArena> m_intervalArena;
    286281};
Note: See TracChangeset for help on using the changeset viewer.