Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / compositing / CompositingReasonFinder.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/compositing/CompositingReasonFinder.h"
7
8 #include "core/CSSPropertyNames.h"
9 #include "core/dom/Document.h"
10 #include "core/frame/FrameView.h"
11 #include "core/frame/Settings.h"
12 #include "core/page/Page.h"
13 #include "core/rendering/RenderView.h"
14 #include "core/rendering/compositing/RenderLayerCompositor.h"
15
16 namespace blink {
17
18 CompositingReasonFinder::CompositingReasonFinder(RenderView& renderView)
19     : m_renderView(renderView)
20     , m_compositingTriggers(static_cast<CompositingTriggerFlags>(AllCompositingTriggers))
21 {
22     updateTriggers();
23 }
24
25 void CompositingReasonFinder::updateTriggers()
26 {
27     m_compositingTriggers = 0;
28
29     Settings& settings = m_renderView.document().page()->settings();
30     if (settings.preferCompositingToLCDTextEnabled()) {
31         m_compositingTriggers |= ScrollableInnerFrameTrigger;
32         m_compositingTriggers |= OverflowScrollTrigger;
33         m_compositingTriggers |= ViewportConstrainedPositionedTrigger;
34     }
35 }
36
37 bool CompositingReasonFinder::hasOverflowScrollTrigger() const
38 {
39     return m_compositingTriggers & OverflowScrollTrigger;
40 }
41
42 bool CompositingReasonFinder::isMainFrame() const
43 {
44     // FIXME: LocalFrame::isMainFrame() is probably better.
45     return !m_renderView.document().ownerElement();
46 }
47
48 CompositingReasons CompositingReasonFinder::directReasons(const RenderLayer* layer) const
49 {
50     ASSERT(potentialCompositingReasonsFromStyle(layer->renderer()) == layer->potentialCompositingReasonsFromStyle());
51     CompositingReasons styleDeterminedDirectCompositingReasons = layer->potentialCompositingReasonsFromStyle() & CompositingReasonComboAllDirectStyleDeterminedReasons;
52     return styleDeterminedDirectCompositingReasons | nonStyleDeterminedDirectReasons(layer);
53 }
54
55 // This information doesn't appear to be incorporated into CompositingReasons.
56 bool CompositingReasonFinder::requiresCompositingForScrollableFrame() const
57 {
58     // Need this done first to determine overflow.
59     ASSERT(!m_renderView.needsLayout());
60     if (isMainFrame())
61         return false;
62
63     if (!(m_compositingTriggers & ScrollableInnerFrameTrigger))
64         return false;
65
66     return m_renderView.frameView()->isScrollable();
67 }
68
69 CompositingReasons CompositingReasonFinder::potentialCompositingReasonsFromStyle(RenderObject* renderer) const
70 {
71     CompositingReasons reasons = CompositingReasonNone;
72
73     RenderStyle* style = renderer->style();
74
75     if (requiresCompositingForTransform(renderer))
76         reasons |= CompositingReason3DTransform;
77
78     if (style->backfaceVisibility() == BackfaceVisibilityHidden)
79         reasons |= CompositingReasonBackfaceVisibilityHidden;
80
81     if (requiresCompositingForAnimation(style))
82         reasons |= CompositingReasonActiveAnimation;
83
84     if (style->hasWillChangeCompositingHint() && !style->subtreeWillChangeContents())
85         reasons |= CompositingReasonWillChangeCompositingHint;
86
87     if (style->hasInlineTransform())
88         reasons |= CompositingReasonInlineTransform;
89
90     if (style->transformStyle3D() == TransformStyle3DPreserve3D)
91         reasons |= CompositingReasonPreserve3DWith3DDescendants;
92
93     if (style->hasPerspective())
94         reasons |= CompositingReasonPerspectiveWith3DDescendants;
95
96     // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
97     ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
98
99     if (style->hasMask())
100         reasons |= CompositingReasonMaskWithCompositedDescendants;
101
102     if (style->hasFilter())
103         reasons |= CompositingReasonFilterWithCompositedDescendants;
104
105     // See RenderLayer::updateTransform for an explanation of why we check both.
106     if (renderer->hasTransformRelatedProperty() && style->hasTransform())
107         reasons |= CompositingReasonTransformWithCompositedDescendants;
108
109     if (renderer->isTransparent())
110         reasons |= CompositingReasonOpacityWithCompositedDescendants;
111
112     if (renderer->hasBlendMode())
113         reasons |= CompositingReasonBlendingWithCompositedDescendants;
114
115     if (renderer->hasReflection())
116         reasons |= CompositingReasonReflectionWithCompositedDescendants;
117
118     ASSERT(!(reasons & ~CompositingReasonComboAllStyleDeterminedReasons));
119     return reasons;
120 }
121
122 bool CompositingReasonFinder::requiresCompositingForTransform(RenderObject* renderer) const
123 {
124     // Note that we ask the renderer if it has a transform, because the style may have transforms,
125     // but the renderer may be an inline that doesn't suppport them.
126     return renderer->hasTransformRelatedProperty() && renderer->style()->transform().has3DOperation();
127 }
128
129 CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(const RenderLayer* layer) const
130 {
131     CompositingReasons directReasons = CompositingReasonNone;
132     RenderObject* renderer = layer->renderer();
133
134     if (hasOverflowScrollTrigger()) {
135         if (layer->clipParent())
136             directReasons |= CompositingReasonOutOfFlowClipping;
137
138         if (const RenderLayer* scrollingAncestor = layer->ancestorScrollingLayer()) {
139             if (scrollingAncestor->needsCompositedScrolling() && layer->scrollParent())
140                 directReasons |= CompositingReasonOverflowScrollingParent;
141         }
142
143         if (layer->needsCompositedScrolling())
144             directReasons |= CompositingReasonOverflowScrollingTouch;
145     }
146
147     if (requiresCompositingForPositionFixed(layer))
148         directReasons |= CompositingReasonPositionFixed;
149
150     directReasons |= renderer->additionalCompositingReasons();
151
152     ASSERT(!(directReasons & CompositingReasonComboAllStyleDeterminedReasons));
153     return directReasons;
154 }
155
156 bool CompositingReasonFinder::requiresCompositingForAnimation(RenderStyle* style) const
157 {
158     if (style->subtreeWillChangeContents())
159         return style->isRunningAnimationOnCompositor();
160
161     return style->shouldCompositeForCurrentAnimations();
162 }
163
164 bool CompositingReasonFinder::requiresCompositingForPositionFixed(const RenderLayer* layer) const
165 {
166     if (!(m_compositingTriggers & ViewportConstrainedPositionedTrigger))
167         return false;
168     // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
169     // They will stay fixed wrt the container rather than the enclosing frame.
170     return layer->scrollsWithViewport() && m_renderView.frameView()->isScrollable();
171 }
172
173 }