Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / PaintInvalidationState.cpp
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/rendering/PaintInvalidationState.h"
7
8 #include "core/rendering/RenderInline.h"
9 #include "core/rendering/RenderLayer.h"
10 #include "core/rendering/RenderView.h"
11 #include "core/rendering/svg/RenderSVGModelObject.h"
12 #include "core/rendering/svg/RenderSVGRoot.h"
13 #include "platform/Partitions.h"
14
15 namespace blink {
16
17 PaintInvalidationState::PaintInvalidationState(const RenderView& renderView)
18     : m_clipped(false)
19     , m_cachedOffsetsEnabled(true)
20     , m_forceCheckForPaintInvalidation(false)
21     , m_paintInvalidationContainer(*renderView.containerForPaintInvalidation())
22 {
23     bool establishesPaintInvalidationContainer = renderView == m_paintInvalidationContainer;
24     if (!establishesPaintInvalidationContainer) {
25         if (!renderView.supportsPaintInvalidationStateCachedOffsets()) {
26             m_cachedOffsetsEnabled = false;
27             return;
28         }
29         FloatPoint point = renderView.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
30         m_paintOffset = LayoutSize(point.x(), point.y());
31     }
32     m_clipRect = renderView.viewRect();
33     m_clipRect.move(m_paintOffset);
34     m_clipped = true;
35 }
36
37 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, RenderLayerModelObject& renderer, const RenderLayerModelObject& paintInvalidationContainer)
38     : m_clipped(false)
39     , m_cachedOffsetsEnabled(true)
40     , m_forceCheckForPaintInvalidation(next.m_forceCheckForPaintInvalidation)
41     , m_paintInvalidationContainer(paintInvalidationContainer)
42 {
43     // FIXME: SVG could probably benefit from a stack-based optimization like html does. crbug.com/391054
44     bool establishesPaintInvalidationContainer = renderer == m_paintInvalidationContainer;
45     bool fixed = renderer.style()->position() == FixedPosition;
46
47     if (establishesPaintInvalidationContainer) {
48         // When we hit a new paint invalidation container, we don't need to
49         // continue forcing a check for paint invalidation because movement
50         // from our parents will just move the whole invalidation container.
51         m_forceCheckForPaintInvalidation = false;
52     } else {
53         if (!renderer.supportsPaintInvalidationStateCachedOffsets() || !next.m_cachedOffsetsEnabled) {
54             m_cachedOffsetsEnabled = false;
55         } else {
56             if (fixed) {
57                 FloatPoint fixedOffset = renderer.localToContainerPoint(FloatPoint(), &m_paintInvalidationContainer, TraverseDocumentBoundaries);
58                 m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
59             } else {
60                 LayoutSize offset = renderer.isBox() && !renderer.isTableRow() ? toRenderBox(renderer).locationOffset() : LayoutSize();
61                 m_paintOffset = next.m_paintOffset + offset;
62             }
63
64             if (renderer.isOutOfFlowPositioned() && !fixed) {
65                 if (RenderObject* container = renderer.container()) {
66                     if (container->style()->hasInFlowPosition() && container->isRenderInline())
67                         m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(toRenderBox(renderer));
68                 }
69             }
70
71             if (renderer.style()->hasInFlowPosition() && renderer.hasLayer())
72                 m_paintOffset += renderer.layer()->offsetForInFlowPosition();
73         }
74
75         m_clipped = !fixed && next.m_clipped;
76         if (m_clipped)
77             m_clipRect = next.m_clipRect;
78     }
79
80     if (m_cachedOffsetsEnabled && renderer.isSVGRoot()) {
81         const RenderSVGRoot& svgRoot = toRenderSVGRoot(renderer);
82         m_svgTransform = adoptPtr(new AffineTransform(svgRoot.localToBorderBoxTransform()));
83         if (svgRoot.shouldApplyViewportClip())
84             addClipRectRelativeToPaintOffset(svgRoot.pixelSnappedSize());
85     }
86
87     applyClipIfNeeded(renderer);
88
89     // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
90 }
91
92 PaintInvalidationState::PaintInvalidationState(const PaintInvalidationState& next, const RenderSVGModelObject& renderer)
93     : m_clipped(next.m_clipped)
94     , m_cachedOffsetsEnabled(next.m_cachedOffsetsEnabled)
95     , m_forceCheckForPaintInvalidation(next.m_forceCheckForPaintInvalidation)
96     , m_clipRect(next.m_clipRect)
97     , m_paintOffset(next.m_paintOffset)
98     , m_paintInvalidationContainer(next.m_paintInvalidationContainer)
99 {
100     ASSERT(renderer != m_paintInvalidationContainer);
101
102     if (m_cachedOffsetsEnabled)
103         m_svgTransform = adoptPtr(new AffineTransform(next.svgTransform() * renderer.localToParentTransform()));
104 }
105
106 void PaintInvalidationState::addClipRectRelativeToPaintOffset(const LayoutSize& clipSize)
107 {
108     LayoutRect clipRect(toPoint(m_paintOffset), clipSize);
109     if (m_clipped) {
110         m_clipRect.intersect(clipRect);
111     } else {
112         m_clipRect = clipRect;
113         m_clipped = true;
114     }
115 }
116
117 void PaintInvalidationState::applyClipIfNeeded(const RenderObject& renderer)
118 {
119     if (!renderer.hasOverflowClip())
120         return;
121
122     const RenderBox& box = toRenderBox(renderer);
123
124     // Do not clip scroll layer contents because the compositor expects the whole layer
125     // to be always invalidated in-time.
126     if (box.usesCompositedScrolling())
127         ASSERT(!m_clipped); // The box should establish paint invalidation container, so no m_clipped inherited.
128     else
129         addClipRectRelativeToPaintOffset(box.layer()->size());
130
131     m_paintOffset -= box.scrolledContentOffset();
132 }
133
134 } // namespace blink