Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / PaintInvalidationState.cpp
index 12753da..ea23a83 100644 (file)
@@ -9,36 +9,29 @@
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/svg/RenderSVGModelObject.h"
+#include "core/rendering/svg/RenderSVGRoot.h"
 #include "platform/Partitions.h"
 
 namespace blink {
 
-PaintInvalidationState::PaintInvalidationState(RenderObject& renderer)
+PaintInvalidationState::PaintInvalidationState(const RenderView& renderView)
     : m_clipped(false)
     , m_cachedOffsetsEnabled(true)
     , m_forceCheckForPaintInvalidation(false)
-    , m_paintInvalidationContainer(*renderer.containerForPaintInvalidation())
-    , m_renderer(renderer)
+    , m_paintInvalidationContainer(*renderView.containerForPaintInvalidation())
 {
-    bool establishesPaintInvalidationContainer = &m_renderer == &m_paintInvalidationContainer;
+    bool establishesPaintInvalidationContainer = renderView == m_paintInvalidationContainer;
     if (!establishesPaintInvalidationContainer) {
-        if (!renderer.supportsPaintInvalidationStateCachedOffsets()) {
+        if (!renderView.supportsPaintInvalidationStateCachedOffsets()) {
             m_cachedOffsetsEnabled = false;
             return;
         }
-        bool invalidationContainerSkipped;
-        RenderObject* container = renderer.container(&m_paintInvalidationContainer, &invalidationContainerSkipped);
-        if (container && !invalidationContainerSkipped) {
-            FloatPoint point = container->localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer);
-            if (container->isTableRow())
-                point = FloatPoint(point.x() - toRenderBox(container)->x().toFloat(), point.y() - toRenderBox(container)->y().toFloat());
-            m_paintOffset = LayoutSize(point.x(), point.y());
-
-            applyClipIfNeeded(*container);
-        }
-    } else {
-        applyClipIfNeeded(m_renderer);
+        FloatPoint point = renderView.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
+        m_paintOffset = LayoutSize(point.x(), point.y());
     }
+    m_clipRect = renderView.viewRect();
+    m_clipRect.move(m_paintOffset);
+    m_clipped = true;
 }
 
 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, RenderLayerModelObject& renderer, const RenderLayerModelObject& paintInvalidationContainer)
@@ -46,11 +39,10 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& nex
     , m_cachedOffsetsEnabled(true)
     , m_forceCheckForPaintInvalidation(next.m_forceCheckForPaintInvalidation)
     , m_paintInvalidationContainer(paintInvalidationContainer)
-    , m_renderer(renderer)
 {
     // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054
-    bool establishesPaintInvalidationContainer = &m_renderer == &m_paintInvalidationContainer;
-    bool fixed = m_renderer.isOutOfFlowPositioned() && m_renderer.style()->position() == FixedPosition;
+    bool establishesPaintInvalidationContainer = renderer == m_paintInvalidationContainer;
+    bool fixed = renderer.style()->position() == FixedPosition;
 
     if (establishesPaintInvalidationContainer) {
         // When we hit a new paint invalidation container, we don't need to
@@ -61,23 +53,22 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& nex
         if (!renderer.supportsPaintInvalidationStateCachedOffsets() || !next.m_cachedOffsetsEnabled) {
             m_cachedOffsetsEnabled = false;
         } else {
-            LayoutSize offset = m_renderer.isBox() && !m_renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize();
             if (fixed) {
-                // FIXME: This doesn't work correctly with transforms.
-                FloatPoint fixedOffset = m_renderer.view()->localToAbsolute(FloatPoint(), IsFixed);
-                m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
+                FloatPoint fixedOffset = renderer.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
+                m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
             } else {
+                LayoutSize offset = renderer.isBox() && !renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize();
                 m_paintOffset = next.m_paintOffset + offset;
             }
 
-            if (m_renderer.isOutOfFlowPositioned() && !fixed) {
-                if (RenderObject* container = m_renderer.container()) {
+            if (renderer.isOutOfFlowPositioned() && !fixed) {
+                if (RenderObject* container = renderer.container()) {
                     if (container->style()->hasInFlowPosition() && container->isRenderInline())
                         m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(toRenderBox(renderer));
                 }
             }
 
-            if (m_renderer.style()->hasInFlowPosition() && renderer.hasLayer())
+            if (renderer.style()->hasInFlowPosition() && renderer.hasLayer())
                 m_paintOffset += renderer.layer()->offsetForInFlowPosition();
         }
 
@@ -86,24 +77,57 @@ PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& nex
             m_clipRect = next.m_clipRect;
     }
 
+    if (m_cachedOffsetsEnabled && renderer.isSVGRoot()) {
+        const RenderSVGRoot& svgRoot = toRenderSVGRoot(renderer);
+        m_svgTransform = adoptPtr(new AffineTransform(svgRoot.localToBorderBoxTransform()));
+        if (svgRoot.shouldApplyViewportClip())
+            addClipRectRelativeToPaintOffset(svgRoot.pixelSnappedSize());
+    }
+
     applyClipIfNeeded(renderer);
 
     // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
 }
 
-void PaintInvalidationState::applyClipIfNeeded(const RenderObject& renderer)
+PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, const RenderSVGModelObject& renderer)
+    : m_clipped(next.m_clipped)
+    , m_cachedOffsetsEnabled(next.m_cachedOffsetsEnabled)
+    , m_forceCheckForPaintInvalidation(next.m_forceCheckForPaintInvalidation)
+    , m_clipRect(next.m_clipRect)
+    , m_paintOffset(next.m_paintOffset)
+    , m_paintInvalidationContainer(next.m_paintInvalidationContainer)
 {
-    if (!renderer.hasOverflowClip())
-        return;
+    ASSERT(renderer != m_paintInvalidationContainer);
 
-    const RenderBox& box = toRenderBox(renderer);
-    LayoutRect clipRect(toPoint(m_paintOffset), box.layer()->size());
+    if (m_cachedOffsetsEnabled)
+        m_svgTransform = adoptPtr(new AffineTransform(next.svgTransform() * renderer.localToParentTransform()));
+}
+
+void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutSize& clipSize)
+{
+    LayoutRect clipRect(toPoint(m_paintOffset), clipSize);
     if (m_clipped) {
         m_clipRect.intersect(clipRect);
     } else {
         m_clipRect = clipRect;
         m_clipped = true;
     }
+}
+
+void PaintInvalidationState::applyClipIfNeeded(const RenderObject& renderer)
+{
+    if (!renderer.hasOverflowClip())
+        return;
+
+    const RenderBox& box = toRenderBox(renderer);
+
+    // Do not clip scroll layer contents because the compositor expects the whole layer
+    // to be always invalidated in-time.
+    if (box.usesCompositedScrolling())
+        ASSERT(!m_clipped); // The box should establish paint invalidation container, so no m_clipped inherited.
+    else
+        addClipRectRelativeToPaintOffset(box.layer()->size());
+
     m_paintOffset -= box.scrolledContentOffset();
 }