Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/rendering/compositing/CompositingReasonFinder.h" | 6 #include "core/rendering/compositing/CompositingReasonFinder.h" |
| 7 | 7 |
| 8 #include "core/CSSPropertyNames.h" | 8 #include "core/CSSPropertyNames.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 | 144 |
| 145 if (const RenderLayer* scrollingAncestor = layer->ancestorScrollingLayer ()) { | 145 if (const RenderLayer* scrollingAncestor = layer->ancestorScrollingLayer ()) { |
| 146 if (scrollingAncestor->needsCompositedScrolling() && layer->scrollPa rent()) | 146 if (scrollingAncestor->needsCompositedScrolling() && layer->scrollPa rent()) |
| 147 directReasons |= CompositingReasonOverflowScrollingParent; | 147 directReasons |= CompositingReasonOverflowScrollingParent; |
| 148 } | 148 } |
| 149 | 149 |
| 150 if (layer->needsCompositedScrolling()) | 150 if (layer->needsCompositedScrolling()) |
| 151 directReasons |= CompositingReasonOverflowScrollingTouch; | 151 directReasons |= CompositingReasonOverflowScrollingTouch; |
| 152 } | 152 } |
| 153 | 153 |
| 154 if (requiresCompositingForPositionFixed(renderer, layer, 0)) | 154 if (requiresCompositingForPositionFixed(renderer)) |
| 155 directReasons |= CompositingReasonPositionFixed; | 155 directReasons |= CompositingReasonPositionFixed; |
| 156 | 156 |
| 157 directReasons |= renderer->additionalCompositingReasons(m_compositingTrigger s); | 157 directReasons |= renderer->additionalCompositingReasons(m_compositingTrigger s); |
| 158 | 158 |
| 159 ASSERT(!(directReasons & CompositingReasonComboAllStyleDeterminedReasons)); | 159 ASSERT(!(directReasons & CompositingReasonComboAllStyleDeterminedReasons)); |
| 160 return directReasons; | 160 return directReasons; |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool CompositingReasonFinder::requiresCompositingForAnimation(RenderStyle* style ) const | 163 bool CompositingReasonFinder::requiresCompositingForAnimation(RenderStyle* style ) const |
| 164 { | 164 { |
| 165 if (style->subtreeWillChangeContents()) | 165 if (style->subtreeWillChangeContents()) |
| 166 return style->isRunningAnimationOnCompositor(); | 166 return style->isRunningAnimationOnCompositor(); |
| 167 | 167 |
| 168 return style->shouldCompositeForCurrentAnimations(); | 168 return style->shouldCompositeForCurrentAnimations(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 bool CompositingReasonFinder::requiresCompositingForPositionFixed(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotComposite dReason* viewportConstrainedNotCompositedReason) const | 171 bool CompositingReasonFinder::requiresCompositingForPositionFixed(RenderObject* renderer) const |
| 172 { | 172 { |
| 173 if (!(m_compositingTriggers & ViewportConstrainedPositionedTrigger)) | 173 if (!(m_compositingTriggers & ViewportConstrainedPositionedTrigger)) |
| 174 return false; | 174 return false; |
| 175 | |
| 176 if (renderer->style()->position() != FixedPosition) | |
| 177 return false; | |
| 178 | |
| 179 RenderObject* container = renderer->container(); | |
| 180 // If the renderer is not hooked up yet then we have to wait until it is. | |
| 181 if (!container) { | |
| 182 ASSERT(m_renderView.document().lifecycle().state() < DocumentLifecycle:: InCompositingUpdate); | |
| 183 // FIXME: Remove this and ASSERT(container) once we get rid of the incre mental | |
| 184 // allocateOrClearCompositedLayerMapping compositing update. This happen s when | |
| 185 // adding the renderer to the tree because we setStyle before addChild i n | |
| 186 // createRendererForElementIfNeeded. | |
| 187 return false; | |
| 188 } | |
| 189 | |
| 190 // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements. | 175 // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements. |
| 191 // They will stay fixed wrt the container rather than the enclosing frame. | 176 // They will stay fixed wrt the container rather than the enclosing frame. |
| 192 if (container != &m_renderView) { | 177 return renderer->style()->position() == FixedPosition |
| 193 if (viewportConstrainedNotCompositedReason) | 178 && renderer->container() == &m_renderView |
| 194 *viewportConstrainedNotCompositedReason = RenderLayer::NotComposited ForNonViewContainer; | 179 && m_renderView.frameView()->isScrollable(); |
|
Ian Vollick
2014/08/07 18:18:16
Gorgeous.
| |
| 195 return false; | |
| 196 } | |
| 197 | |
| 198 // If the fixed-position element does not have any scrollable ancestor betwe en it and | |
| 199 // its container, then we do not need to spend compositor resources for it. Start by | |
| 200 // assuming we can opt-out (i.e. no scrollable ancestor), and refine the ans wer below. | |
| 201 bool hasScrollableAncestor = false; | |
| 202 | |
| 203 // The FrameView has the scrollbars associated with the top level viewport, so we have to | |
| 204 // check the FrameView in addition to the hierarchy of ancestors. | |
| 205 FrameView* frameView = m_renderView.frameView(); | |
| 206 if (frameView && frameView->isScrollable()) | |
| 207 hasScrollableAncestor = true; | |
| 208 | |
| 209 RenderLayer* ancestor = layer->parent(); | |
| 210 while (ancestor && !hasScrollableAncestor) { | |
| 211 if (ancestor->scrollsOverflow()) | |
| 212 hasScrollableAncestor = true; | |
| 213 if (ancestor->renderer() == &m_renderView) | |
| 214 break; | |
| 215 ancestor = ancestor->parent(); | |
| 216 } | |
| 217 | |
| 218 if (!hasScrollableAncestor) { | |
| 219 if (viewportConstrainedNotCompositedReason) | |
| 220 *viewportConstrainedNotCompositedReason = RenderLayer::NotComposited ForUnscrollableAncestors; | |
| 221 return false; | |
| 222 } | |
| 223 | |
| 224 // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done. | |
| 225 // FIXME: Get rid of this codepath once we get rid of the incremental compos iting update in RenderLayer::styleChanged. | |
| 226 if (m_renderView.document().lifecycle().state() < DocumentLifecycle::LayoutC lean) | |
| 227 return layer->hasCompositedLayerMapping(); | |
| 228 | |
| 229 bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescend ant(); | |
| 230 if (!paintsContent) { | |
| 231 if (viewportConstrainedNotCompositedReason) | |
| 232 *viewportConstrainedNotCompositedReason = RenderLayer::NotComposited ForNoVisibleContent; | |
| 233 return false; | |
| 234 } | |
| 235 | |
| 236 // Fixed position elements that are invisible in the current view don't get their own layer. | |
| 237 if (FrameView* frameView = m_renderView.frameView()) { | |
| 238 ASSERT(m_renderView.document().lifecycle().state() == DocumentLifecycle: :InCompositingUpdate); | |
| 239 LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect (); | |
| 240 LayoutRect layerBounds = layer->boundingBoxForCompositing(layer->composi tor()->rootRenderLayer(), RenderLayer::ApplyBoundsChickenEggHacks); | |
| 241 if (!viewBounds.intersects(enclosingIntRect(layerBounds))) { | |
| 242 if (viewportConstrainedNotCompositedReason) | |
| 243 *viewportConstrainedNotCompositedReason = RenderLayer::NotCompos itedForBoundsOutOfView; | |
| 244 return false; | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 return true; | |
| 249 } | 180 } |
| 250 | 181 |
| 251 } | 182 } |
| OLD | NEW |