| Index: Source/core/rendering/RenderObject.cpp
 | 
| diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
 | 
| index d79cd3f75902c5e8c1d3aae705e877adb5771435..760ebba3932af3d2fed99960e9d3b6757a493ccd 100644
 | 
| --- a/Source/core/rendering/RenderObject.cpp
 | 
| +++ b/Source/core/rendering/RenderObject.cpp
 | 
| @@ -1840,62 +1840,62 @@ void RenderObject::handleDynamicFloatPositionChange()
 | 
|      }
 | 
|  }
 | 
|  
 | 
| -StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
 | 
| +StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff) const
 | 
|  {
 | 
|      // If transform changed, and the layer does not paint into its own separate backing, then we need to do a layout.
 | 
|      // FIXME: The comment above is what the code does, but it is technically not following spec. This means we will
 | 
|      // not to layout for 3d transforms, but we should be invoking a simplified relayout. Is it possible we are avoiding
 | 
|      // doing this for some performance reason at this time?
 | 
| -    if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
 | 
| +    if (diff.transformChanged()) {
 | 
|          // Text nodes share style with their parents but transforms don't apply to them,
 | 
|          // hence the !isText() check.
 | 
|          // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
 | 
|          if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->hasDirectReasonsForCompositing())) {
 | 
| -            // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set
 | 
| -            // then we actually need SimplifiedLayoutAndPositionedMovement.
 | 
| +            diff.setNeedsRepaintLayer();
 | 
|              if (!hasLayer())
 | 
| -                diff = StyleDifferenceLayout; // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
 | 
| -            else if (diff < StyleDifferenceLayoutPositionedMovementOnly)
 | 
| -                diff = StyleDifferenceSimplifiedLayout;
 | 
| -            else if (diff < StyleDifferenceSimplifiedLayout)
 | 
| -                diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement;
 | 
| -        } else if (diff < StyleDifferenceRecompositeLayer)
 | 
| -            diff = StyleDifferenceRecompositeLayer;
 | 
| +                diff.setNeedsFullLayout(); // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
 | 
| +            else
 | 
| +                diff.setNeedsSimplifiedLayout();
 | 
| +        } else {
 | 
| +            diff.setNeedsRecompositeLayer();
 | 
| +        }
 | 
|      }
 | 
|  
 | 
| -    // If opacity or filters changed, and the layer does not paint into its own separate backing, then we need to repaint (also
 | 
| +    // If opacity or zIndex changed, and the layer does not paint into its own separate backing, then we need to repaint (also
 | 
|      // ignoring text nodes)
 | 
| -    if (contextSensitiveProperties & ContextSensitivePropertyOpacity && diff <= StyleDifferenceRepaintLayer) {
 | 
| +    if ((diff.opacityChanged() || diff.zIndexChanged()) && !diff.needsRepaintLayer()) {
 | 
|          if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->hasDirectReasonsForCompositing()))
 | 
| -            diff = StyleDifferenceRepaintLayer;
 | 
| -        else if (diff < StyleDifferenceRecompositeLayer)
 | 
| -            diff = StyleDifferenceRecompositeLayer;
 | 
| +            diff.setNeedsRepaintLayer();
 | 
| +        else
 | 
| +            diff.setNeedsRecompositeLayer();
 | 
|      }
 | 
|  
 | 
| -    if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer() && diff <= StyleDifferenceRepaintLayer) {
 | 
| +    // If filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to repaint.
 | 
| +    if (diff.filterChanged() && hasLayer() && !diff.needsRepaintLayer()) {
 | 
|          RenderLayer* layer = toRenderLayerModelObject(this)->layer();
 | 
|          if (!layer->hasDirectReasonsForCompositing() || layer->paintsWithFilters())
 | 
| -            diff = StyleDifferenceRepaintLayer;
 | 
| -        else if (diff < StyleDifferenceRecompositeLayer)
 | 
| -            diff = StyleDifferenceRecompositeLayer;
 | 
| +            diff.setNeedsRepaintLayer();
 | 
| +        else
 | 
| +            diff.setNeedsRecompositeLayer();
 | 
|      }
 | 
|  
 | 
| -    if ((contextSensitiveProperties & ContextSensitivePropertyTextOrColor) && diff < StyleDifferenceRepaint
 | 
| -        && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
 | 
| -        diff = StyleDifferenceRepaint;
 | 
| +    if (!diff.needsRepaint() && diff.textOrColorChanged() && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
 | 
| +        diff.setNeedsRepaintSelf();
 | 
| +
 | 
| +    diff.resetContextSensitiveFlags();
 | 
|  
 | 
|      // The answer to layerTypeRequired() for plugins, iframes, and canvas can change without the actual
 | 
|      // style changing, since it depends on whether we decide to composite these elements. When the
 | 
|      // layer status of one of these elements changes, we need to force a layout.
 | 
| -    if (diff == StyleDifferenceEqual && style() && isLayerModelObject()) {
 | 
| +    if (!diff.needsFullLayout() && style() && isLayerModelObject()) {
 | 
|          bool requiresLayer = toRenderLayerModelObject(this)->layerTypeRequired() != NoLayer;
 | 
|          if (hasLayer() != requiresLayer)
 | 
| -            diff = StyleDifferenceLayout;
 | 
| +            diff.setNeedsFullLayout();
 | 
|      }
 | 
|  
 | 
|      // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
 | 
| -    if (diff == StyleDifferenceRepaintLayer && !hasLayer())
 | 
| -        diff = StyleDifferenceRepaint;
 | 
| +    if (diff.needsRepaintLayer() && !hasLayer())
 | 
| +        diff.setNeedsRepaintSelf();
 | 
|  
 | 
|      return diff;
 | 
|  }
 | 
| @@ -1947,12 +1947,11 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
 | 
|          return;
 | 
|      }
 | 
|  
 | 
| -    StyleDifference diff = StyleDifferenceEqual;
 | 
| -    unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
 | 
| +    StyleDifference diff;
 | 
|      if (m_style)
 | 
| -        diff = m_style->visualInvalidationDiff(*style, contextSensitiveProperties);
 | 
| +        diff = m_style->visualInvalidationDiff(*style);
 | 
|  
 | 
| -    diff = adjustStyleDifference(diff, contextSensitiveProperties);
 | 
| +    diff = adjustStyleDifference(diff);
 | 
|  
 | 
|      styleWillChange(diff, *style);
 | 
|  
 | 
| @@ -1980,21 +1979,22 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
 | 
|  
 | 
|      // Now that the layer (if any) has been updated, we need to adjust the diff again,
 | 
|      // check whether we should layout now, and decide if we need to repaint.
 | 
| -    StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
 | 
| +    StyleDifference updatedDiff = adjustStyleDifference(diff);
 | 
|  
 | 
| -    if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
 | 
| -        if (updatedDiff == StyleDifferenceLayout)
 | 
| +    if (updatedDiff.needsFullLayout()) {
 | 
| +        if (!diff.needsFullLayout())
 | 
|              setNeedsLayoutAndPrefWidthsRecalc();
 | 
| -        else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
 | 
| -            setNeedsPositionedMovementLayout();
 | 
| -        else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
 | 
| -            setNeedsPositionedMovementLayout();
 | 
| -            setNeedsSimplifiedNormalFlowLayout();
 | 
| -        } else if (updatedDiff == StyleDifferenceSimplifiedLayout)
 | 
| +    } else {
 | 
| +        if (updatedDiff.needsSimplifiedLayout() && !diff.needsSimplifiedLayout())
 | 
|              setNeedsSimplifiedNormalFlowLayout();
 | 
| +        if (updatedDiff.needsPositionedMovementLayout() && !diff.needsPositionedMovementLayout())
 | 
| +            setNeedsPositionedMovementLayout();
 | 
|      }
 | 
|  
 | 
| -    if (updatedDiff == StyleDifferenceRepaint || updatedDiff == StyleDifferenceRepaintLayer) {
 | 
| +    // FIXME: For now if needsFullLayout() or needsSimplifiedLayout(), repaint is handled during layout(),
 | 
| +    // so don't repaint here to avoid duplicate repaints.
 | 
| +    // Need to optimize repaint during layout() to reduce unnecessary repaints and duplicate code.
 | 
| +    if (updatedDiff.needsRepaintSelf() && !updatedDiff.needsFullLayout() && !updatedDiff.needsSimplifiedLayout()) {
 | 
|          // Do a repaint with the new style now, e.g., for example if we go from
 | 
|          // not having an outline to having an outline.
 | 
|          repaint();
 | 
| @@ -2028,14 +2028,18 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle& newS
 | 
|                      layer->setHasVisibleContent();
 | 
|                  } else if (layer->hasVisibleContent() && (this == layer->renderer() || layer->renderer()->style()->visibility() != VISIBLE)) {
 | 
|                      layer->dirtyVisibleContentStatus();
 | 
| -                    if (diff > StyleDifferenceRepaintLayer)
 | 
| +                    if (diff.needsLayout())
 | 
|                          repaint();
 | 
|                  }
 | 
|              }
 | 
|          }
 | 
|  
 | 
| -        if (m_parent && diff == StyleDifferenceRepaint)
 | 
| +        // FIXME: For now if needsFullLayout() or needsSimplifiedLayout(), repaint is handled during layout(),
 | 
| +        // so don't repaint here to avoid duplicate repaints.
 | 
| +        // Need to optimize repaint during layout() to reduce unnecessary repaints and duplicate code.
 | 
| +        if (m_parent && diff.needsRepaintSelf() && !diff.needsFullLayout() && !diff.needsSimplifiedLayout())
 | 
|              repaint();
 | 
| +
 | 
|          if (isFloating() && (m_style->floating() != newStyle.floating()))
 | 
|              // For changes in float styles, we need to conceivably remove ourselves
 | 
|              // from the floating objects list.
 | 
| @@ -2051,12 +2055,13 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle& newS
 | 
|  
 | 
|          // Clearing these bits is required to avoid leaving stale renderers.
 | 
|          // FIXME: We shouldn't need that hack if our logic was totally correct.
 | 
| -        if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
 | 
| +        if (diff.needsLayout()) {
 | 
|              setFloating(false);
 | 
|              clearPositionedState();
 | 
|          }
 | 
| -    } else
 | 
| +    } else {
 | 
|          s_affectsParentBlock = false;
 | 
| +    }
 | 
|  
 | 
|      if (view()->frameView()) {
 | 
|          bool shouldBlitOnFixedBackgroundImage = false;
 | 
| @@ -2124,7 +2129,7 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
 | 
|      if (!m_parent)
 | 
|          return;
 | 
|  
 | 
| -    if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
 | 
| +    if (diff.needsFullLayout() || diff.needsSimplifiedLayout()) {
 | 
|          RenderCounter::rendererStyleChanged(*this, oldStyle, m_style.get());
 | 
|  
 | 
|          // If the object already needs layout, then setNeedsLayout won't do
 | 
| @@ -2135,14 +2140,12 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
 | 
|          if (needsLayout() && oldStyle->position() != m_style->position())
 | 
|              markContainingBlocksForLayout();
 | 
|  
 | 
| -        if (diff == StyleDifferenceLayout)
 | 
| +        if (diff.needsFullLayout())
 | 
|              setNeedsLayoutAndPrefWidthsRecalc();
 | 
|          else
 | 
|              setNeedsSimplifiedNormalFlowLayout();
 | 
| -    } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
 | 
| -        setNeedsPositionedMovementLayout();
 | 
| -        setNeedsSimplifiedNormalFlowLayout();
 | 
| -    } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
 | 
| +    }
 | 
| +    if (diff.needsPositionedMovementLayout())
 | 
|          setNeedsPositionedMovementLayout();
 | 
|  
 | 
|      // Don't check for repaint here; we need to wait until the layer has been
 | 
| 
 |