2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@web.de>
10 * Randall Jesup <rjesup@wgate.com>
11 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12 * Josh Soref <timeless@mac.com>
13 * Boris Zbarsky <bzbarsky@mit.edu>
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 * Alternatively, the contents of this file may be used under the terms
30 * of either the Mozilla Public License Version 1.1, found at
31 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33 * (the "GPL"), in which case the provisions of the MPL or the GPL are
34 * applicable instead of those above. If you wish to allow use of your
35 * version of this file only under the terms of one of those two
36 * licenses (the MPL or the GPL) and not to allow others to use your
37 * version of this file under the LGPL, indicate your decision by
38 * deletingthe provisions above and replace them with the notice and
39 * other provisions required by the MPL or the GPL, as the case may be.
40 * If you do not delete the provisions above, a recipient may use your
41 * version of this file under any of the LGPL, the MPL or the GPL.
45 #include "core/rendering/RenderLayer.h"
47 #include "core/CSSPropertyNames.h"
48 #include "core/HTMLNames.h"
49 #include "core/css/PseudoStyleRequest.h"
50 #include "core/dom/Document.h"
51 #include "core/dom/shadow/ShadowRoot.h"
52 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
53 #include "core/frame/FrameView.h"
54 #include "core/frame/LocalFrame.h"
55 #include "core/html/HTMLFrameElement.h"
56 #include "core/page/Page.h"
57 #include "core/page/scrolling/ScrollingCoordinator.h"
58 #include "core/rendering/ColumnInfo.h"
59 #include "core/rendering/FilterEffectRenderer.h"
60 #include "core/rendering/HitTestRequest.h"
61 #include "core/rendering/HitTestResult.h"
62 #include "core/rendering/HitTestingTransformState.h"
63 #include "core/rendering/RenderFlowThread.h"
64 #include "core/rendering/RenderGeometryMap.h"
65 #include "core/rendering/RenderInline.h"
66 #include "core/rendering/RenderPart.h"
67 #include "core/rendering/RenderReplica.h"
68 #include "core/rendering/RenderScrollbar.h"
69 #include "core/rendering/RenderScrollbarPart.h"
70 #include "core/rendering/RenderTreeAsText.h"
71 #include "core/rendering/RenderView.h"
72 #include "core/rendering/compositing/CompositedLayerMapping.h"
73 #include "core/rendering/compositing/RenderLayerCompositor.h"
74 #include "core/rendering/svg/ReferenceFilterBuilder.h"
75 #include "platform/LengthFunctions.h"
76 #include "platform/Partitions.h"
77 #include "platform/RuntimeEnabledFeatures.h"
78 #include "platform/TraceEvent.h"
79 #include "platform/geometry/FloatPoint3D.h"
80 #include "platform/geometry/FloatRect.h"
81 #include "platform/geometry/TransformState.h"
82 #include "platform/graphics/filters/ReferenceFilter.h"
83 #include "platform/graphics/filters/SourceGraphic.h"
84 #include "platform/transforms/ScaleTransformOperation.h"
85 #include "platform/transforms/TransformationMatrix.h"
86 #include "platform/transforms/TranslateTransformOperation.h"
87 #include "public/platform/Platform.h"
88 #include "wtf/StdLibExtras.h"
89 #include "wtf/text/CString.h"
95 static CompositingQueryMode gCompositingQueryMode =
96 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
100 using namespace HTMLNames;
102 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
104 , m_hasSelfPaintingLayerDescendant(false)
105 , m_hasSelfPaintingLayerDescendantDirty(false)
106 , m_isRootLayer(renderer->isRenderView())
107 , m_usedTransparency(false)
108 , m_visibleContentStatusDirty(true)
109 , m_hasVisibleContent(false)
110 , m_visibleDescendantStatusDirty(false)
111 , m_hasVisibleDescendant(false)
112 , m_hasVisibleNonLayerContent(false)
113 , m_isPaginated(false)
114 , m_3DTransformedDescendantStatusDirty(true)
115 , m_has3DTransformedDescendant(false)
116 , m_containsDirtyOverlayScrollbars(false)
117 , m_hasFilterInfo(false)
118 , m_needsAncestorDependentCompositingInputsUpdate(true)
119 , m_needsDescendantDependentCompositingInputsUpdate(true)
120 , m_childNeedsCompositingInputsUpdate(true)
121 , m_hasCompositingDescendant(false)
122 , m_hasNonCompositedChild(false)
123 , m_shouldIsolateCompositedDescendants(false)
124 , m_lostGroupedMapping(false)
125 , m_renderer(renderer)
131 , m_staticInlinePosition(0)
132 , m_staticBlockPosition(0)
133 , m_enclosingPaginationLayer(0)
134 , m_potentialCompositingReasonsFromStyle(CompositingReasonNone)
135 , m_compositingReasons(CompositingReasonNone)
136 , m_groupedMapping(0)
137 , m_clipper(*renderer)
139 updateStackingNode();
141 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
143 if (!renderer->slowFirstChild() && renderer->style()) {
144 m_visibleContentStatusDirty = false;
145 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
148 updateScrollableArea();
151 RenderLayer::~RenderLayer()
153 if (renderer()->frame() && renderer()->frame()->page()) {
154 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
155 scrollingCoordinator->willDestroyRenderLayer(this);
158 removeFilterInfoIfNeeded();
160 if (groupedMapping()) {
161 DisableCompositingQueryAsserts disabler;
162 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
163 setGroupedMapping(0);
166 // Child layers will be deleted by their corresponding render objects, so
167 // we don't need to delete them ourselves.
169 clearCompositedLayerMapping(true);
171 if (m_reflectionInfo)
172 m_reflectionInfo->destroy();
175 String RenderLayer::debugName() const
177 if (isReflection()) {
178 return renderer()->parent()->debugName() + " (reflection)";
180 return renderer()->debugName();
183 RenderLayerCompositor* RenderLayer::compositor() const
185 if (!renderer()->view())
187 return renderer()->view()->compositor();
190 void RenderLayer::contentChanged(ContentChangeType changeType)
192 // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling.
193 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html
194 DisableCompositingQueryAsserts disabler;
196 if (changeType == CanvasChanged)
197 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
199 if (changeType == CanvasContextChanged) {
200 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
202 // Although we're missing test coverage, we need to call
203 // GraphicsLayer::setContentsToPlatformLayer with the new platform
204 // layer for this canvas.
205 // See http://crbug.com/349195
206 if (hasCompositedLayerMapping())
207 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
210 if (m_compositedLayerMapping)
211 m_compositedLayerMapping->contentChanged(changeType);
214 bool RenderLayer::paintsWithFilters() const
216 if (!renderer()->hasFilter())
219 // https://code.google.com/p/chromium/issues/detail?id=343759
220 DisableCompositingQueryAsserts disabler;
221 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacking;
224 LayoutSize RenderLayer::subpixelAccumulation() const
226 return m_subpixelAccumulation;
229 void RenderLayer::setSubpixelAccumulation(const LayoutSize& size)
231 m_subpixelAccumulation = size;
234 void RenderLayer::updateLayerPositionsAfterLayout()
236 TRACE_EVENT0("blink", "RenderLayer::updateLayerPositionsAfterLayout");
238 m_clipper.clearClipRectsIncludingDescendants();
239 updateLayerPositionRecursive();
242 // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
243 // https://code.google.com/p/chromium/issues/detail?id=343756
244 DisableCompositingQueryAsserts disabler;
245 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer();
246 updatePaginationRecursive(needsPaginationUpdate);
250 void RenderLayer::updateLayerPositionRecursive()
252 if (m_reflectionInfo)
253 m_reflectionInfo->reflection()->layout();
255 // FIXME: We should be able to remove this call because we don't care about
256 // any descendant-dependent flags, but code somewhere else is reading these
257 // flags and depending on us to update them.
258 updateDescendantDependentFlags();
260 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
261 child->updateLayerPositionRecursive();
264 void RenderLayer::updateHasSelfPaintingLayerDescendant() const
266 ASSERT(m_hasSelfPaintingLayerDescendantDirty);
268 m_hasSelfPaintingLayerDescendant = false;
270 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
271 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) {
272 m_hasSelfPaintingLayerDescendant = true;
277 m_hasSelfPaintingLayerDescendantDirty = false;
280 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
282 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
283 layer->m_hasSelfPaintingLayerDescendantDirty = true;
284 // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
285 // in this case, there is no need to dirty our ancestors further.
286 if (layer->isSelfPaintingLayer()) {
287 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->m_hasSelfPaintingLayerDescendant);
293 bool RenderLayer::scrollsWithViewport() const
295 return renderer()->style()->position() == FixedPosition && renderer()->containerForFixedPosition() == renderer()->view();
298 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
300 if (scrollsWithViewport() != other->scrollsWithViewport())
302 return ancestorScrollingLayer() != other->ancestorScrollingLayer();
305 void RenderLayer::updateTransformationMatrix()
308 RenderBox* box = renderBox();
310 m_transform->makeIdentity();
311 box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
312 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing());
316 void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
318 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
321 // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
322 // so check style too.
323 bool hasTransform = renderer()->hasTransformRelatedProperty() && newStyle->hasTransform();
324 bool had3DTransform = has3DTransform();
326 bool hadTransform = m_transform;
327 if (hasTransform != hadTransform) {
329 m_transform = adoptPtr(new TransformationMatrix);
333 // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
334 m_clipper.clearClipRectsIncludingDescendants();
335 } else if (hasTransform) {
336 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
339 updateTransformationMatrix();
341 if (had3DTransform != has3DTransform())
342 dirty3DTransformedDescendantStatus();
345 static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer)
347 if (RenderObject* containingBlock = layer->renderer()->containingBlock())
348 return containingBlock->enclosingLayer();
352 RenderLayer* RenderLayer::renderingContextRoot()
354 RenderLayer* renderingContext = 0;
356 if (shouldPreserve3D())
357 renderingContext = this;
359 for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current))
360 renderingContext = current;
362 return renderingContext;
365 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
368 return TransformationMatrix();
370 // m_transform includes transform-origin, so we need to recompute the transform here.
371 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
372 RenderBox* box = renderBox();
373 TransformationMatrix currTransform;
374 box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
375 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing());
376 return currTransform;
382 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
385 return TransformationMatrix();
387 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
388 TransformationMatrix matrix = *m_transform;
389 makeMatrixRenderable(matrix, false /* flatten 3d */);
396 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
398 RenderView* view = renderer->view();
399 RenderLayerModelObject* prevBlock = renderer;
400 RenderBlock* containingBlock;
401 for (containingBlock = renderer->containingBlock();
402 containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
403 containingBlock = containingBlock->containingBlock())
404 prevBlock = containingBlock;
406 // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
407 if (containingBlock != ancestorColumnsRenderer)
410 // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
411 if (prevBlock->isOutOfFlowPositioned())
414 // Otherwise we are paginated by the columns block.
418 // Convert a bounding box from flow thread coordinates, relative to |layer|, to visual coordinates, relative to |ancestorLayer|.
419 static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutRect& rect)
421 RenderLayer* paginationLayer = layer->enclosingPaginationLayer();
422 ASSERT(paginationLayer);
423 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer());
425 // First make the flow thread rectangle relative to the flow thread, not to |layer|.
426 LayoutPoint offsetWithinPaginationLayer;
427 layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer);
428 rect.moveBy(offsetWithinPaginationLayer);
430 // Then make the rectangle visual, relative to the fragmentation context. Split our box up into
431 // the actual fragment boxes that render in the columns/pages and unite those together to get
432 // our true bounding box.
433 rect = flowThread->fragmentsBoundingBox(rect);
435 // Finally, make the visual rectangle relative to |ancestorLayer|.
436 // FIXME: Handle nested fragmentation contexts (crbug.com/423076). For now just give up if there
437 // are different pagination layers involved.
438 if (!ancestorLayer->enclosingPaginationLayer() || ancestorLayer->enclosingPaginationLayer() != paginationLayer) {
439 // The easy case. The ancestor layer is not within the pagination layer.
440 paginationLayer->convertToLayerCoords(ancestorLayer, rect);
443 // The ancestor layer is also inside the pagination layer, so we need to subtract the visual
444 // distance from the ancestor layer to the pagination layer.
445 LayoutPoint offsetFromPaginationLayerToAncestor;
446 ancestorLayer->convertToLayerCoords(paginationLayer, offsetFromPaginationLayerToAncestor);
447 offsetFromPaginationLayerToAncestor = flowThread->flowThreadPointToVisualPoint(offsetFromPaginationLayerToAncestor);
448 rect.moveBy(-offsetFromPaginationLayerToAncestor);
451 bool RenderLayer::useRegionBasedColumns() const
453 return renderer()->document().regionBasedColumnsEnabled();
456 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate)
458 m_isPaginated = false;
459 m_enclosingPaginationLayer = 0;
461 if (useRegionBasedColumns() && renderer()->isRenderFlowThread())
462 needsPaginationUpdate = true;
464 if (needsPaginationUpdate)
467 if (renderer()->hasColumns())
468 needsPaginationUpdate = true;
470 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
471 child->updatePaginationRecursive(needsPaginationUpdate);
474 void RenderLayer::updatePagination()
476 bool usesRegionBasedColumns = useRegionBasedColumns();
477 if ((!usesRegionBasedColumns && compositingState() != NotComposited) || !parent())
478 return; // FIXME: For now the RenderView can't be paginated. Eventually printing will move to a model where it is though.
480 // The main difference between the paginated booleans for the old column code and the new column code
481 // is that each paginated layer has to paint on its own with the new code. There is no
482 // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
483 // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
484 // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
485 // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
486 // to that layer easily.
487 if (usesRegionBasedColumns && renderer()->isRenderFlowThread()) {
488 m_enclosingPaginationLayer = this;
492 if (m_stackingNode->isNormalFlowOnly()) {
493 if (usesRegionBasedColumns) {
494 // Content inside a transform is not considered to be paginated, since we simply
495 // paint the transform multiple times in each column, so we don't have to use
496 // fragments for the transformed content.
497 m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
498 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransformRelatedProperty())
499 m_enclosingPaginationLayer = 0;
501 m_isPaginated = parent()->renderer()->hasColumns();
506 // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
507 // we find one, then we just check its pagination status.
508 if (usesRegionBasedColumns) {
509 RenderView* view = renderer()->view();
510 RenderBlock* containingBlock;
511 for (containingBlock = renderer()->containingBlock();
512 containingBlock && containingBlock != view;
513 containingBlock = containingBlock->containingBlock()) {
514 if (containingBlock->hasLayer()) {
515 // Content inside a transform is not considered to be paginated, since we simply
516 // paint the transform multiple times in each column, so we don't have to use
517 // fragments for the transformed content.
518 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
519 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransformRelatedProperty())
520 m_enclosingPaginationLayer = 0;
527 // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
528 RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode();
529 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
530 if (curr->renderer()->hasColumns()) {
531 m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
534 if (curr->stackingNode() == ancestorStackingContextNode)
539 LayoutPoint RenderLayer::positionFromPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
541 FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintInvalidationContainer, 0, 0, paintInvalidationState);
543 // FIXME: Eventually we are going to unify coordinates in GraphicsLayer space.
544 if (paintInvalidationContainer && paintInvalidationContainer->layer()->groupedMapping())
545 mapPointToPaintBackingCoordinates(paintInvalidationContainer, point);
547 return LayoutPoint(point);
550 void RenderLayer::mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint& point)
552 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
553 if (!paintInvalidationLayer->groupedMapping()) {
554 point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
558 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
559 if (!transformedAncestor)
562 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
563 // transformed ancestor.
564 point = paintInvalidationContainer->localToContainerPoint(point, transformedAncestor);
566 point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
569 void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect)
571 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
572 if (!paintInvalidationLayer->groupedMapping()) {
573 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
577 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
578 if (!transformedAncestor)
581 // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
582 // transformed ancestor.
583 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox());
585 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
588 void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState)
590 if (!paintInvalidationContainer->layer()->groupedMapping()) {
591 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
595 // This code adjusts the paint invalidation rectangle to be in the space of the transformed ancestor of the grouped (i.e. squashed)
596 // layer. This is because all layers that squash together need to issue paint invalidations w.r.t. a single container that is
597 // an ancestor of all of them, in order to properly take into account any local transforms etc.
598 // FIXME: remove this special-case code that works around the paint invalidation code structure.
599 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
601 mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect);
604 LayoutRect RenderLayer::computePaintInvalidationRect(const RenderObject* renderObject, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
606 if (!paintInvalidationContainer->groupedMapping())
607 return renderObject->computePaintInvalidationRect(paintInvalidationContainer->renderer(), paintInvalidationState);
609 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer->renderer(), paintInvalidationState);
610 mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rect);
614 void RenderLayer::dirtyVisibleContentStatus()
616 m_visibleContentStatusDirty = true;
618 parent()->dirtyAncestorChainVisibleDescendantStatus();
621 void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility)
623 if (m_visibleContentStatusDirty)
625 if (hasVisibleContent() == (visibility == VISIBLE))
627 dirtyVisibleContentStatus();
630 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
632 for (RenderLayer* layer = this; layer; layer = layer->parent()) {
633 if (layer->m_visibleDescendantStatusDirty)
636 layer->m_visibleDescendantStatusDirty = true;
640 // FIXME: this is quite brute-force. We could be more efficient if we were to
641 // track state and update it as appropriate as changes are made in the Render tree.
642 void RenderLayer::updateScrollingStateAfterCompositingChange()
644 TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChange");
645 m_hasVisibleNonLayerContent = false;
646 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) {
647 if (!r->hasLayer()) {
648 m_hasVisibleNonLayerContent = true;
653 m_hasNonCompositedChild = false;
654 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
655 if (child->compositingState() == NotComposited) {
656 m_hasNonCompositedChild = true;
662 // The descendant-dependent flags system is badly broken because we clean dirty
663 // bits in upward tree walks, which means we need to call updateDescendantDependentFlags
664 // at every node in the tree to fully clean all the dirty bits. While we'll in
665 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubtree
666 // provides a big hammer for actually cleaning all the dirty bits in a subtree.
668 // FIXME: Remove this function once the descendant-dependent flags system keeps
669 // its dirty bits scoped to subtrees.
670 void RenderLayer::updateDescendantDependentFlagsForEntireSubtree()
672 updateDescendantDependentFlags();
674 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
675 child->updateDescendantDependentFlagsForEntireSubtree();
678 void RenderLayer::updateDescendantDependentFlags()
680 if (m_visibleDescendantStatusDirty) {
681 m_hasVisibleDescendant = false;
683 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
684 child->updateDescendantDependentFlags();
686 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
687 m_hasVisibleDescendant = true;
692 m_visibleDescendantStatusDirty = false;
695 if (m_visibleContentStatusDirty) {
696 bool previouslyHasVisibleContent = m_hasVisibleContent;
697 if (renderer()->style()->visibility() == VISIBLE)
698 m_hasVisibleContent = true;
700 // layer may be hidden but still have some visible content, check for this
701 m_hasVisibleContent = false;
702 RenderObject* r = renderer()->slowFirstChild();
704 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
705 m_hasVisibleContent = true;
708 RenderObject* rendererFirstChild = r->slowFirstChild();
709 if (rendererFirstChild && !r->hasLayer())
710 r = rendererFirstChild;
711 else if (r->nextSibling())
712 r = r->nextSibling();
718 } while (r && !r->nextSibling());
720 r = r->nextSibling();
724 m_visibleContentStatusDirty = false;
726 if (hasVisibleContent() != previouslyHasVisibleContent) {
727 setNeedsCompositingInputsUpdate();
728 // We need to tell m_renderer to recheck its rect because we
729 // pretend that invisible RenderObjects have 0x0 rects. Changing
730 // visibility therefore changes our rect and we need to visit
731 // this RenderObject during the invalidateTreeIfNeeded walk.
732 m_renderer->setMayNeedPaintInvalidation(true);
737 void RenderLayer::dirty3DTransformedDescendantStatus()
739 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode();
743 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
745 // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
746 // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
747 while (stackingNode && stackingNode->layer()->preserves3D()) {
748 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
749 stackingNode = stackingNode->ancestorStackingContextNode();
753 // Return true if this layer or any preserve-3d descendants have 3d.
754 bool RenderLayer::update3DTransformedDescendantStatus()
756 if (m_3DTransformedDescendantStatusDirty) {
757 m_has3DTransformedDescendant = false;
759 m_stackingNode->updateZOrderLists();
761 // Transformed or preserve-3d descendants can only be in the z-order lists, not
762 // in the normal flow list, so we only need to check those.
763 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrderChildren | NegativeZOrderChildren);
764 while (RenderLayerStackingNode* node = iterator.next())
765 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDescendantStatus();
767 m_3DTransformedDescendantStatusDirty = false;
770 // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
771 // the m_has3DTransformedDescendant set.
773 return has3DTransform() || m_has3DTransformedDescendant;
775 return has3DTransform();
778 IntSize RenderLayer::size() const
780 if (renderer()->isInline() && renderer()->isRenderInline())
781 return toRenderInline(renderer())->linesBoundingBox().size();
783 // FIXME: Is snapping the size really needed here?
784 if (RenderBox* box = renderBox())
785 return pixelSnappedIntSize(box->size(), box->location());
790 LayoutPoint RenderLayer::location() const
792 LayoutPoint localPoint;
793 LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
795 if (renderer()->isInline() && renderer()->isRenderInline()) {
796 RenderInline* inlineFlow = toRenderInline(renderer());
797 IntRect lineBox = inlineFlow->linesBoundingBox();
798 inlineBoundingBoxOffset = toSize(lineBox.location());
799 localPoint += inlineBoundingBoxOffset;
800 } else if (RenderBox* box = renderBox()) {
801 localPoint += box->topLeftLocationOffset();
804 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) {
805 // We must adjust our position by walking up the render tree looking for the
806 // nearest enclosing object with a layer.
807 RenderObject* curr = renderer()->parent();
808 while (curr && !curr->hasLayer()) {
809 if (curr->isBox() && !curr->isTableRow()) {
810 // Rows and cells share the same coordinate space (that of the section).
811 // Omit them when computing our xpos/ypos.
812 localPoint += toRenderBox(curr)->topLeftLocationOffset();
814 curr = curr->parent();
816 if (curr->isBox() && curr->isTableRow()) {
817 // Put ourselves into the row coordinate space.
818 localPoint -= toRenderBox(curr)->topLeftLocationOffset();
822 // Subtract our parent's scroll offset.
823 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
824 RenderLayer* positionedParent = enclosingPositionedAncestor();
826 // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
827 if (positionedParent->renderer()->hasOverflowClip()) {
828 LayoutSize offset = positionedParent->renderBox()->scrolledContentOffset();
829 localPoint -= offset;
832 if (positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
833 LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
834 localPoint += offset;
836 } else if (parent()) {
837 // FIXME: This code is very wrong, but luckily only needed in the old/current multicol
838 // implementation. The compositing system doesn't understand columns and we're hacking
839 // around that fact by faking the position of the RenderLayers when we think we'll end up
841 if (hasStyleDeterminedDirectCompositingReasons() && !useRegionBasedColumns()) {
842 // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
843 // They won't split across columns properly.
844 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns())
845 localPoint += renderer()->view()->columnOffset(localPoint);
847 localPoint += parent()->renderer()->columnOffset(localPoint);
850 if (parent()->renderer()->hasOverflowClip()) {
851 IntSize scrollOffset = parent()->renderBox()->scrolledContentOffset();
852 localPoint -= scrollOffset;
856 localPoint.move(offsetForInFlowPosition());
858 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
859 localPoint -= inlineBoundingBoxOffset;
864 const LayoutSize RenderLayer::offsetForInFlowPosition() const
866 return renderer()->isRelPositioned() ? toRenderBoxModelObject(renderer())->offsetForInFlowPosition() : LayoutSize();
869 TransformationMatrix RenderLayer::perspectiveTransform() const
871 if (!renderer()->hasTransformRelatedProperty())
872 return TransformationMatrix();
874 RenderStyle* style = renderer()->style();
875 if (!style->hasPerspective())
876 return TransformationMatrix();
878 // Maybe fetch the perspective from the backing?
879 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
880 const float boxWidth = borderBox.width();
881 const float boxHeight = borderBox.height();
883 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth);
884 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight);
886 // A perspective origin of 0,0 makes the vanishing point in the center of the element.
887 // We want it to be in the top-left, so subtract half the height and width.
888 perspectiveOriginX -= boxWidth / 2.0f;
889 perspectiveOriginY -= boxHeight / 2.0f;
891 TransformationMatrix t;
892 t.translate(perspectiveOriginX, perspectiveOriginY);
893 t.applyPerspective(style->perspective());
894 t.translate(-perspectiveOriginX, -perspectiveOriginY);
899 FloatPoint RenderLayer::perspectiveOrigin() const
901 if (!renderer()->hasTransformRelatedProperty())
904 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
905 RenderStyle* style = renderer()->style();
907 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat()));
910 static inline bool isFixedPositionedContainer(RenderLayer* layer)
912 return layer->isRootLayer() || layer->hasTransformRelatedProperty();
915 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
917 RenderLayer* curr = parent();
918 while (curr && !curr->isPositionedContainer())
919 curr = curr->parent();
924 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
926 RenderLayer* curr = parent();
927 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransformRelatedProperty())
928 curr = curr->parent();
933 LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const
935 const AncestorDependentCompositingInputs& properties = ancestorDependentCompositingInputs();
937 TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
938 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct.
939 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip);
940 transformState.flatten();
941 return LayoutPoint(transformState.lastPlanarPoint());
944 const RenderLayer* RenderLayer::compositingContainer() const
946 if (stackingNode()->isNormalFlowOnly())
948 if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode())
949 return ancestorStackingNode->layer();
953 bool RenderLayer::isPaintInvalidationContainer() const
955 return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking;
958 // Note: enclosingCompositingLayer does not include squashed layers. Compositing stacking children of squashed layers
959 // receive graphics layers that are parented to the compositing ancestor of the squashed layer.
960 RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeSelf) const
962 ASSERT(isAllowedToQueryCompositingState());
964 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
965 return const_cast<RenderLayer*>(this);
967 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
968 if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
969 return const_cast<RenderLayer*>(curr);
975 // Return the enclosingCompositedLayerForPaintInvalidation for the given RenderLayer
976 // including crossing frame boundaries.
977 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const
979 const RenderLayer* layer = this;
980 RenderLayer* compositedLayer = 0;
981 while (!compositedLayer) {
982 compositedLayer = layer->enclosingLayerForPaintInvalidation();
983 if (!compositedLayer) {
984 RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
987 layer = owner->enclosingLayer();
990 return compositedLayer;
993 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const
995 ASSERT(isAllowedToQueryCompositingState());
997 if (isPaintInvalidationContainer())
998 return const_cast<RenderLayer*>(this);
1000 for (const RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1001 if (curr->isPaintInvalidationContainer())
1002 return const_cast<RenderLayer*>(curr);
1008 void RenderLayer::setNeedsCompositingInputsUpdate()
1010 m_needsAncestorDependentCompositingInputsUpdate = true;
1011 m_needsDescendantDependentCompositingInputsUpdate = true;
1013 for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent())
1014 current->m_childNeedsCompositingInputsUpdate = true;
1016 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
1019 void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs& compositingInputs)
1021 m_ancestorDependentCompositingInputs = compositingInputs;
1022 m_needsAncestorDependentCompositingInputsUpdate = false;
1025 void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs& compositingInputs)
1027 m_descendantDependentCompositingInputs = compositingInputs;
1028 m_needsDescendantDependentCompositingInputsUpdate = false;
1031 void RenderLayer::didUpdateCompositingInputs()
1033 ASSERT(!needsCompositingInputsUpdate());
1034 m_childNeedsCompositingInputsUpdate = false;
1035 if (m_scrollableArea)
1036 m_scrollableArea->updateNeedsCompositedScrolling();
1039 void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask)
1041 if ((compositingReasons() & mask) == (reasons & mask))
1043 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask);
1046 void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant)
1048 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant))
1051 m_hasCompositingDescendant = hasCompositingDescendant;
1053 if (hasCompositedLayerMapping())
1054 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1057 void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants)
1059 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants))
1062 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants;
1064 if (hasCompositedLayerMapping())
1065 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
1068 bool RenderLayer::hasAncestorWithFilterOutsets() const
1070 for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1071 RenderLayerModelObject* renderer = curr->renderer();
1072 if (renderer->style()->hasFilterOutsets())
1078 RenderLayer* RenderLayer::transparentPaintingAncestor()
1080 if (hasCompositedLayerMapping())
1083 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1084 if (curr->hasCompositedLayerMapping())
1086 if (curr->isTransparent())
1092 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1093 RenderLayer::TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1095 // If we have a mask, then the clip is limited to the border box area (and there is
1096 // no need to examine child layers).
1097 if (!layer->renderer()->hasMask()) {
1098 // Note: we don't have to walk z-order lists since transparent elements always establish
1099 // a stacking container. This means we can just walk the layer tree directly.
1100 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1101 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
1102 clipRect.unite(RenderLayer::transparencyClipBox(curr, rootLayer, transparencyBehavior, RenderLayer::DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
1106 // If we have a reflection, then we need to account for that when we push the clip. Reflect our entire
1107 // current transparencyClipBox to catch all child layers.
1108 // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1109 // size into the parent layer.
1110 if (layer->renderer()->hasReflection()) {
1112 layer->convertToLayerCoords(rootLayer, delta);
1113 clipRect.move(-delta.x(), -delta.y());
1114 clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1115 clipRect.moveBy(delta);
1119 LayoutRect RenderLayer::transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1120 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1122 // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1123 // paintDirtyRect, and that should cut down on the amount we have to paint. Still it
1124 // would be better to respect clips.
1126 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1127 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransformRelatedProperty()))) {
1128 // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1129 // the transformed layer and all of its children.
1130 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1131 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1133 layer->convertToLayerCoords(rootLayerForTransform, delta);
1135 delta.move(subPixelAccumulation);
1136 IntPoint pixelSnappedDelta = roundedIntPoint(delta);
1137 TransformationMatrix transform;
1138 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
1139 transform = transform * *layer->transform();
1141 // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1142 // paints unfragmented.
1143 LayoutRect clipRect = layer->physicalBoundingBox(layer);
1144 expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1145 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1146 LayoutRect result = transform.mapRect(clipRect);
1147 if (!paginationLayer)
1150 // We have to break up the transformed extent across our columns.
1151 // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1152 // get our true bounding box.
1153 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1154 result = enclosingFlowThread->fragmentsBoundingBox(result);
1156 LayoutPoint rootLayerDelta;
1157 paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1158 result.moveBy(rootLayerDelta);
1162 LayoutRect clipRect = layer->fragmentsBoundingBox(rootLayer);
1163 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
1164 layer->renderer()->style()->filterOutsets().expandRect(clipRect);
1165 clipRect.move(subPixelAccumulation);
1169 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
1171 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
1174 void* RenderLayer::operator new(size_t sz)
1176 return partitionAlloc(Partitions::getRenderingPartition(), sz);
1179 void RenderLayer::operator delete(void* ptr)
1184 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1186 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1188 child->setPreviousSibling(prevSibling);
1189 prevSibling->setNextSibling(child);
1190 ASSERT(prevSibling != child);
1192 setFirstChild(child);
1195 beforeChild->setPreviousSibling(child);
1196 child->setNextSibling(beforeChild);
1197 ASSERT(beforeChild != child);
1199 setLastChild(child);
1201 child->m_parent = this;
1203 setNeedsCompositingInputsUpdate();
1205 if (child->stackingNode()->isNormalFlowOnly())
1206 m_stackingNode->dirtyNormalFlowList();
1208 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
1209 // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the
1210 // case where we're building up generated content layers. This is ok, since the lists will start
1211 // off dirty in that case anyway.
1212 child->stackingNode()->dirtyStackingContextZOrderLists();
1215 dirtyAncestorChainVisibleDescendantStatus();
1216 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1218 child->updateDescendantDependentFlags();
1221 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1223 if (oldChild->previousSibling())
1224 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1225 if (oldChild->nextSibling())
1226 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1228 if (m_first == oldChild)
1229 m_first = oldChild->nextSibling();
1230 if (m_last == oldChild)
1231 m_last = oldChild->previousSibling();
1233 if (oldChild->stackingNode()->isNormalFlowOnly())
1234 m_stackingNode->dirtyNormalFlowList();
1235 if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
1236 // Dirty the z-order list in which we are contained. When called via the
1237 // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1238 // from the main layer tree, so we need to null-check the
1239 // |stackingContext| value.
1240 oldChild->stackingNode()->dirtyStackingContextZOrderLists();
1243 if (renderer()->style()->visibility() != VISIBLE)
1244 dirtyVisibleContentStatus();
1246 oldChild->setPreviousSibling(0);
1247 oldChild->setNextSibling(0);
1248 oldChild->m_parent = 0;
1250 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1252 oldChild->updateDescendantDependentFlags();
1254 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1255 dirtyAncestorChainVisibleDescendantStatus();
1260 void RenderLayer::removeOnlyThisLayer()
1265 m_clipper.clearClipRectsIncludingDescendants();
1267 RenderLayer* nextSib = nextSibling();
1269 // Remove the child reflection layer before moving other child layers.
1270 // The reflection layer should not be moved to the parent.
1271 if (m_reflectionInfo)
1272 removeChild(m_reflectionInfo->reflectionLayer());
1274 // Now walk our kids and reattach them to our parent.
1275 RenderLayer* current = m_first;
1277 RenderLayer* next = current->nextSibling();
1278 removeChild(current);
1279 m_parent->addChild(current, nextSib);
1281 // FIXME: We should call a specialized version of this function.
1282 current->updateLayerPositionsAfterLayout();
1286 // Remove us from the parent.
1287 m_parent->removeChild(this);
1288 m_renderer->destroyLayer();
1291 void RenderLayer::insertOnlyThisLayer()
1293 if (!m_parent && renderer()->parent()) {
1294 // We need to connect ourselves when our renderer() has a parent.
1295 // Find our enclosingLayer and add ourselves.
1296 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
1297 ASSERT(parentLayer);
1298 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
1299 parentLayer->addChild(this, beforeChild);
1302 // Remove all descendant layers from the hierarchy and add them to the new position.
1303 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling())
1304 curr->moveLayers(m_parent, this);
1306 // Clear out all the clip rects.
1307 m_clipper.clearClipRectsIncludingDescendants();
1310 // Returns the layer reached on the walk up towards the ancestor.
1311 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
1313 ASSERT(ancestorLayer != layer);
1315 const RenderLayerModelObject* renderer = layer->renderer();
1316 EPosition position = renderer->style()->position();
1318 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1319 // may need to be revisited in a future patch.
1320 // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1321 // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
1322 // positioned in a completely different place in the viewport (RenderView).
1323 if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
1324 // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1325 // localToAbsolute() on the RenderView.
1326 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed);
1327 location += LayoutSize(absPos.x(), absPos.y());
1328 return ancestorLayer;
1331 // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1332 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1333 // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1334 if (position == FixedPosition) {
1335 // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1336 // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1337 // so we should always find the ancestor at or before we find the fixed position container.
1338 RenderLayer* fixedPositionContainerLayer = 0;
1339 bool foundAncestor = false;
1340 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1341 if (currLayer == ancestorLayer)
1342 foundAncestor = true;
1344 if (isFixedPositionedContainer(currLayer)) {
1345 fixedPositionContainerLayer = currLayer;
1346 ASSERT_UNUSED(foundAncestor, foundAncestor);
1351 ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1353 if (fixedPositionContainerLayer != ancestorLayer) {
1354 LayoutPoint fixedContainerCoords;
1355 layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1357 LayoutPoint ancestorCoords;
1358 ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1360 location += (fixedContainerCoords - ancestorCoords);
1362 location += toSize(layer->location());
1364 return ancestorLayer;
1367 RenderLayer* parentLayer;
1368 if (position == AbsolutePosition || position == FixedPosition) {
1369 // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1370 parentLayer = layer->parent();
1371 bool foundAncestorFirst = false;
1372 while (parentLayer) {
1373 // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
1374 // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
1375 // we are bailing out before reaching root layer.
1376 if (parentLayer->isPositionedContainer())
1379 if (parentLayer == ancestorLayer) {
1380 foundAncestorFirst = true;
1384 parentLayer = parentLayer->parent();
1387 // We should not reach RenderView layer past the RenderFlowThread layer for any
1388 // children of the RenderFlowThread.
1389 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
1391 if (foundAncestorFirst) {
1392 // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1393 // to enclosingPositionedAncestor and subtract.
1394 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1396 LayoutPoint thisCoords;
1397 layer->convertToLayerCoords(positionedAncestor, thisCoords);
1399 LayoutPoint ancestorCoords;
1400 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
1402 location += (thisCoords - ancestorCoords);
1403 return ancestorLayer;
1406 parentLayer = layer->parent();
1411 location += toSize(layer->location());
1415 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
1417 if (ancestorLayer == this)
1420 const RenderLayer* currLayer = this;
1421 while (currLayer && currLayer != ancestorLayer)
1422 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location);
1425 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
1428 convertToLayerCoords(ancestorLayer, delta);
1432 void RenderLayer::didUpdateNeedsCompositedScrolling()
1434 updateSelfPaintingLayer();
1437 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
1439 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
1440 if (renderer()->hasReflection()) {
1441 if (!m_reflectionInfo)
1442 m_reflectionInfo = adoptPtrWillBeNoop(new RenderLayerReflectionInfo(*renderBox()));
1443 m_reflectionInfo->updateAfterStyleChange(oldStyle);
1444 } else if (m_reflectionInfo) {
1445 m_reflectionInfo->destroy();
1446 m_reflectionInfo = nullptr;
1450 void RenderLayer::updateStackingNode()
1452 if (requiresStackingNode())
1453 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this));
1455 m_stackingNode = nullptr;
1458 void RenderLayer::updateScrollableArea()
1460 if (requiresScrollableArea())
1461 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this));
1463 m_scrollableArea = nullptr;
1466 bool RenderLayer::hasOverflowControls() const
1468 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
1471 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
1472 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
1473 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
1475 if (!enclosingPaginationLayer() || hasTransformRelatedProperty()) {
1476 // For unpaginated layers, there is only one fragment.
1477 LayerFragment fragment;
1478 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy, subPixelAccumulation);
1479 if (respectOverflowClip == IgnoreOverflowClip)
1480 clipRectsContext.setIgnoreOverflowClip();
1481 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
1482 fragments.append(fragment);
1486 // Compute our offset within the enclosing pagination layer.
1487 LayoutPoint offsetWithinPaginatedLayer;
1488 convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginatedLayer);
1490 // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
1491 // layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
1492 ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
1493 if (respectOverflowClip == IgnoreOverflowClip)
1494 paginationClipRectsContext.setIgnoreOverflowClip();
1495 LayoutRect layerBoundsInFlowThread;
1496 ClipRect backgroundRectInFlowThread;
1497 ClipRect foregroundRectInFlowThread;
1498 ClipRect outlineRectInFlowThread;
1499 clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
1500 outlineRectInFlowThread, &offsetWithinPaginatedLayer);
1502 // Take our bounding box within the flow thread and clip it.
1503 LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer);
1504 layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
1506 // Make the dirty rect relative to the fragmentation context (multicol container, etc.).
1507 RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
1508 LayoutPoint offsetOfPaginationLayerFromRoot;
1509 // FIXME: more work needed if there are nested pagination layers.
1510 if (rootLayer != enclosingPaginationLayer() && rootLayer->enclosingPaginationLayer() == enclosingPaginationLayer()) {
1511 // The root layer is inside the fragmentation context. So we need to look inside it and find
1512 // the visual offset from the fragmentation context.
1513 LayoutPoint flowThreadOffset;
1514 rootLayer->convertToLayerCoords(enclosingPaginationLayer(), flowThreadOffset);
1515 offsetOfPaginationLayerFromRoot = -enclosingFlowThread->flowThreadPointToVisualPoint(flowThreadOffset);
1517 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
1519 LayoutRect dirtyRectInFlowThread(dirtyRect);
1520 dirtyRectInFlowThread.moveBy(-offsetOfPaginationLayerFromRoot);
1522 // Tell the flow thread to collect the fragments. We pass enough information to create a minimal number of fragments based off the pages/columns
1523 // that intersect the actual dirtyRect as well as the pages/columns that intersect our layer's bounding box.
1524 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlowThread, dirtyRectInFlowThread);
1526 if (fragments.isEmpty())
1529 // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
1530 ClipRect ancestorClipRect = dirtyRect;
1531 if (enclosingPaginationLayer()->parent()) {
1532 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
1533 if (respectOverflowClip == IgnoreOverflowClip)
1534 clipRectsContext.setIgnoreOverflowClip();
1535 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
1536 ancestorClipRect.intersect(dirtyRect);
1539 for (size_t i = 0; i < fragments.size(); ++i) {
1540 LayerFragment& fragment = fragments.at(i);
1542 // Set our four rects with all clipping applied that was internal to the flow thread.
1543 fragment.setRects(layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread, outlineRectInFlowThread);
1545 // Shift to the root-relative physical position used when painting the flow thread in this fragment.
1546 fragment.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
1548 // Intersect the fragment with our ancestor's background clip so that e.g., columns in an overflow:hidden block are
1549 // properly clipped by the overflow.
1550 fragment.intersect(ancestorClipRect.rect());
1552 // Now intersect with our pagination clip. This will typically mean we're just intersecting the dirty rect with the column
1553 // clip, so the column clip ends up being all we apply.
1554 fragment.intersect(fragment.paginationClip);
1558 static inline LayoutRect frameVisibleRect(RenderObject* renderer)
1560 FrameView* frameView = renderer->document().view();
1562 return LayoutRect();
1564 return frameView->visibleContentRect();
1567 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
1569 return hitTest(request, result.hitTestLocation(), result);
1572 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTestLocation, HitTestResult& result)
1574 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1576 // RenderView should make sure to update layout before entering hit testing
1577 ASSERT(!renderer()->frame()->view()->layoutPending());
1578 ASSERT(!renderer()->document().renderView()->needsLayout());
1580 // Start with frameVisibleRect to ensure we include the scrollbars.
1581 LayoutRect hitTestArea = frameVisibleRect(renderer());
1582 if (request.ignoreClipping())
1583 hitTestArea.unite(renderer()->view()->documentRect());
1585 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hitTestLocation, false);
1587 // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
1588 // return ourselves. We do this so mouse events continue getting delivered after a drag has
1589 // exited the WebView, and so hit testing over a scrollbar hits the content document.
1590 // In addtion, it is possible for the mouse to stay in the document but there is no element.
1591 // At that time, the events of the mouse should be fired.
1592 LayoutPoint hitPoint = hitTestLocation.point();
1593 if (!request.isChildFrameHitTest() && ((request.active() || request.release()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) {
1594 renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
1599 // Now determine if the result is inside an anchor - if the urlElement isn't already set.
1600 Node* node = result.innerNode();
1601 if (node && !result.URLElement())
1602 result.setURLElement(node->enclosingLinkEventParentOrSelf());
1604 // Now return whether we were inside this layer (this will always be true for the root
1609 Node* RenderLayer::enclosingElement() const
1611 for (RenderObject* r = renderer(); r; r = r->parent()) {
1612 if (Node* e = r->node())
1615 ASSERT_NOT_REACHED();
1619 bool RenderLayer::isInTopLayer() const
1621 Node* node = renderer()->node();
1622 return node && node->isElementNode() && toElement(node)->isInTopLayer();
1625 // Compute the z-offset of the point in the transformState.
1626 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
1627 // ray intersects target, and computing the z delta between those two points.
1628 static double computeZOffset(const HitTestingTransformState& transformState)
1630 // We got an affine transform, so no z-offset
1631 if (transformState.m_accumulatedTransform.isAffine())
1634 // Flatten the point into the target plane
1635 FloatPoint targetPoint = transformState.mappedPoint();
1637 // Now map the point back through the transform, which computes Z.
1638 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
1639 return backmappedPoint.z();
1642 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
1643 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
1644 const HitTestingTransformState* containerTransformState,
1645 const LayoutPoint& translationOffset) const
1647 RefPtr<HitTestingTransformState> transformState;
1649 if (containerTransformState) {
1650 // If we're already computing transform state, then it's relative to the container (which we know is non-null).
1651 transformState = HitTestingTransformState::create(*containerTransformState);
1652 convertToLayerCoords(containerLayer, offset);
1654 // If this is the first time we need to make transform state, then base it off of hitTestLocation,
1655 // which is relative to rootLayer.
1656 transformState = HitTestingTransformState::create(hitTestLocation.transformedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect));
1657 convertToLayerCoords(rootLayer, offset);
1659 offset.moveBy(translationOffset);
1661 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
1662 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
1663 TransformationMatrix containerTransform;
1664 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform);
1665 transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
1667 transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
1670 return transformState;
1674 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
1679 // The hit layer is depth-sorting with other layers, so just say that it was hit.
1683 // We need to look at z-depth to decide if this layer was hit.
1685 ASSERT(transformState);
1686 // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
1687 double childZOffset = computeZOffset(*transformState);
1688 if (childZOffset > *zOffset) {
1689 *zOffset = childZOffset;
1698 // hitTestLocation and hitTestRect are relative to rootLayer.
1699 // A 'flattening' layer is one preserves3D() == false.
1700 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
1701 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the containing flattening layer.
1702 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
1704 // If zOffset is non-null (which indicates that the caller wants z offset information),
1705 // *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
1706 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
1707 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool appliedTransform,
1708 const HitTestingTransformState* transformState, double* zOffset)
1710 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
1713 // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
1715 // Apply a transform if we have one.
1716 if (transform() && !appliedTransform) {
1717 if (enclosingPaginationLayer())
1718 return hitTestTransformedLayerInFragments(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
1720 // Make sure the parent's clip rects have been calculated.
1722 ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize));
1723 // Go ahead and test the enclosing clip now.
1724 if (!clipRect.intersects(hitTestLocation))
1728 return hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset);
1731 // Ensure our lists and 3d status are up-to-date.
1732 m_stackingNode->updateLayerListsIfNeeded();
1733 update3DTransformedDescendantStatus();
1735 RefPtr<HitTestingTransformState> localTransformState;
1736 if (appliedTransform) {
1737 // We computed the correct state in the caller (above code), so just reference it.
1738 ASSERT(transformState);
1739 localTransformState = const_cast<HitTestingTransformState*>(transformState);
1740 } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
1741 // We need transform state for the first time, or to offset the container state, so create it here.
1742 localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
1745 // Check for hit test on backface if backface-visibility is 'hidden'
1746 if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
1747 TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
1748 // If the z-vector of the matrix is negative, the back is facing towards the viewer.
1749 if (invertedMatrix.m33() < 0)
1753 RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
1754 if (localTransformState && !preserves3D()) {
1755 // Keep a copy of the pre-flattening state, for computing z-offsets for the container
1756 unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
1757 // This layer is flattening, so flatten the state passed to descendants.
1758 localTransformState->flatten();
1761 // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
1763 double localZOffset = -std::numeric_limits<double>::infinity();
1764 double* zOffsetForDescendantsPtr = 0;
1765 double* zOffsetForContentsPtr = 0;
1767 bool depthSortDescendants = false;
1768 if (preserves3D()) {
1769 depthSortDescendants = true;
1770 // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
1771 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
1772 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
1773 } else if (zOffset) {
1774 zOffsetForDescendantsPtr = 0;
1775 // Container needs us to give back a z offset for the hit layer.
1776 zOffsetForContentsPtr = zOffset;
1779 // This variable tracks which layer the mouse ends up being inside.
1780 RenderLayer* candidateLayer = 0;
1782 // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
1783 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
1784 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
1786 if (!depthSortDescendants)
1788 candidateLayer = hitLayer;
1791 // Now check our overflow objects.
1792 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
1793 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
1795 if (!depthSortDescendants)
1797 candidateLayer = hitLayer;
1800 // Collect the fragments. This will compute the clip rectangles for each layer fragment.
1801 LayerFragments layerFragments;
1802 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
1804 if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
1805 renderer()->updateHitTestResult(result, hitTestLocation.point());
1809 // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
1810 // every fragment in reverse order.
1811 if (isSelfPaintingLayer()) {
1812 // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
1813 HitTestResult tempResult(result.hitTestLocation());
1814 bool insideFragmentForegroundRect = false;
1815 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
1816 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
1817 if (result.isRectBasedTest())
1818 result.append(tempResult);
1820 result = tempResult;
1821 if (!depthSortDescendants)
1823 // Foreground can depth-sort with descendant layers, so keep this as a candidate.
1824 candidateLayer = this;
1825 } else if (insideFragmentForegroundRect && result.isRectBasedTest())
1826 result.append(tempResult);
1829 // Now check our negative z-index children.
1830 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
1831 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
1833 if (!depthSortDescendants)
1835 candidateLayer = hitLayer;
1838 // If we found a layer, return. Child layers, and foreground always render in front of background.
1840 return candidateLayer;
1842 if (isSelfPaintingLayer()) {
1843 HitTestResult tempResult(result.hitTestLocation());
1844 bool insideFragmentBackgroundRect = false;
1845 if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
1846 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
1847 if (result.isRectBasedTest())
1848 result.append(tempResult);
1850 result = tempResult;
1853 if (insideFragmentBackgroundRect && result.isRectBasedTest())
1854 result.append(tempResult);
1860 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
1861 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
1863 if (layerFragments.isEmpty())
1866 for (int i = layerFragments.size() - 1; i >= 0; --i) {
1867 const LayerFragment& fragment = layerFragments.at(i);
1868 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
1869 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
1871 insideClipRect = true;
1872 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
1879 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
1880 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
1882 LayerFragments enclosingPaginationFragments;
1883 LayoutPoint offsetOfPaginationLayerFromRoot;
1884 // FIXME: We're missing a sub-pixel offset here crbug.com/348728
1885 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RenderLayer::RootOfTransparencyClipBox, LayoutSize());
1886 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
1887 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
1889 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
1890 const LayerFragment& fragment = enclosingPaginationFragments.at(i);
1892 // Apply the page/column clip for this fragment, as well as any clips established by layers in between us and
1893 // the enclosing pagination layer.
1894 LayoutRect clipRect = fragment.backgroundRect.rect();
1896 // Now compute the clips within a given fragment
1897 if (parent() != enclosingPaginationLayer()) {
1898 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
1899 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize)).rect();
1900 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
1901 clipRect.intersect(parentClipRect);
1904 if (!hitTestLocation.intersects(clipRect))
1907 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLayer, request, result, hitTestRect, hitTestLocation,
1908 transformState, zOffset, fragment.paginationOffset);
1916 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
1917 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
1918 const LayoutPoint& translationOffset)
1920 // Create a transform state to accumulate this transform.
1921 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, translationOffset);
1923 // If the transform can't be inverted, then don't hit test this layer at all.
1924 if (!newTransformState->m_accumulatedTransform.isInvertible())
1927 // Compute the point and the hit test rect in the coords of this layer by using the values
1928 // from the transformState, which store the point and quad in the coords of the last flattened
1929 // layer, and the accumulated transform which lets up map through preserve-3d layers.
1931 // We can't just map hitTestLocation and hitTestRect because they may have been flattened (losing z)
1932 // by our container.
1933 FloatPoint localPoint = newTransformState->mappedPoint();
1934 FloatQuad localPointQuad = newTransformState->mappedQuad();
1935 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea();
1936 HitTestLocation newHitTestLocation;
1937 if (hitTestLocation.isRectBasedTest())
1938 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
1940 newHitTestLocation = HitTestLocation(localPoint);
1942 // Now do a hit test with the root layer shifted to be us.
1943 return hitTestLayer(this, containerLayer, request, result, localHitTestRect, newHitTestLocation, true, newTransformState.get(), zOffset);
1946 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter) const
1948 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant());
1950 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(layerBounds.location() - renderBoxLocation()), hitTestFilter)) {
1951 // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
1952 // a rect-based test.
1953 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
1957 // For positioned generated content, we might still not have a
1958 // node by the time we get to the layer level, since none of
1959 // the content in the layer has an element. So just walk up
1961 if (!result.innerNode() || !result.innerNonSharedNode()) {
1962 Node* e = enclosingElement();
1963 if (!result.innerNode())
1964 result.setInnerNode(e);
1965 if (!result.innerNonSharedNode())
1966 result.setInnerNonSharedNode(e);
1972 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer,
1973 const HitTestRequest& request, HitTestResult& result,
1974 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
1975 const HitTestingTransformState* transformState,
1976 double* zOffsetForDescendants, double* zOffset,
1977 const HitTestingTransformState* unflattenedTransformState,
1978 bool depthSortDescendants)
1980 if (!hasSelfPaintingLayerDescendant())
1983 RenderLayer* resultLayer = 0;
1984 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit);
1985 while (RenderLayerStackingNode* child = iterator.next()) {
1986 RenderLayer* childLayer = child->layer();
1987 RenderLayer* hitLayer = 0;
1988 HitTestResult tempResult(result.hitTestLocation());
1989 if (childLayer->isPaginated())
1990 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendants);
1992 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants);
1994 // If it a rect-based test, we can safely append the temporary result since it might had hit
1995 // nodes but not necesserily had hitLayer set.
1996 if (result.isRectBasedTest())
1997 result.append(tempResult);
1999 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
2000 resultLayer = hitLayer;
2001 if (!result.isRectBasedTest())
2002 result = tempResult;
2003 if (!depthSortDescendants)
2011 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2012 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
2014 Vector<RenderLayer*> columnLayers;
2015 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
2016 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
2017 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
2018 columnLayers.append(curr);
2019 if (curr->stackingNode() == ancestorNode)
2023 ASSERT(columnLayers.size());
2024 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestLocation, transformState, zOffset,
2025 columnLayers, columnLayers.size() - 1);
2028 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
2029 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset,
2030 const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
2032 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
2034 ASSERT(columnBlock && columnBlock->hasColumns());
2035 if (!columnBlock || !columnBlock->hasColumns())
2038 LayoutPoint layerOffset;
2039 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
2041 ColumnInfo* colInfo = columnBlock->columnInfo();
2042 int colCount = columnBlock->columnCount(colInfo);
2044 // We have to go backwards from the last column to the first.
2045 bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
2046 LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent();
2047 LayoutUnit currLogicalTopOffset = 0;
2049 for (i = 0; i < colCount; i++) {
2050 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2051 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2052 if (columnBlock->style()->slowIsFlippedBlocksWritingMode())
2053 currLogicalTopOffset += blockDelta;
2055 currLogicalTopOffset -= blockDelta;
2057 for (i = colCount - 1; i >= 0; i--) {
2058 // For each rect, we clip to the rect, and then we adjust our coords.
2059 LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
2060 columnBlock->flipForWritingMode(colRect);
2061 LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
2062 LayoutUnit blockDelta = (isHorizontal ? colRect.height() : colRect.width());
2063 if (columnBlock->style()->slowIsFlippedBlocksWritingMode())
2064 currLogicalTopOffset -= blockDelta;
2066 currLogicalTopOffset += blockDelta;
2070 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2071 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset);
2073 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
2075 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
2076 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
2078 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
2081 colRect.moveBy(layerOffset);
2083 LayoutRect localClipRect(hitTestRect);
2084 localClipRect.intersect(colRect);
2086 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect)) {
2087 RenderLayer* hitLayer = 0;
2089 // Apply a translation transform to change where the layer paints.
2090 TransformationMatrix oldTransform;
2091 bool oldHasTransform = childLayer->transform();
2092 if (oldHasTransform)
2093 oldTransform = *childLayer->transform();
2094 TransformationMatrix newTransform(oldTransform);
2095 newTransform.translateRight(offset.width(), offset.height());
2097 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
2098 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestLocation, false, transformState, zOffset);
2099 if (oldHasTransform)
2100 childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
2102 childLayer->m_transform.clear();
2104 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
2105 // This involves subtracting out the position of the layer in our current coordinate space.
2106 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
2107 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation, transformState);
2108 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
2109 FloatPoint localPoint = newTransformState->mappedPoint();
2110 FloatQuad localPointQuad = newTransformState->mappedQuad();
2111 LayoutRect localHitTestRect = newTransformState->mappedArea().enclosingBoundingBox();
2112 HitTestLocation newHitTestLocation;
2113 if (hitTestLocation.isRectBasedTest())
2114 newHitTestLocation = HitTestLocation(localPoint, localPointQuad);
2116 newHitTestLocation = HitTestLocation(localPoint);
2117 newTransformState->flatten();
2119 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, newHitTestLocation,
2120 newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
2131 void RenderLayer::blockSelectionGapsBoundsChanged()
2133 setNeedsCompositingInputsUpdate();
2136 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
2138 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
2139 blockSelectionGapsBoundsChanged();
2142 void RenderLayer::clearBlockSelectionGapsBounds()
2144 m_blockSelectionGapsBounds = IntRect();
2145 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2146 child->clearBlockSelectionGapsBounds();
2147 blockSelectionGapsBoundsChanged();
2150 void RenderLayer::invalidatePaintForBlockSelectionGaps()
2152 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2153 child->invalidatePaintForBlockSelectionGaps();
2155 if (m_blockSelectionGapsBounds.isEmpty())
2158 LayoutRect rect = m_blockSelectionGapsBounds;
2159 if (renderer()->hasOverflowClip()) {
2160 RenderBox* box = renderBox();
2161 rect.move(-box->scrolledContentOffset());
2162 if (!scrollableArea()->usesCompositedScrolling())
2163 rect.intersect(box->overflowClipRect(LayoutPoint()));
2165 if (renderer()->hasClip())
2166 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
2167 if (!rect.isEmpty())
2168 renderer()->invalidatePaintRectangle(rect);
2171 IntRect RenderLayer::blockSelectionGapsBounds() const
2173 if (!renderer()->isRenderBlock())
2176 RenderBlock* renderBlock = toRenderBlock(renderer());
2177 LayoutRect gapRects = renderBlock->selectionGapRectsForPaintInvalidation(renderBlock);
2179 return pixelSnappedIntRect(gapRects);
2182 bool RenderLayer::hasBlockSelectionGapBounds() const
2184 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible
2185 // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802).
2186 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean);
2188 if (!renderer()->isRenderBlock())
2191 return toRenderBlock(renderer())->shouldPaintSelectionGaps();
2194 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
2196 // Always examine the canvas and the root.
2197 // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
2198 // paints the root's background.
2199 if (isRootLayer() || renderer()->isDocumentElement())
2202 // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
2203 // can go ahead and return true.
2204 RenderView* view = renderer()->view();
2206 if (view && !renderer()->isRenderInline()) {
2207 if (layerBounds.intersects(damageRect))
2211 // Otherwise we need to compute the bounding box of this single layer and see if it intersects
2213 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
2216 LayoutRect RenderLayer::logicalBoundingBox() const
2218 // There are three special cases we need to consider.
2219 // (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
2220 // inline. In other words, if some <span> wraps to three lines, we'll create a bounding box that fully encloses the
2221 // line boxes of all three lines (including overflow on those lines).
2222 // (2) Left/Top Overflow. The width/height of layers already includes right/bottom overflow. However, in the case of left/top
2223 // overflow, we have to create a bounding box that will extend to include this overflow.
2224 // (3) Floats. When a layer has overhanging floats that it paints, we need to make sure to include these overhanging floats
2225 // as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
2228 if (renderer()->isInline() && renderer()->isRenderInline()) {
2229 result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
2230 } else if (renderer()->isTableRow()) {
2231 // Our bounding box is just the union of all of our cells' border/overflow rects.
2232 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
2233 if (child->isTableCell()) {
2234 LayoutRect bbox = toRenderBox(child)->borderBoxRect();
2236 LayoutRect overflowRect = renderBox()->visualOverflowRect();
2237 if (bbox != overflowRect)
2238 result.unite(overflowRect);
2242 RenderBox* box = renderBox();
2244 result = box->borderBoxRect();
2245 result.unite(box->visualOverflowRect());
2248 ASSERT(renderer()->view());
2252 static inline LayoutRect flippedLogicalBoundingBox(LayoutRect boundingBox, RenderObject* renderer)
2254 if (!UNLIKELY(renderer->document().containsAnyRareWritingMode()))
2257 LayoutRect result = boundingBox;
2258 if (renderer->isBox())
2259 toRenderBox(renderer)->flipForWritingMode(result);
2261 renderer->containingBlock()->flipForWritingMode(result);
2265 LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
2267 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer());
2269 result.moveBy(*offsetFromRoot);
2271 convertToLayerCoords(ancestorLayer, result);
2275 LayoutRect RenderLayer::fragmentsBoundingBox(const RenderLayer* ancestorLayer) const
2277 if (!enclosingPaginationLayer())
2278 return physicalBoundingBox(ancestorLayer);
2280 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer());
2281 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result);
2285 LayoutRect RenderLayer::boundingBoxForCompositingOverlapTest() const
2287 return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : fragmentsBoundingBox(this);
2290 static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result)
2292 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
2293 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer));
2295 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList());
2298 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorLayer)->stackingNode());
2301 RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren);
2302 while (RenderLayerStackingNode* node = iterator.next()) {
2303 // Here we exclude both directly composited layers and squashing layers
2304 // because those RenderLayers don't paint into the graphics layer
2305 // for this RenderLayer. For example, the bounds of squashed RenderLayers
2306 // will be included in the computation of the appropriate squashing
2308 if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited)
2310 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options));
2314 LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const
2317 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
2319 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
2321 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggHacks, result);
2323 result.moveBy(offsetFromRoot);
2327 LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const
2329 if (!isSelfPaintingLayer())
2330 return LayoutRect();
2333 ancestorLayer = this;
2335 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
2336 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
2337 return LayoutRect();
2339 // The root layer is always just the size of the document.
2341 return m_renderer->view()->unscaledDocumentRect();
2343 // The layer created for the RenderFlowThread is just a helper for painting and hit-testing,
2344 // and should not contribute to the bounding box. The RenderMultiColumnSets will contribute
2345 // the correct size for the rendered content of the multicol container.
2346 if (useRegionBasedColumns() && renderer()->isRenderFlowThread())
2347 return LayoutRect();
2349 LayoutRect result = clipper().localClipRect();
2350 if (result == PaintInfo::infiniteRect()) {
2352 result = physicalBoundingBox(ancestorLayer, &origin);
2354 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
2356 // Reflections are implemented with RenderLayers that hang off of the reflected layer. However,
2357 // the reflection layer subtree does not include the subtree of the parent RenderLayer, so
2358 // a recursive computation of stacking children yields no results. This breaks cases when there are stacking
2359 // children of the parent, that need to be included in reflected composited bounds.
2360 // Fix this by including composited bounds of stacking children of the reflected RenderLayer.
2361 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this)
2362 expandRectForReflectionAndStackingChildren(parent(), options, result);
2364 expandRectForReflectionAndStackingChildren(this, options, result);
2366 // FIXME: We can optimize the size of the composited layers, by not enlarging
2367 // filtered areas with the outsets if we know that the filter is going to render in hardware.
2368 // https://bugs.webkit.org/show_bug.cgi?id=81239
2369 m_renderer->style()->filterOutsets().expandRect(result);
2372 if (paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform()))
2373 result = transform()->mapRect(result);
2375 if (enclosingPaginationLayer()) {
2376 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result);
2380 convertToLayerCoords(ancestorLayer, delta);
2381 result.moveBy(delta);
2385 CompositingState RenderLayer::compositingState() const
2387 ASSERT(isAllowedToQueryCompositingState());
2389 // This is computed procedurally so there is no redundant state variable that
2390 // can get out of sync from the real actual compositing state.
2392 if (m_groupedMapping) {
2393 ASSERT(compositor()->layerSquashingEnabled());
2394 ASSERT(!m_compositedLayerMapping);
2395 return PaintsIntoGroupedBacking;
2398 if (!m_compositedLayerMapping)
2399 return NotComposited;
2401 return PaintsIntoOwnBacking;
2404 bool RenderLayer::isAllowedToQueryCompositingState() const
2406 if (gCompositingQueryMode == CompositingQueriesAreAllowed)
2408 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
2411 CompositedLayerMapping* RenderLayer::compositedLayerMapping() const
2413 ASSERT(isAllowedToQueryCompositingState());
2414 return m_compositedLayerMapping.get();
2417 GraphicsLayer* RenderLayer::graphicsLayerBacking() const
2419 switch (compositingState()) {
2422 case PaintsIntoGroupedBacking:
2423 return groupedMapping()->squashingLayer();
2425 return compositedLayerMapping()->mainGraphicsLayer();
2429 GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const
2431 switch (compositingState()) {
2434 case PaintsIntoGroupedBacking:
2435 return groupedMapping()->squashingLayer();
2437 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLayerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsLayer();
2441 CompositedLayerMapping* RenderLayer::ensureCompositedLayerMapping()
2443 if (!m_compositedLayerMapping) {
2444 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
2445 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
2447 updateOrRemoveFilterEffectRenderer();
2449 return m_compositedLayerMapping.get();
2452 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
2454 if (!layerBeingDestroyed) {
2455 // We need to make sure our decendants get a geometry update. In principle,
2456 // we could call setNeedsGraphicsLayerUpdate on our children, but that would
2457 // require walking the z-order lists to find them. Instead, we over-invalidate
2458 // by marking our parent as needing a geometry update.
2459 if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
2460 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
2463 m_compositedLayerMapping.clear();
2465 if (!layerBeingDestroyed)
2466 updateOrRemoveFilterEffectRenderer();
2469 void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
2471 if (groupedMapping == m_groupedMapping)
2474 if (!layerBeingDestroyed && m_groupedMapping) {
2475 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
2476 m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this);
2478 m_groupedMapping = groupedMapping;
2479 if (!layerBeingDestroyed && m_groupedMapping)
2480 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
2483 bool RenderLayer::hasCompositedMask() const
2485 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
2488 bool RenderLayer::hasCompositedClippingMask() const
2490 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer();
2493 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
2495 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
2498 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
2500 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
2503 if (paintsWithTransparency(PaintBehaviorNormal))
2506 // We can't use hasVisibleContent(), because that will be true if our renderer is hidden, but some child
2507 // is visible and that child doesn't cover the entire rect.
2508 if (renderer()->style()->visibility() != VISIBLE)
2511 if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity())
2514 // FIXME: Handle simple transforms.
2515 if (paintsWithTransform(PaintBehaviorNormal))
2518 // FIXME: Remove this check.
2519 // This function should not be called when layer-lists are dirty.
2520 // It is somehow getting triggered during style update.
2521 if (m_stackingNode->zOrderListsDirty() || m_stackingNode->normalFlowListDirty())
2524 // FIXME: We currently only check the immediate renderer,
2525 // which will miss many cases.
2526 if (renderer()->backgroundIsKnownToBeOpaqueInRect(localRect))
2529 // We can't consult child layers if we clip, since they might cover
2530 // parts of the rect that are clipped out.
2531 if (renderer()->hasOverflowClip())
2534 return childBackgroundIsKnownToBeOpaqueInRect(localRect);
2537 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
2539 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren);
2540 while (RenderLayerStackingNode* child = revertseIterator.next()) {
2541 const RenderLayer* childLayer = child->layer();
2542 // Stop at composited paint boundaries.
2543 if (childLayer->isPaintInvalidationContainer())
2546 if (!childLayer->canUseConvertToLayerCoords())
2549 LayoutPoint childOffset;
2550 LayoutRect childLocalRect(localRect);
2551 childLayer->convertToLayerCoords(this, childOffset);
2552 childLocalRect.moveBy(-childOffset);
2554 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect))
2560 bool RenderLayer::shouldBeSelfPaintingLayer() const
2562 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing())
2564 return m_layerType == NormalLayer
2565 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
2566 || needsCompositedScrolling();
2569 void RenderLayer::updateSelfPaintingLayer()
2571 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
2572 if (this->isSelfPaintingLayer() == isSelfPaintingLayer)
2575 m_isSelfPaintingLayer = isSelfPaintingLayer;
2578 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
2581 bool RenderLayer::hasNonEmptyChildRenderers() const
2583 // Some HTML can cause whitespace text nodes to have renderers, like:
2587 // so test for 0x0 RenderTexts here
2588 for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
2589 if (!child->hasLayer()) {
2590 if (child->isRenderInline() || !child->isBox())
2593 if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
2600 bool RenderLayer::hasBoxDecorationsOrBackground() const
2602 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasBackground();
2605 bool RenderLayer::hasVisibleBoxDecorations() const
2607 if (!hasVisibleContent())
2610 return hasBoxDecorationsOrBackground() || hasOverflowControls();
2613 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
2615 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
2618 updateOrRemoveFilterClients();
2619 updateOrRemoveFilterEffectRenderer();
2622 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderStyle* oldStyle)
2624 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialCompositingReasonsFromStyle;
2625 compositor()->updatePotentialCompositingReasonsFromStyle(this);
2627 // This function implements an optimization for transforms and opacity.
2628 // A common pattern is for a touchmove handler to update the transform
2629 // and/or an opacity of an element every frame while the user moves their
2630 // finger across the screen. The conditions below recognize when the
2631 // compositing state is set up to receive a direct transform or opacity
2634 if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformChanged | StyleDifference::OpacityChanged))
2636 // The potentialCompositingReasonsFromStyle could have changed without
2637 // a corresponding StyleDifference if an animation started or ended.
2638 if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasonsFromStyle)
2640 // We could add support for reflections if we updated the transform on
2641 // the reflection layers.
2642 if (renderer()->hasReflection())
2644 // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
2645 // perform a direct compositing update because the filters code is going
2646 // to produce different output this time around. We can remove this code
2647 // once we fix the chicken/egg bugs in the filters code and delete the
2648 // scheduleSVGFilterLayerUpdateHack().
2649 if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate())
2651 if (!m_compositedLayerMapping)
2654 // To cut off almost all the work in the compositing update for
2655 // this case, we treat inline transforms has having assumed overlap
2656 // (similar to how we treat animated transforms). Notice that we read
2657 // CompositingReasonInlineTransform from the m_compositingReasons, which
2658 // means that the inline transform actually triggered assumed overlap in
2660 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInlineTransform))
2663 // We composite transparent RenderLayers differently from non-transparent
2664 // RenderLayers even when the non-transparent RenderLayers are already a
2665 // stacking context.
2666 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->hasOpacity())
2669 updateTransform(oldStyle, renderer()->style());
2671 // FIXME: Consider introducing a smaller graphics layer update scope
2672 // that just handles transforms and opacity. GraphicsLayerUpdateLocal
2673 // will also program bounds, clips, and many other properties that could
2674 // not possibly have changed.
2675 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
2676 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
2680 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
2682 if (attemptDirectCompositingUpdate(diff, oldStyle))
2685 m_stackingNode->updateIsNormalFlowOnly();
2686 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
2688 if (m_scrollableArea)
2689 m_scrollableArea->updateAfterStyleChange(oldStyle);
2691 // Overlay scrollbars can make this layer self-painting so we need
2692 // to recompute the bit once scrollbars have been updated.
2693 updateSelfPaintingLayer();
2695 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
2696 ASSERT(!oldStyle || diff.needsFullLayout());
2697 updateReflectionInfo(oldStyle);
2700 updateDescendantDependentFlags();
2702 updateTransform(oldStyle, renderer()->style());
2703 updateFilters(oldStyle, renderer()->style());
2705 setNeedsCompositingInputsUpdate();
2708 bool RenderLayer::scrollsOverflow() const
2710 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
2711 return scrollableArea->scrollsOverflow();
2716 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
2718 const FilterOperations& filters = style->filter();
2719 if (filters.hasReferenceFilter()) {
2720 for (size_t i = 0; i < filters.size(); ++i) {
2721 FilterOperation* filterOperation = filters.operations().at(i).get();
2722 if (filterOperation->type() != FilterOperation::REFERENCE)
2724 ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
2725 // FIXME: Cache the ReferenceFilter if it didn't change.
2726 RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create(style->effectiveZoom());
2727 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
2728 referenceOperation));
2729 referenceOperation->setFilter(referenceFilter.release());
2736 void RenderLayer::updateOrRemoveFilterClients()
2739 removeFilterInfoIfNeeded();
2743 if (renderer()->style()->filter().hasReferenceFilter())
2744 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
2745 else if (hasFilterInfo())
2746 filterInfo()->removeReferenceFilterClients();
2749 void RenderLayer::updateOrRemoveFilterEffectRenderer()
2751 // FilterEffectRenderer is only used to render the filters in software mode,
2752 // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
2753 // mode might have changed for this layer.
2754 if (!paintsWithFilters()) {
2755 // Don't delete the whole filter info here, because we might use it
2756 // for loading CSS shader files.
2757 if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
2758 filterInfo->setRenderer(nullptr);
2763 RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
2764 if (!filterInfo->renderer()) {
2765 RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
2766 filterInfo->setRenderer(filterRenderer.release());
2769 // If the filter fails to build, remove it from the layer. It will still attempt to
2770 // go through regular processing (e.g. compositing), but never apply anything.
2771 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
2772 filterInfo->setRenderer(nullptr);
2775 void RenderLayer::filterNeedsPaintInvalidation()
2778 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
2779 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which
2780 // is a problem because this function can be called while performing layout.
2781 // Presumably this represents an illegal data flow of layout or compositing
2782 // information into the style system.
2783 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack();
2786 renderer()->setShouldDoFullPaintInvalidation();
2789 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
2791 computeSelfHitTestRects(rects);
2792 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
2793 child->addLayerHitTestRects(rects);
2796 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
2798 if (!size().isEmpty()) {
2799 Vector<LayoutRect> rect;
2801 if (renderBox() && renderBox()->scrollsOverflow()) {
2802 // For scrolling layers, rects are taken to be in the space of the contents.
2803 // We need to include the bounding box of the layer in the space of its parent
2804 // (eg. for border / scroll bars) and if it's composited then the entire contents
2805 // as well as they may be on another composited layer. Skip reporting contents
2806 // for non-composited layers as they'll get projected to the same layer as the
2808 if (compositingState() != NotComposited)
2809 rect.append(m_scrollableArea->overflowRect());
2811 rects.set(this, rect);
2812 if (const RenderLayer* parentLayer = parent()) {
2813 LayerHitTestRects::iterator iter = rects.find(parentLayer);
2814 if (iter == rects.end()) {
2815 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer));
2817 iter->value.append(physicalBoundingBox(parentLayer));
2821 rect.append(logicalBoundingBox());
2822 rects.set(this, rect);
2827 void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
2829 renderer()->setShouldDoFullPaintInvalidation();
2831 // Disable for reading compositingState() in isPaintInvalidationContainer() below.
2832 DisableCompositingQueryAsserts disabler;
2834 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
2835 if (!child->isPaintInvalidationContainer())
2836 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
2840 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
2841 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
2843 } // namespace blink
2846 void showLayerTree(const blink::RenderLayer* layer)
2851 if (blink::LocalFrame* frame = layer->renderer()->frame()) {
2852 WTF::String output = externalRepresentation(frame, blink::RenderAsTextShowAllLayers | blink::RenderAsTextShowLayerNesting | blink::RenderAsTextShowCompositedLayers | blink::RenderAsTextShowAddresses | blink::RenderAsTextShowIDAndClass | blink::RenderAsTextDontUpdateLayout | blink::RenderAsTextShowLayoutState);
2853 fprintf(stderr, "%s\n", output.utf8().data());
2857 void showLayerTree(const blink::RenderObject* renderer)
2861 showLayerTree(renderer->enclosingLayer());